2009-02-05 8 views
29

TDD es algo que parece estar en boca de todos en estos días, y lo he probado solo, pero no creo que me haya entendido. Entiendo cómo escribir una prueba unitaria, pero no entiendo exactamente qué deberían probar las pruebas de mi unidad.¿Qué prueba con las pruebas de su unidad?

  1. Si tengo un método de acción que devuelve una lista de datos, ¿qué debo verificar? Solo que el nombre de la vista es correcto, o debo verificar los datos también?
  2. Si también debo probar los datos, ¿no escribiré el mismo código dos veces? ¿Para qué sirve probar los datos si utilizo el mismo método para recuperar los datos que comparo?
  3. ¿Debo probar los métodos para agregar/editar mis datos también? ¿Cómo verifico si un registro ha sido agregado/editado/eliminado, de manera correcta?

Sé que es un buen montón de preguntas grandes, pero no he vuelto más sabio de la lectura de artículos en internet, ya que todos ellos parecen estar preocupados con cómo para poner a prueba, y no con lo.

Como ejemplo, tengo (o voy a escribir) un GuestbookController, con métodos para ver, agregar, editar y eliminar publicaciones. ¿Qué necesito probar? ¿Cómo lo hago?

Respuesta

26

pruebas unitarias (UT)! = Test Driven Design (TDD)

Esta confusión parece ser bastante común. UT tiene que ver con la cobertura del código. TDD se refiere a características. Son no lo mismo [lo siento Joel!]

Con UT, escriba el código que desee, luego regrese y pruebe cada función (incluso algunas triviales).

Con TDD, selecciona la siguiente función y escribe primero la prueba para esa función. Escriba solo la prueba para esa función, y la cobertura de prueba es irrelevante. Primero escribe la prueba para forzar las decisiones de interfaz que se tomarán por adelantado. Luego, escribe el código para pasar la prueba (teniendo en cuenta lo 'más simple que pueda funcionar'). Luego, refactoriza el código según lo que ha aprendido. Luego se pasa a la siguiente función (presumiblemente después de registrar y volver a ejecutar todas las pruebas de unidad).

Si lo desea, desarrolle usando TDD y luego vuelva atrás y complete la cobertura con las herramientas UT. Si está creando una biblioteca de clases u otra API para que los desarrolladores la usen, cuanta más cobertura de prueba mejor ;-)

Si solo está escribiendo una aplicación para hacer cinco cosas específicas, TDD solo debería ser suficiente.

+2

Estoy de acuerdo en que UT! = TDD, ya que TDD es una metodología que usa UT. Sin embargo, no conozco ninguna definición en la literatura de TDD, que respalde su afirmación acerca de que UT tiene que ver con la cobertura. Por favor elabora. –

+0

@ [Brian Rasmussen]: el énfasis de UT en la cobertura del código proviene de dos fuentes: proveedores de herramientas de cobertura de código y personas distraídas por (fascinadas con) las métricas de cobertura de código. UT en sí mismo es una herramienta, no una metodología. No hay ninguna mención de cobertura de código en absoluto en ninguna de las publicaciones de TDD que he leído. –

+1

Con la prueba unitaria, no prueba todas las funciones. Por ejemplo, no prueba getters y setters que no tienen lógica en ellos. Sin embargo, si hacen más que devolver o establecer un valor, entonces de hecho se prueban. –

0
  1. Para una entrada o estado dado, debe probar que el valor de retorno del método es el esperado. Si su método arroja muchos tipos de datos, debe verificar que sean correctos.
  2. Utilice un pequeño conjunto de datos de muestra directamente en su caso de prueba. No cargue nada desde el disco o una base de datos. Pase una cuerda o construya el objeto de prueba allí en su prueba. Dado ese pequeño conjunto de datos, usted espera obtener un resultado muy específico de su método, que usted compara con su resultado real. ¡Desea evitar mucho código que calcula valores para usted en sus pruebas, porque entonces tendría que escribir pruebas para sus pruebas para asegurarse de que funcionen correctamente!
  3. Pruebe cada bit de código que escribe. Para agregar un registro (si sus pruebas están conectadas a una base de datos de prueba) simplemente puede consultar el último registro insertado, o comparar el total de registros antes y después y asegurarse de que se incremente en uno. Si tiene un marco de burla/stubbing puede omitir la base de datos y afirmar que se llamó el método que guarda las cosas en la base de datos. Para probar una edición solo recupere el registro editado de la base de datos nuevamente y afirme que el valor ha cambiado desde su valor anterior. O si se burlaba/tropezaba, que el método para cambiar el valor del atributo se llamó correctamente.

Pero, en realidad, a escribir una prueba para la porción de código que son punto de escribir. Mira que no. Luego escribe el código suficiente para hacerlo pasar. Ahora escribe otra prueba y repite.

0

Creo que puede obtener el mayor beneficio de la prueba unitaria mediante el desarrollo impulsado por prueba/desarrollo de prueba primero. Primero debe escribir la prueba y luego escribir el código que aprueba la prueba. ¿Y qué debería probar primero?

Me resulta muy útil para escribir pruebas de historias de usuario. La mayoría de las veces escribo pruebas de estilo desde el inicio de historias de usuarios. Por ejemplo, nuestra historia de usuario contiene una tarea como esta:

  1. Cuando el usuario guarda una vista de orden debe mostrar el mensaje de información.

general I Write prueba para esta historia de capa de presentación/controlador

[Test] 
    public void When_User_Save_Order_View_Should_Display_Information_Message() 
    { 
     using (mockRepository.Record()) 
     { 
      repository.Save(order); 
      view.Message= "Order saved successfully"; 
     } 

     using (mockRepository.Playback()) 
     { 
      presenter = new OrderSavePresenter(view, orderRepository); 
      presenter.Save(); 
     } 
    } 

Y luego sigo escribiendo prueba para cada clase que ser burlado o necesitaba.

0

No me molesto en probar cosas simples, como un getter o un setter. No es necesario que pruebe el compilador por sí mismo, por lo que no es útil comprobar que se asigna un valor cuando llama a un setter.

En general trato de escribir una prueba unitaria para cada método de una clase que tiene código real. De esta forma, si alguien alguna vez rompe un método más adelante, será atrapado.

Por ejemplo, alguien cambió un método como "addElements (String [] elements)". Intentaron usar "for (int i = 0; i < = elements.length; i ++)". Se lanzó una excepción fuera de límites cuando las pruebas de la unidad se ejecutaron después del check-in y se corrigió.

Para algo así como un GuestBookController, puede haber métodos que puede probar sin conexión, pero es probable que deba establecer una conexión con un servidor de base de datos de prueba. A partir de ahí, realice una prueba para agregar una publicación, editar una publicación y eliminar una publicación, verificando en cada una el cambio que se produjo con un método que recupera la publicación.

Las pruebas unitarias deben hacer que se sienta más seguro de que su código funciona, y que cuando realiza un cambio, todavía funciona. Agregue el código de prueba de unidad hasta que se sienta seguro de que está probado adecuadamente. En el ejemplo anterior, no tiene que preocuparse tanto por romper accidentalmente el libro de visitas. Cuando realiza un cambio en el código, la prueba unitaria confirma que aún puede agregar, eliminar, editar y recuperar publicaciones.

+2

Para la * unidad de prueba * el controlador de GuestBook, el controlador realmente debería usar simulaciones DAO y simplemente afirmar que la interacción correcta ha tenido lugar. Una prueba de unidad nunca debería golpear la base de datos, ese es el trabajo de pruebas de integración – tddmonkey

3

prueba del contrato de la interfaz del módulo que se está probando:

  • Si un cliente se puede esperar un comportamiento específico al usar su clase, probarlo.
  • Si su clase debe evitar algún comportamiento del cliente, como se define en su contrato, pruébelo.

Por cliente me refiero al código que usa su clase.
Por comportamiento esperado me refiero al resultado esperado de un método sobre valores de retorno y estados de objeto.

y centrar su análisis en lógica (si, por, tiempo, etc.), porque las cosas plana como propiedades tienen menos oportunidades de fallar sin ser capturados por los usos normales de su aplicación.

1

Éstas son las pautas genéricas que encuentro útil para las pruebas unitarias:

1) Identificar objetos de contorno (Win/WebForms, CustomControls etc).

2) Identificar los objetos de control (objetos de la capa de negocios)

3) Asegúrese de escribir pruebas unitarias, al menos, para el control de objetos métodos públicos invocadas por objetos de contorno.

De esta manera estarás seguro de que estás cubriendo los principales aspectos funcionales (características) de tu aplicación y no corres el riesgo de realizar micro-pruebas (a menos que desees).

1

En TDD escribe las especificaciones del comportamiento del sistema y las utiliza para controlar el diseño del sistema. Usted escribe una prueba para un comportamiento minúsculo, luego mira cómo falla la prueba y luego escribe el código para pasar la prueba. En todo momento mantenga la calidad del código lo más alta posible refactorizando regularmente, de modo que sea más fácil hacer más cambios.

ejemplos de cómo hacer TDD: http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata

También vea mi respuesta de Writing standards for unit testing - tiene ejemplos y enlaces para obtener más información. Aquí también hay buenos enlaces a seguir: http://code.google.com/p/instinct/wiki/UsersGuide

+0

Estoy tan cansado de todos los gestos dogmáticos a mano de los ejemplos del mundo real. En su primer enlace, nadie proporcionó una respuesta satisfactoria al ejemplo de Keith Gregory. El hecho es que existen preocupaciones de ingeniería que tenemos para nuestra implementación que no deberían ser una preocupación de la API pública. – Jeremy

4

Creo que hay un poco de Shu-Ha-Ri aquí. Estás haciendo una pregunta que es difícil de explicar. Es solo después de practicar y luchar para aplicar TDD que obtendrás el What. Hasta entonces, te daremos respuestas que no tienen sentido, diciéndote cosas al alcance de Monads Are Burritos. Eso no te ayudará y sonaremos como idiotas (las mónadas son claramente pastel de limón y chifón).

Recomiendo conseguir Kent Beck's TDD book y trabajar a través de él, y luego simplemente practicar. "No hay un camino real hacia Ri".

+0

+1 para las Mónadas son enlace de Burritos - hilarante! – Contango

+0

+1 para el enlace del libro Beck –

Cuestiones relacionadas