Pruebas unitarias de Java, diseño de directorio [cerrado]

76

Al crear un conjunto de pruebas unitarias para código Java, ¿existe una convención sobre dónde colocar el código de prueba en relación con el código fuente?

Por ejemplo, si tengo un directorio /javaque contiene un montón de .javaarchivos fuente, ¿es mejor poner los casos de prueba en /javasí mismo o usar algo como /java/test.

Si se prefiere lo último, ¿cómo se prueban las partes internas del código cuando los miembros private / protectedde una clase no están disponibles fuera del paquete?

Miguel
fuente

Respuestas:

73

Puede poner las pruebas en el mismo paquete que las clases originales, incluso si el código fuente está en su propio directorio raíz:

PROJECT_ROOT
    +--- src/
    +----test/

Puede declarar una clase com.foo.MyClassbajo srcy su prueba com.foo.MyClassTestbajo test.

En cuanto al acceso a miembros privados, puede usar la reflexión para invocar los métodos (alterando su accesibilidad a través de Class.getDeclaredMethod.setAccessible), o podría usar algo como testng / junit5 para poner algunas pruebas basadas en anotaciones en el código fuente en sí (personalmente creo que esto es un mala idea).

¿Por qué no ver algunos proyectos java.netpara ver cómo han organizado las cosas, por ejemplo, swinglabs (me temo que el repositorio SVN es bastante lento)?

oxbow_lakes
fuente
117

Recomiendo seguir la estructura de directorios estándar de Apache Software Foundation , que produce esto:

module/
  src/
    main/
      java/
    test/
      java/

Esto mantiene las pruebas separadas de la fuente, pero al mismo nivel en la estructura del directorio. Si lee detenidamente cómo Apache define su estructura, verá que también ayuda a dividir otras preocupaciones, incluidos recursos, archivos de configuración, otros idiomas, etc.

Esta estructura también permite que las pruebas unitarias prueben paquetes y métodos de nivel protegido de las unidades bajo prueba, asumiendo que coloca sus casos de prueba en el mismo paquete que lo que prueban. Con respecto a las pruebas de métodos privados, no me molestaría. Algo más, ya sea público, empaquetado o protegido, los llama y debería poder obtener una cobertura de prueba completa probando esas cosas.

Por cierto, el enlace anterior es a Maven, la herramienta de compilación estándar de Apache. Todos los proyectos de Java que tienen se ajustan a este estándar, así como todos los proyectos que he encontrado que se construyen con Maven.

Un solo tiro
fuente
6
+1 Incluso si no usa maven, es una buena idea seguir este diseño (una especie de estándar de facto basado en las mejores prácticas de la industria).
Pascal Thivent
7
La única razón por la que se menciona a Maven aquí es porque su sitio web es un lugar donde se documenta el diseño de directorio estándar de Apache. Si le gusta o no le gusta es irrelevante con respecto a si la estructura de directorio en cuestión es buena. Quizás pueda comentar una respuesta que se alinee con su opinión para indicar por qué esa estructura de directorio es superior.
SingleShot
1
Si está codificando en Java puro, el javadirectorio es una adición innecesaria
oxbow_lakes
6
Bueno, debe mencionarse que, por lo general, las carpetas mainy testtienen una resourcescarpeta de origen que se compila en la misma carpeta de salida que la javacarpeta, lo que permite una fácil separación del código Java y los archivos de recursos en el nivel de origen. También me gusta esta estructura porque mantiene el nivel superior libre de múltiples carpetas de origen ... es una organización muy lógica. Y sí, esto no tiene nada que ver con si a uno le gusta o no Maven.
ColinD
3
Hice ese comentario hace ocho años. Desde entonces he llegado a comprender y amar a Maven. No trabajaré sin él ahora. La gente puede cambiar.
duffymo
8

La mayoría de las veces se hace así:

<SOME_DIR>/project/src/com/foo/Application.java
<SOME_DIR>/project/test/com/foo/ApplicationTest.java

Por lo tanto, los mantiene separados y aún puede probar el paquete / la funcionalidad protegida porque la prueba está en el mismo paquete.

No puede probar cosas privadas, a menos que se declare dentro de la propia clase.

En el momento de la entrega, solo empaca lo .classgenerado por src, no las pruebas

OscarRyz
fuente
1
La prueba debe estar en la carpeta src. maven.apache.org/guides/introduction/…
Philip Rego
5

En realidad, tiene mucho sentido separar sus proyectos de producción y prueba en 2 entidades separadas, pero tener la misma estructura de paquete en ambos proyectos.

Entonces, si tengo un proyecto 'my-project', también creo 'my-project-test', por lo que tengo la siguiente estructura de directorio:

my-project
  +--- src/com/foo
my-project-test
  +---test/com/foo

Este enfoque asegura que las dependencias del código de prueba no contaminen el código de producción.

En mi opinión personal, los paquetes de métodos privados y protegidos deben probarse, así como los métodos públicos. Por lo tanto, quiero mis clases de prueba en el mismo paquete que las clases de producción.

Alexander Pogrebnyak
fuente
2

Así lo tenemos configurado y nos gusta.

build/
src/
test/build/
test/src/

Todo el código de prueba se compila en su propio directorio de compilación. Esto se debe a que no queremos que la producción contenga clases de prueba por error.

cristiano
fuente
1

Al crear un módulo de biblioteca de Java en Android Studio , crea una clase predeterminada en:

[module]
   + src/main/java/[com/foo/bar]

Si busca en el [module].imlarchivo, encontrará esa ruta, así como la ruta para las pruebas, que puede utilizar. El siguiente es un resumen:

<module>
  <component>
    <content>
      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
      <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
    </content>
  </component>
</module>

Lo que puede hacer en particular es crear un directorio para que las pruebas tengan la siguiente estructura:

[module]
   + src/main/java/[com/foo/bar]
   + src/test/java/[com/foo/bar]

La estructura anterior será reconocida por Android Studio y los archivos que se encuentran debajo se incluirán en el módulo.

Supongo que esa estructura es un diseño recomendado para código y pruebas.

Ryszard Dżegan
fuente