¿Debería cada método tener una clase de prueba JUnit separada?


13

Estoy escribiendo pruebas unitarias JUnit para mis clases.

¿Es mejor tener una clase separada para cada método, o tener solo una clase de prueba para cada clase real?

Respuestas:


19

La forma en que se organizan sus pruebas no es importante en comparación con la importancia de tenerlas.

Lo más importante para un buen conjunto de pruebas es que cubre toda la funcionalidad; eso asegura que cada vez que se introduce un defecto de regresión, lo notará de inmediato. Ya sea escribir una prueba para cada método, una prueba para cada combinación de valor de entrada de un método, o incluso una prueba para cada posible ruta de código dentro de ese método es menos importante. Si organizar estas pruebas en pocas o muchas clases de pruebas es aún menos importante: un conjunto de pruebas siempre debe tener éxito en su totalidad, por lo que no importa si falla una de tres o dos de las diecisiete pruebas, ambas están mal y deben ser fijo.

Por supuesto, el código de prueba también es código, por lo que debe seguir las mejores prácticas normales para ser mantenible, modular, etc. Pero eso debe decidirse por lo bien mantenible que es el conjunto de pruebas en sí, no por cómo las clases de prueba se relacionan con el clases que prueban. Ambas políticas que mencione pueden ayudarlo a recordar dónde encontrar cosas si las sigue de manera consistente, pero para eso la coherencia es más importante que la elección de la política.


9

Para su pregunta específica, la convención JUnit es tener una correspondencia 1: 1 entre sus clases de aplicación ( Foo1.java, Foo2.java) y las clases de prueba JUnit ( Foo1Test.java, Foo2Test.java).

Dicho esto, estoy totalmente de acuerdo con el hecho de que Kilian destaca la importancia del espíritu / objetivos de las pruebas unitarias sobre cualquier esquema organizacional que pueda usarse. Elija algunas convenciones y quédese con ellas la mayor parte del tiempo, mientras que con cautela permite excepciones a sus convenciones, cuando estén justificadas.


4

¿Es mejor tener una clase separada para cada método, o tener solo una clase de prueba para cada clase real?

Si tiene la necesidad de escribir clases de prueba separadas para métodos de una clase, entonces tiene el diseño incorrecto. Los métodos deben ser pequeños, fáciles de leer, fáciles de probar y fáciles de cambiar. Las pruebas podrían ser un poco más largas que el código original debido a la creación de datos de prueba, burlas, etc., pero no deberían ser significativamente más largas. Si lo son, su clase bajo prueba es demasiado compleja y seguramente hace más de una cosa ( principio de responsabilidad única ): trabajar en su diseño.


2

Creo que "una clase de prueba por método" y "una clase de prueba por clase" suelen ser demasiado extremas.

En general, desea tener una verificación por método de prueba / prueba unitaria. Por ejemplo, estas podrían ser afirmaciones múltiples para verificar que a list.isEmpty = truey list.Length = 0, por lo tanto, un método de prueba / prueba de unidad por comportamiento.

Esto facilita encontrar un nombre de método de prueba que describa el comportamiento. Desea agrupar los métodos de prueba en una clase de prueba, por lo que cuando lee test classname.test method, tiene sentido. Por lo general, esos tienen un código de configuración compartido que luego es fácil de poner en la configuración / accesorio de prueba. Dependiendo de la clase bajo prueba, esta puede ser una clase de prueba para toda la clase, y también puede ser una clase de prueba para un método. Pero por lo general, será en algún punto intermedio.

Al igual que con el código normal, desea que las pruebas sean lo más legibles posible. Lo que me ayuda es seguir el estilo BDD dado-cuando-entonces u organizar-actuar-afirmar de organizar el código de prueba. Una clase de prueba podría tener eso dado, es la configuración. Luego, cada método de prueba en esa clase usa el dado (o parte de él) y tiene uno cuando y uno entonces.

Piense también en las pruebas unitarias como documentación sobre cómo usar la funcionalidad de la clase bajo prueba. Con buenas pruebas unitarias, puede leer las pruebas para descubrir cómo usar la funcionalidad de la clase que desea usar y cuáles serán los efectos exactamente.

Cuando algo se rompe y una prueba unitaria falla, desea que sea lo más fácil posible entender lo que se rompió, una afirmación por prueba ayuda mucho aquí. Cuando hay varias afirmaciones en una prueba, solo falla la primera y luego sale el método, por lo que no sabe si el otro comportamiento probado en las siguientes pruebas también se rompe hasta que arregle lo que hizo que fallara la primera afirmación. Con una afirmación, todos los demás métodos de prueba aún se ejecutan y es mucho más rápido comprender la profundidad del error.

Por supuesto, estoy de acuerdo con Kilian Foth: en la práctica, puede tener suerte de tener algunas pruebas unitarias para el código en el que está trabajando. Y cualquier pequeña prueba localizada es mejor que ninguna prueba, o solo las grandes pruebas de integración que se ejecutan en el servidor de compilación toman mucho tiempo y generalmente no están muy localizadas (no le dicen rápidamente dónde está el error: usted tendré que trabajar un poco en ello).


Buen punto: "Desea agrupar los métodos de prueba en una clase de prueba para que cuando lea el nombre de la clase de prueba. El método de prueba tenga sentido".
MAChitgarha

1

Creo que es correcto que cada clase tenga su clase de prueba. La idea es centralizar todas las pruebas unitarias relacionadas con la clase objetivo en una sola clase de prueba. Entonces, por ejemplo, MyClass.javatendrá su clase de prueba llamada MyClassTest.java.


0

Es una buena práctica también preguntar a sus colegas si existe documentación sobre cómo realizar las pruebas en su empresa o cuál es la forma en que lo siguen. Si sigue sus pautas, hace que sus pruebas sean más legibles para otros.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.