2010-11-15 12 views
7

¿Hay demasiadas afirmaciones en esta prueba de una unidad?¿Hay demasiadas afirmaciones en esta prueba unitaria?

[Fact] 
public void Send_sends_an_email_message() { 
    using (var server = new MockSmtpServer()) { 
     server.Start(); 
     using (var client = new EmailClient("localhost")) { 
      string from = "[email protected]"; 
      IEnumerable<string> to = new[] { "[email protected]" }; 
      string subject = "Test"; 
      string body = "Test."; 
      client.Send(from, to, subject, body); 
      var session = server.Sessions.FirstOrDefault(); 
      Assert.NotNull(session); 
      var message = session.Messages.FirstOrDefault(); 
      Assert.NotNull(message); 
      Assert.NotNull(message.From); 
      Assert.Equal(message.From.Address, "[email protected]"); 
      Assert.NotNull(message.To); 
      var recipient = message.To.FirstOrDefault(); 
      Assert.NotNull(recipient); 
      Assert.Equal(recipient.Address, "[email protected]"); 
      Assert.Equal(message.Subject, "Test"); 
      Assert.Equal(message.Body, "Test."); 
     } 
    } 
} 

No creo que este código requiera ninguna explicación, pero si lo hace hágamelo saber.

+0

Sólo una cosa que decir. Lea este libro: http://www.amazon.com/Art-Unit-Testing-Examples-Net/dp/1933988274. Serás otro desarrollador después de leerlo. – Steven

+0

@Steven: lo leeré; gracias. – Arlen

Respuesta

6

Intento mantener mis UnitTests bastante pequeños y probar una cosa a la vez. Así que probablemente haga pruebas de partes distintas en pruebas separadas, p.

  • sendWillSendAnEmail,
  • fromContainsSenderAddress,
  • toContainsRecipientAddress,
  • mailBodyContainsMailMessage,
  • mailContainsSubject
+0

¿Pero no terminas con un código repetido o una gran cantidad de código de infraestructura para configurar estas varias pruebas? ¿Realmente vale la pena? – Arlen

+1

@Arlen: Mi unidad prueba que la carpa tenga que repetir un poco el código, pero mantén esto al mínimo usando los métodos de fábrica para la configuración de prueba y los métodos de confirmación personalizados. El truco es minimizar la duplicación de código para garantizar el mantenimiento, pero también garantizar la legibilidad. Este es el arte de la prueba unitaria :-) – Steven

+1

@Arlen Normalmente, configuro lo que se necesita en el método de configuración para que esté disponible en cualquier prueba o escribo un ayudante para configurar el estado, sea lo que sea, menos código. Eso funciona bastante bien y con muy poca duplicación de código para mí. No agregó una etiqueta de idioma a su pregunta, así que debería tener en cuenta que estoy usando PHPUnit. PHPUnit es un framework xUnit así que supongo que lo mismo debería ser posible con su framework. – Gordon

1

No, en general, cuantas más afirmaciones, mejor. Un error común en las pruebas unitarias no es lo suficientemente explícito.

Su prueba es muy explícita y legible. Me gustan especialmente las afirmaciones sobre null. Es una buena práctica porque hace que interpretar una falla de prueba sea extremadamente simple.

La única forma en que puede tener demasiadas afirmaciones es si afirma exactamente lo mismo más de una vez, lo cual no está haciendo.

4

veo ningún problema particular con su afirma, pero si desea limpiar su código, puede cambiar

var session = server.Sessions.FirstOrDefault(); 
Assert.NotNull(session); 

en

var session = server.Sessions.First(); 

First() lanzará una excepción de todos modos, así que por simplemente cambiando tu código obtienes el beneficio que la afirmación te traería sin tanto código. Hay otros lugares donde puedes hacer cambios similares también.

Pero como regla general, no damos nada por sentado en las pruebas unitarias, ¡y eso significa muchas afirmaciones!

2

Depende de las normas a las que se adhiere, pero generalmente digo que sí, que tiene demasiadas afirmaciones en esa prueba.

Muchas personas afirman que una sola prueba debe tener una sola afirmación; Creo que puede ser un poco exagerado, pero ciertamente creo que es apropiado tener una prueba unitaria para un solo "pedazo" de funcionalidad; estás por todos lados con tus afirmaciones. La prueba es muy grande; dividirlo en varias pruebas diferentes.

0

Creo que la pregunta es, ¿los assert() d valores cambian de forma independiente? Si cambian de forma independiente, deben probarse en diferentes pruebas que varían las condiciones relacionadas con cada afirmación.

Sin embargo, si tiene un solo código que está generando un correo electrónico con todos esos campos, entonces es apropiado probar todo eso en una prueba.

Ahora la prueba es algo difícil de leer. Es posible que desee envolver esos asertos en un método descriptivo de ayuda. No me molestaría con eso hasta que encuentre que el mismo método de ayuda podría ser útil en otro lugar.

6

Creo que es demasiado grande.

Cuando tiene un montón de pruebas más pequeñas, puede obtener "localización de defectos": con solo ejecutar todas las pruebas, puede ver exactamente dónde está el problema. Con tantas afirmaciones como las que tiene actualmente (y sin mensajes de afirmación) probablemente tenga que iniciar un depurador para averiguarlo. Recuerde que probablemente terminará teniendo cientos si no miles de pruebas, y si un grupo de ellas falla, no quiere tener que depurar cada una para ver por qué.

Además, cualquier afirmación que falle temprano en la prueba significa que las afirmaciones posteriores no se ejecutarán. Cuando se separan en pruebas individuales, se verifica cada afirmación. Esto es una especie de compensación; muchas de esas afirmaciones probablemente están relacionadas y fallarán al mismo tiempo, por lo que tendrá cinco pruebas rojas en lugar de una. Pero trabajo desde la premisa de que hay más información mejor, así que preferiría tener esas cinco pruebas y saber que las cinco afirmaciones fallaron.

0

Sus muchas afirmaciones afirmativas son un indicador de cuánta lógica tiene en las pruebas unitarias. Tendrás que mantener tus pruebas unitarias como el código normal. Es mejor dedicar tiempo a la programación defensiva y a la programación por contrato que a las pruebas de unidades de código.

0

Tal vez pueda crear una nueva clase de correo electrónico que acepte todos esos parámetros en su constructor predeterminado.

Y luego puede lanzar una excepción en caso de que el usuario pase un parámetro no válido.

Y en su unidad de prueba

Send_sends_an_email_message

puede agregar el afirma que los cheques igualdades sólo que en lugar de comprobar contra los nulos.

Quizás pueda crear 2 correos electrónicos en una prueba y hacer la igualdad afirma para ambas instancias.

1

¡Sí, tienes demasiadas afirmaciones en tu código! Además, la declaración de afirmación debe ser solo uno por método de prueba. El uso de muchas afirmaciones puede ser el olor del código que está probando más de una cosa. Además, existe la posibilidad de que alguien pueda agregar una nueva afirmación en su prueba en lugar de escribir otra. ¿Y cómo puedes entender cómo terminaron tus otros asertos cuando falló el primero?

También pueden parecido interesante este post: https://timetocode.wordpress.com/2016/06/01/zen-of-unit-testing/

Cuestiones relacionadas