2010-03-12 19 views
38

¿hay algo malo con la comprobación de tantas cosas en esta unidad de prueba ?:¿Las afirmaciones múltiples son malas en una prueba unitaria? Incluso si encadena?

ActualModel = ActualResult.AssertViewRendered()  // check 1 
          .ForView("Index")   // check 2 
          .WithViewData<List<Page>>(); // check 3 

CollectionAssert.AreEqual(Expected, ActualModel);  // check 4 

Los objetivos principales de esta prueba son para verificar se devuelve la vista derecha (marque 2) y contiene los datos correctos (cheque 4).

¿Ganaría algo al dividir esto en varias pruebas? Me refiero a hacer las cosas bien, pero no voy a dividir las cosas si no tiene un valor práctico.

Soy bastante nuevo en pruebas unitarias, así que sea amable.

+0

Algunos mayor discusión sobre el tema: http: // stackoverflow. com/questions/831390/multiple-assert-in-single-test y http://stackoverflow.com/questions/762512/unit-testing-question – Alconja

+0

Todas las buenas respuestas (todas votaciones), gracias! –

+0

Vea también http://programmers.stackexchange.com/questions/7823/is-it-ok-to-have-multiple-asserts-in-a-single-unit-test# –

Respuesta

29

Como han señalado otros, es mejor mantener una afirmación en cada prueba para evitar perder información: si la primera afirmación falla, no se sabe si las últimas fallarán también. Tienes que solucionar el problema con menos información, lo que podría ser (probablemente) más difícil.

Una muy buena referencia es Art of Unit Testing de Roy Osherove - si quiere comenzar bien con Unit Testing, podría hacer mucho peor que comenzar aquí.

+2

Encontré ese libro muy bueno. Mejoró enormemente la calidad de mi unidad de pruebas. Y aunque la mayoría de los libros sobre desarrollo de software son muy densos, este libro contiene aproximadamente 270 páginas. Esto hace que sea ideal para poner en la lista de lectura obligada de su equipo. Y si tienes prisa, Roy te aconseja que solo leas el capítulo 7. – Steven

2

Lo mejor es quedarse con una sola afirmación en cada prueba para evitar Assertion Roulette.

Si necesita configurar el mismo escenario para probar varias condiciones basadas en premisas idénticas, es mejor extraer el código de configuración a un método de ayuda compartido, y luego escribir varias pruebas que llaman a este método de ayuda.

Esto asegura que cada caso de prueba prueba solo una cosa.

Como siempre, hay excepciones a esta regla, pero ya que es nuevo a la unidad de pruebas, recomiendo que se quede con el una afirmación por unidad de prueba regla hasta que haya aprendido cuándo está bien para desviarse .

+0

Eso tiene sentido. ¡Gracias! –

8

Siempre que cada afirmación tenga un mensaje único e identificativo de falla, debe ser bueno y evitará cualquier problema de Assertion Roulette porque no será difícil determinar qué prueba falló. Usa el sentido común.

+5

El problema de tener varias afirmaciones no es decir cuál falló: en la mayoría de los casos, se obtiene el número de línea, en caso de que no sea así. El problema es que no puedes ver si las pruebas posteriores también fallan, por lo que terminas con menos información sobre el error. En algunos casos esto no es significativo, pero en algunos (la mayoría, en mi experiencia, antes de que aprendiera esta lección) lo es. – Bevan

+1

* es que no puede ver si las pruebas posteriores también fallarán *, pero eso no es relevante. Arreglas un Assert a la vez.También es seguro asumir que si el primer Assert está fallando, el siguiente también fallará porque las condiciones previas no se cumplen. En mis pruebas, reemplazo la mayoría de las declaraciones 'si' con un Assert. Además de cuando una rama es válida (que casi nunca es el caso). –

+0

No estoy de acuerdo. Si tiene tres pruebas diferentes y las ejecuta todas, podrá ver qué pasa y qué no pasó. Cuanta más información tenga al intentar arreglar algo, mejor estará. Puede hacer cambios más precisos para arreglar lo que está roto. –

11

Observando para lectores futuros que esta pregunta y su duplicado Is it bad practice to have more than one assertion in a unit test? tienen opiniones de mayoría opuestas, así que léalas y decida usted mismo.

Mi experiencia es que el quantum de prueba más útil no es la aserción, sino el escenario, es decir, debe haber una prueba unitaria para un conjunto determinado de condiciones iniciales y llamada de método, con tantas aserciones como necesario para afirmar las condiciones finales esperadas. Tener una prueba unitaria por afirmación conduce a una configuración duplicada o soluciones temporales tortuosas para evitar la duplicación (como los horribles contextos rspec profundamente anidados que veo cada vez más últimamente). También multiplica las pruebas, ralentizando drásticamente su suite.

6

he encontrado un argumento diferente a esta pregunta (al menos para mí):

uso de múltiples afirma está bien si se están poniendo a prueba la misma cosa.

Por ejemplo, está bien que hacer:

Assert.IsNotNull(value); 
Assert.AreEqual(0, value.Count); 

¿Por qué? - porque estas dos afirmaciones no ocultan la intención de la prueba. Si la primera afirmación falla, significa que la segunda también fallará. Y de hecho, si eliminamos la primera afirmación, la segunda afirmación falla (con excepción de referencia nula - !!!) de todos modos cuando el value es nulo. Si este no fue el caso, entonces no deberíamos juntar estos dos asertos.

Por lo tanto, esto es un error:

Assert.IsNotNull(value1); 
Assert.IsNotNull(value2); 

Como he mencionado anteriormente, si falla el primer afirman, no hay ninguna indicación clara sobre la segunda aserción - tendríamos todavía quiere saber qué pasa con el el segundo (incluso si el primero falló). Entonces, por esta razón, estas dos afirmaciones pertenecen a dos pruebas unitarias diferentes.

Conclusión: poner uno o más afirma, cuando se hace correctamente, se convierte en la cuestión de la preferencia - si queremos ver excepciones afirmación en los resultados de la prueba, o queremos ver algunas otras excepciones, así, en particular, casos.

0

Sé que esta es una pregunta antigua pero pensé en agregar mi parte.

En general, tengo la menor cantidad de aserciones posible en cada caso de prueba. Las pruebas se pueden escribir a menudo para ahorrar muchas aserciones diferentes.

Supongamos que tengo pruebas de unidad para un método que crea un saludo (por ejemplo, el Sr. Smith) a partir de los componentes de un nombre. Quiero comprobar esto con una gran cantidad de escenarios diferentes, no es necesario tener una prueba separada para cada uno.

Dado el siguiente código, hay muchas aserciones diferentes. Cuando fallan, puede solucionarlos de uno en uno hasta que se detengan las afirmaciones.

Assert.AreEqual("Mr Smith", GetSalutation("Mr", "J", "Smith")); 
Assert.AreEqual("Mr Smith", GetSalutation("Mr", "John", "Smith")); 
Assert.AreEqual("Sir/Madam", GetSalutation("", "John", "Smith")); 
Assert.AreEqual("Sir/Madam", GetSalutation("", "J", "Smith")); 

Una alternativa a esto es llevar un conteo de problemas y afirmar esto al final.

int errorCount = 0; 
string result; 

result = GetSalutation("Mr", "J", "Smith"); 
if (result == "Mr Smith") 
    errorCount++; 

result = GetSalutation("Mr", "John", "Smith"); 
if (result == "Mr Smith") 
    errorCount++; 

Assert.AreEqual(0, errorCount); 

En una verdadera situación mundial probablemente añadiría algún rastro comandos para escribir el detalle de las pruebas individuales que no lograron la ventana de salida

Cuestiones relacionadas