2009-09-03 21 views
28

En las pruebas unitarias, el método de configuración se utiliza para crear los objetos necesarios para las pruebas.Pruebas unitarias: ¿es una buena práctica tener afirmaciones en los métodos de configuración?

En esos métodos de configuración, me gusta usar las aserciones: sé qué valores quiero ver en esos objetos , y me gusta documentar ese conocimiento mediante una aserción.

En un post reciente sobre unit tests calling other unit tests aquí en stackoverflow, el sentimiento general parece ser que las pruebas de unidad debe no llamadas otras pruebas: La respuesta a esta pregunta parece ser que usted debe refactorizar su configuración, por lo que los casos de prueba no dependen el uno del otro.

Pero no hay mucha diferencia en un "setup-with-asserts" y en una prueba de unidad llamando a otras pruebas unitarias.

De ahí mi pregunta: ¿es una buena práctica tener aserciones en los métodos de configuración?

EDIT:

La respuesta resulta ser: esto no es una buena práctica en general. Si es necesario probar los resultados de la configuración, se recomienda agregar un método de prueba separado con las aserciones (la respuesta que marqué); para documentar la intención, considere usar Java afirma.

+1

Lea este artículo sobre cómo escribir buenas pruebas unitarias: http://blog.codeville.net/2009/08/24/writing-great-unit-tests-best-and-worst-practises/ – Kane

+0

+1 para preguntas inteligentes – KLE

Respuesta

14

En lugar de aserciones en la configuración para verificar el resultado, utilicé una prueba simple (un método de prueba junto con los demás, pero colocado como primer método de prueba).

que he visto varias ventajas:

  • La configuración mantiene corta y se centró, para facilitar la lectura.
  • Las aserciones se ejecutan solo una vez, que es más eficiente.

Uso y discusión:

Por ejemplo, i el nombre del método testSetup().

Para usarlo, cuando tengo algunos errores de prueba en esa clase, sé que si testSetup() tiene un error, no necesito molestarme con los otros errores, necesito solucionar este primero.

Si a alguien le molesta esto, y quiere que esta dependencia sea explícita, se podría llamar a testSetup() en el método setup(). Pero no creo que importe Mi punto es que, en JUnit, ya se puede tener algo similar en el resto de las pruebas:

  1. algunas pruebas que ponen a prueba el código local,
  2. y algunas pruebas de que son las llamadas al código más global, lo que indirectamente llamadas el mismo código que la prueba anterior.

Cuando se lee el resultado de la prueba donde tanto fallar, que ya tiene para hacerse cargo de esta dependencia que no está en la prueba, pero en el código que se llama. Primero debe corregir la prueba simple y luego volver a ejecutar la prueba global para ver si aún falla. Esta es la razón por la cual no me molesta la dependencia implícita que expliqué anteriormente.

+2

Esta mañana discutí la cuestión con un colega, y se nos ocurrió esta solución también. ¡Es bueno saber que tienes una experiencia positiva con eso! – avandeursen

+0

@Kaka Gracias por su gran comentario y por el refuerzo que proporcionan sus comentarios. :-) – KLE

+0

@KLE: esta es una estrategia interesante y eficiente. Pero me pregunto cómo te aseguras de que 'testSetup()' se ejecute cuando ejecutas la prueba con un filtro (es decir '--gtest_filter'). – Sampath

9

Son escenarios diferentes; No veo la similitud.

Los métodos de instalación deben contener el código que es común para (idealmente) todas las pruebas en un dispositivo. Como tal, no hay nada intrínsecamente incorrecto al poner aseveraciones en un método de configuración de prueba si ciertas cosas deben ser verdaderas antes de que se ejecute el resto del código de prueba. La configuración es una extensión de la prueba; es parte de la prueba como un todo. Si la afirmación se dispara, la gente descubrirá qué prerrequisito falló.

Por otro lado, si la configuración es lo suficientemente complicada como para que sienta la necesidad de afirmar que es correcta, puede ser una señal de advertencia. Además, si todas las pruebas no requieren la salida completa de la configuración, entonces es una señal de que el dispositivo tiene poca cohesión y debe dividirse en función de los escenarios y/o refactorizarse.

Es en parte debido a esto que tiendo a evitar los métodos de instalación. Siempre que sea posible, uso métodos de fábrica privados o similares para configurar cosas. Hace que la prueba sea más legible y evita confusiones. A veces esto no es práctico (por ejemplo, trabajar con clases estrechamente conectadas y/o al escribir pruebas de integración), pero para la mayoría de mis pruebas hace el trabajo.

9

No se recomienda tener aserciones en los métodos Setup/TearDown. Hace que la prueba sea menos legible si el usuario necesita "comprender" que parte de la lógica de prueba no está en el método de prueba. Hay momentos en los que no tienes más remedio que usar los métodos de configuración/desmontaje para algo distinto de lo que estaban destinados.

Hay un problema mayor en esta pregunta: una prueba que llama a otra prueba, es un olor a algún problema en sus pruebas. Cada prueba debe probar un aspecto específico de su código y solo debe tener una o dos aserciones, de modo que si su prueba llama a otra prueba, es posible que esté probando demasiadas cosas en esa prueba. Para obtener más información, lea: Unit Testing: One Test, One Assertion - Why It Works

+0

Puntero interesante para una prueba/una afirmación, y me gusta volver a redactar en "uno o dos". – avandeursen

+1

La URL se ha roto. Aquí hay una actualizada. [Pruebas unitarias: una prueba, una afirmación: por qué funciona] (http://blog.astrumfutura.com/2009/02/unit-testing-one-test-one-assertion-why-it-works/) – James

3

Siga sus decisiones de corazón/parpadeo. Las aseveraciones dentro de un método de configuración pueden documentar el intento; legibilidad del mejoradorAsí que, personalmente, te respaldaré en esto.
Es diferente de una prueba llamando a otras pruebas, lo cual es malo. Sin aislamiento de prueba Una prueba no debe influir en el resultado de otra prueba.

Aunque no es un caso de uso de frecuencia, a veces utilizo Asserts dentro de un método de instalación para poder saber si la configuración de la prueba no se ha llevado a cabo como lo esperaba; usualmente cuando trato con componentes que no escribí yo mismo. Una falla de aserción que dice 'Error de configuración!' en la pestaña Errores, rápidamente me ayuda a ubicar el código de configuración en lugar de tener que mirar un montón de pruebas fallidas.

Una falla en la instalación generalmente debe causar que fallen todas las pruebas en ese artefacto, que es un olor que su nariz debería captar pronto. "Todas las pruebas fallaron por lo general implican la instalación se rompió" Por lo tanto, las afirmaciones no siempre son necesarias. Dicho esto, sea pragmático, mire su contexto específico y 'Agregue al gusto'.

+0

Bueno puntos - Gracias. Esto significa usar las afirmaciones de JUnit para dos propósitos diferentes: (1) intento de documento; (2) Verifique que los resultados sean los esperados. – avandeursen

3

Uso Java afirma, en lugar de JUnit unos, en los casos en que algo como esto es necesario. p.ej. cuando se utiliza alguna otra clase de utilidad para configurar los datos de prueba .:

byte[] pkt = pktFactory.makePacket(TIME, 12, "23, F2"); 
assert pkt.length == 15; 

fallido tiene la implicación 'sistema no está en un estado a tratar incluso para ejecutar esta prueba'.

+0

Me gusta la idea. Esto plantea la pregunta general de si es una buena práctica mezclar afirmaciones Java y métodos JUnit Assert, pero me gusta su razonamiento. – avandeursen

Cuestiones relacionadas