2010-12-09 9 views
18

Estoy tratando de aprender TDD pero me cuesta trabajo entender qué/cómo probar con una pequeña aplicación que necesito escribir.Aprendiendo TDD con un simple ejemplo

El (simplificado un poco) de especificaciones para la aplicación es el siguiente:

Se tiene que tomar por parte del usuario la ubicación de un archivo csv, la ubicación de una plantilla de combinación de correspondencia documento de Word y una ubicación de salida.

La aplicación leerá el archivo csv y para cada fila, combinará los datos con la plantilla de palabra y saldrá a la carpeta especificada.

Para que quede claro, no estoy preguntando cómo voy a codificar una aplicación de este tipo ya que estoy seguro de que sé cómo hacerlo si continúo y empiezo. Pero si quisiera hacerlo usando TDD, se apreciaría algo de orientación sobre las pruebas para escribir, ya que supongo que no quiero probar la lectura de un archivo csv real, o probar el componente de terceros que realiza la fusión o convierte a pdf.

¡Creo que solo una guía general de TDD sería de gran ayuda!

Respuesta

26

Empezaría por pensar en escenarios para cada paso de su prog carnero, a partir de los casos de insuficiencia y su comportamiento esperado:

  • usuario proporciona una ubicación de archivo csv nulo (lanza una ArgumentNullException).

  • El usuario proporciona una ubicación de archivo csv vacía (arroja un ArgumentException).

  • El archivo csv especificado por el usuario no existe (lo que crea que sea apropiado).

A continuación, escriba una prueba para cada uno de esos escenarios y asegúrese de que falle. A continuación, escriba el código suficiente para que pase la prueba. Eso es bastante fácil para algunas de estas condiciones, porque el código que hace que su paso de la prueba es a menudo el código final:

public class Merger { 
    public void Merge(string csvPath, string templatePath, string outputPath) { 
     if (csvPath == null) { throw new ArgumentNullException("csvPath"); } 
    } 
} 

Después de eso, se mueven en escenarios estándar:

  • el archivo CSV especificado tiene una línea (la combinación debe llamarse una vez, la salida debe escribirse en la ubicación esperada).

  • El archivo csv especificado tiene dos líneas (la combinación se debe realizar dos veces, la salida debe escribirse en la ubicación esperada).

  • El nombre del archivo de salida cumple con sus expectativas (sean las que sean).

Y así sucesivamente. Una vez que llegas a esta segunda fase, comenzarás a identificar el comportamiento que deseas esconder y simular. Por ejemplo, verificar si un archivo existe o no: .NET no hace que sea fácil encontrarlo, por lo que probablemente necesite crear una interfaz y clase de adaptador que le permita aislar su programa del sistema de archivos real (a no digas nada de los archivos CSV reales y las plantillas de fusión de correspondencia). Hay otras técnicas disponibles, pero este método es bastante estándar:

public interface IFileFinder { bool FileExists(string path); } 

// Concrete implementation to use in production 
public class FileFinder: IFileFinder { 
    public bool FileExists(string path) { return File.Exists(path); } 
} 

public class Merger { 
    IFileFinder finder; 
    public Merger(IFileFinder finder) { this.finder = finder; } 
} 

En las pruebas, pasará en una implementación de código auxiliar:

[Test] 
[ExpectedException(typeof(FileNotFoundException))] 
public void Fails_When_Csv_File_Does_Not_Exist() { 

    IFileFinder finder = mockery.NewMock<IFileFinder>(); 
    Merger  merger = new Merger(finder); 
    Stub.On(finder).Method("FileExists").Will(Return.Value(false)); 

    merger.Merge("csvPath", "templatePath", "outputPath"); 
} 
+1

¡Ejemplos concretos muy agradables! – Davy8

2

Para poder probar la unidad, necesita desacoplar la clase de cualquier dependencia para que pueda probar efectivamente la clase.

Para hacer esto, necesitará inyectar cualquier dependencia en la clase. Normalmente haría esto pasando un objeto que implementa la interfaz de dependencia a su clase en el constructor.

Los marcos de burla se utilizan para crear una instancia simulada de su dependencia que su clase puede llamar durante la prueba. Usted define el simulacro para comportarse de la misma manera que su dependencia y luego verifica su estado al final de la prueba.

Recomendaría tener un juego con los simulacros de Rhino y seguir los ejemplos en la documentación para tener una idea de cómo funciona esto.

http://ayende.com/projects/rhino-mocks.aspx

5

simple orientación general:

  • Usted escribir primero las pruebas unitarias. Al principio todos fallan.
  • Luego ingresa a la clase bajo prueba y escribe el código hasta que las pruebas relacionadas con pasen cada método.
  • Haga esto para cada método público de sus tipos.

Al escribir la prueba de las unidades que realmente especifica los requisitos, pero en otra forma, fácil de leer el código.

Mirándolo desde otro ángulo: cuando reciba una nueva clase de recuadro negro y pruebas de unidad, debe leer las pruebas unitarias para ver qué hace y cómo se comporta la clase.

para leer más de las pruebas unitarias recomiendo un libro muy bueno: Art Of Unit Testing

Aquí hay un par de enlaces a artículos sobre StackOverflow respecto TDD para más detalles y ejemplos:

+1

+1 para hacer referencia a El Arte de las pruebas unitarias. Es un gran libro. – Steven