Convención de nomenclatura para paquetes de prueba

11

En realidad, nombramos nuestros paquetes de prueba como sus homólogos de prueba. Entonces terminamos con esta estructura:

src/main/java
    com.hello.world
        helloWorld.java
src/test/java
    com.hello.world
        helloWorldTest.java

Siempre sentí que esto no es muy inteligente, ya que no se puede distinguir entre "prueba" y "prueba" si solo se proporciona el nombre del paquete. Por otro lado, no he encontrado un caso en el que esto sea importante de alguna manera. ¿Es una buena práctica tener las mismas convenciones de nomenclatura para ambos paquetes (para los casos de prueba y las clases de origen)? Si no, ¿cuál sería un mejor enfoque?

OddDev
fuente
1
No tengo idea si es una buena práctica, pero es popular. La otra opción (poner "Prueba" en el nombre del paquete, los nombres de los métodos, etc.) huele demasiado a "Nombrar Pitufo". Como usted dice, es difícil pensar en un caso en el que no sea posible "distinguir entre" prueba "y" prueba "si solo se proporciona el nombre del paquete".
David Arno
@DavidArno Gracias por tu aporte :) ¿Cómo evitar entonces el pitufo? Quiero decir que terminaríamos con com.hello.world.test.helloWorld.java, ¿no?
OddDev
El problema "pitufo" es más cuando se tiene un método XXXTest()de com.hello.world.test.helloWorldTest.java. El consejo general sería que solo aparezca "Prueba" una vez en la ruta, de modo que (a) use prueba en el nombre del paquete (y nombre el archivo de prueba igual que el archivo bajo prueba) o (b) haga que el nombre del paquete sea mismo y agregue "prueba" al nombre del archivo / clase.
David Arno
@DavidArno Ah, gracias por la aclaración! Me equivoqué con tu primer comentario. Lo entiendo ahora.
OddDev
Bueno, diría que, si no estaba claro, me equivoqué con mi primer comentario :)
David Arno

Respuestas:

11

Esa es una buena convención.

A veces, también desea escribir pruebas unitarias para clases y métodos privados de paquetes. No podrá llamarlos desde una clase de prueba unitaria colocada en otro paquete.

No debería haber ninguna confusión acerca de tener clases de prueba unitaria en el mismo espacio de nombres, ya que no deberían estar en la ruta de clase al compilar o ejecutar el código de producción.

Aquí hay un ejemplo de un pequeño módulo con una interfaz pública, una clase de fábrica pública y dos clases de implementación de paquete privado:

src/main/java:
    com.hello.transmogrifier
        public interface Transmogrifier
        public class TransmogrifierFactory
        class MapTransmogrifier implements Transmogrifier
        class ListTransmogrifier implements Transmogrifier

scr/test/java:
    com.hello.transmogrifier
        public class TransmogrifierFactoryTest
        public class MapTransmogrifierTest
        public class ListTransmogrifierTest

Ocultar las implementaciones de la interfaz Transmogrifier podría ser una opción de diseño válida. Quizás es responsabilidad de la clase de la fábrica elegir la implementación.

Dado que las implementaciones son privadas de paquete, debe colocar las clases de prueba unitarias en el mismo paquete si desea probarlas directamente. Si tiene sus clases de prueba de unidad en algún otro paquete, solo tiene acceso directo a la interfaz pública y a la clase de fábrica desde sus pruebas.

VIENE DE
fuente
1
"Por lo general, también desea escribir pruebas unitarias para clases y métodos privados de paquetes". ¡No! Esta es realmente una mala práctica. Los tipos privados de paquetes son detalles de implementación y nunca deben probarse directamente. Solo prueba las API públicas.
David Arno
1
@DavidArno No estoy de acuerdo. Sin embargo, reemplacé la palabra "generalmente" por la palabra "a veces" para evitar esa discusión en particular.
VENIDO DEL
1
Puede estar en desacuerdo todo lo que quiera, pero probar el funcionamiento interno de una pieza de código conduce tanto al acoplamiento estrecho entre esos trabajos internos y las pruebas como a las pruebas frágiles que se rompen fácilmente incluso con una refactorización simple. Es muy mala práctica.
David Arno
Si quiero asegurarme de que todas mis implementaciones de Transmogrifier funcionen, sin importar lo que haga la fábrica, escribiré pruebas unitarias que prueben cada implementación. Tenga en cuenta que las implementaciones tienen una API pública compartida a pesar de que las clases son privadas de paquete. Estas pruebas no deben romperse a menos que cambie la API pública. En realidad, probablemente escribiría una prueba genérica para un Transmogrifier y luego la ejecutaría en cada implementación. Si bien es posible obtener cada implementación utilizando la fábrica, es mejor no tener esa dependencia al probar Transmogrifiers.
VENIDO DEL
Entonces, un día, nos fijamos en MapTransmogrifiery ListTransmogrifiery decidir que se podrían hacer en una clase, por lo que se crea ListMapTransmogrifier, modifica la fábrica de usar y eliminar que las dos clases. El código ahora no se compila, por lo que debe modificar cada prueba en ambos MapTransmogrifierTesty ListTransmogrifierTesthacer que se compile. Una prueba falla. ¿Se debió a cambiar las pruebas o crear ListMapTransmogrifier? Sale el depurador para averiguarlo ... alternativamente, cuando las pruebas usan la fábrica, haces ese refactorizador y todo sigue compilando ...
David Arno