Este documento presenta los conceptos fundamentales del desarrollo guiado por pruebas (TDD). Explica que TDD involucra escribir las pruebas automáticas antes de escribir el código de producción para guiar el diseño e implementación. También describe las características de buenas pruebas como ser automáticas, aisladas y repetibles. Finalmente, presenta ejemplos prácticos de implementar TDD al desarrollar una calculadora y un analizador léxico.
2. Agradecimiento La presentación y ejemplosfueronproducidospor el Maestro Angel “Java” Lópezpara el: Southworks Professional Improvement Program http://pip.southworks.net Twitter: @ajlopez
3. Test-Driven Development No es sólo escribir test Kent Beck: No escribir una línea de código sin tener primero un test (failing automated test) Eliminar duplicación Programmer Tests http://www.nunit.org Customer Tests http://fit.c2.com
5. Origen de TDD Kent Beck “redescubre” TDD 1970: Waterfall – Winston W. Royce(lo bueno y lo malo) 1996: Sunit (guía para un mejor Smalltalk) 1999: Primera edición XP (Extreme Programming) 2002: TDD byexample 2005: Segunda edición XP
6. Código Simple que Funcione (Cita de Ron Jeffries, Kent Beck) Criterio “que Funcione”: Pase todos los tests automáticos Criterio “Código Simple”: Apropiado para la audiencia Comunica la intención Factorizado, sin duplicaciones Mínimo
9. Características de un buen test Automático Si es manual, no lo hacemos, o nos cuesta mucho A fondo No debe dejar parte sin probar Repetible En cualquier momento Independiente Aíslado, poner bajo prueba una sola cosa Profesional Rápido Si no, evitamos ejecutarlo Vale el esfuerzo de escribir el test Fuente: PragmaticUnitTestingbyDave Thomas, Andy Hunt
11. Atributos y Variantes TestCase, Fixture o Class Test Method SetUp, TearDown ExpectedExceptions
12. Los tests Escribirlos primero, diseñando lo que se necesita Se evita código innecesario Se crea la especificación de lo que se está construyendo Sirve como red de seguridad ante cambios Minimizan la depuración BabySteps
14. Ejemplo: Lista de Tests Crear Stack y verificar IsEmpty Push un elemento y IsEmpty es falso Push un elemento, Pop, IsEmpty en verdadero Push un elemento, igual al siguiente Pop Push tres elementos, Pop de los tres, verificar orden Pop de una Stackvacía (que genere InvalidOperationException) Push de tres items, Pop de uno, IsEmpty en Falso
15. Refactoring Mejorar el diseño sin cambiar la funcionalidad Cambio de nombres Extraer métodos Eliminar código duplicado Tests en verde
16. Code Coverage Integrado en Visual Studio Reporte de código “cubierto” por los tests Aplicando TDD: No se agregan líneas que no respondan a un tests Se logra un CodeCoverage alto
17. SUT: System Under Testing Colaborador A Test Method SUT Test Method Colaborador B Test Method Colaborador C
18. Tipos de Objetos Colaboradores Dummy: pasado pero nunca usado Fake: implementación andando, pero es un atajo. Ej: base de datos en memoria Stubs: respuestas ya preparadas, pueden registrar información sobre los datos pasados Mocks: preprogramados con “expectations”, que son una especificación de las llamadas a recibir El “Real”
19. Temas a discutir AAA BDD Refactor del Tests Threading Ejemplos con Atributos de inicialización, setup, etc.. Tests contra bases de datos
21. Construir un Lexer Clase Lexer Dada una entrada nos debe dar los “tokens” en forma de string Entrada dada en el constructor Como TextReader Como String Gran método a implementar: string NextToken() Al no haber más a procesar, que devuelva null
22. Tests Crear el Lexer, y que procese “name” como nombre, y luego, null Procesa “ name “ (con espacios) como nombre “name”, y devuelve null Procesa “123” como “123” Procesa “name1 name2” como “name1”, “name2” , y devuelve null Procesa “(,)” como “(“, “,”, “)” , y devuelve null Procesa “name(par1, par2)” como “name”, “(“, “par1”, “,”, “par2”, “)” , y devuelve null
25. Números a Letras Implementar un método que reciba un entero y devuelva un string El string tendrá la traducción a palabras del número Ejemplo 12 “doce”
26. Lista de Tests 1 -> “uno” 2 -> “dos” … y así hasta 9 10 -> “diez” 11 -> “once” 12 -> “doce”.. Y así hasta 19 21 -> “veintiuno”… y así hasta 29 30 -> “treinta”, 40 -> “cuarenta”, y así hasta 90 31 -> “treinta y uno” … y así hasta el 39
27. Lista de Tests Probar los 40..49, 40..59, y así hasta el 90..99 cumple el mismo patrón 100 -> cien 101 -> ciento uno, y así hasta 199 , dan “ciento “ más el módulo 100 200 -> doscientos, 300 -> trescientos, 400, 600, 800, son “número” + “cientos” Casos 500, 700, 900 1000 -> mil 1001 a 1999 dan “mil “ más módulo 1000 Casos 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000 son “número”+”mil”
28. Calculadora de String Clase con método Evaluate que reciba un String (texto) con números enteros y operaciones como 1 * 3 + 12 Y devuelva el resultado
29. Lista de Tests Recibe “1” y devuelve 1 Recibe “2 + 3” y devuelve 5 Recibe “2 -3” y devuelve -1 Recibe “-1+2” y devueve 1 Recibe “2*3” y devuelve 6 Recibe “2*3+1” y devuelve 7 Recibe “2*(3+10)” y devuelve 26 Recibe “(3+3) / 2” (con espacios) y devuelve 3
30. Nueva Factura Hay productos, con descripcion, precio, peso, lleva IVA o no Hay Factura, a la que se le pueden agregar productos (cantidad facturada) Hay una tasa de IVA del 21%
31. Lista de Tests Tomemos Producto 1: $100, con IVA, 100gr de peso Producto 2: $200, sin IVA, 50gr de peso En nueva factura, su subtotal (sin IVA) es 0, total final es 0, IVA es 0, cantidad es 0, peso es 0 Se agrega un Producto 1 a Factura, dando Subtotal $ 100, IVA $ 21, Total $121 Cantidad 1, Peso 100 Se agrega un Producto 2 a Factura, dando Subtotal $ 200, IVA $ 0, Total $100 Cantidad 1, Peso 50
32. Lista de Tests Se agrega un Producto 1 y un Producto 2 Subtotal $ 300, Iva $21, Total $ 321 Cantidad 2, Peso 150 Se agrega 2 Producto 1 a Factura, dando Subtotal $ 200, Total $242 Cantidad 2, Peso 200 Se agrega un Producto 1 y dos Producto 2 Subtotal $ 500, IVA $21, Total $ 521 Cantidad 3, Peso 200 Sugerencia: hacer una planilla para especificar tests
36. xUnit Test Patterns Refactoring Test Code Gerard Meszaros Addison-Wesley 0-13-149505-4
37. Enlaces Writing Great Unit Tests: Best and Worst Practiceshttp://blog.codeville.net/2009/08/24/writing-great-unit-tests-best-and-worst-practises/ Demistifying Extreme Programming: Test-driven programminghttp://www.ibm.com/developerworks/java/library/j-xp042203/index.html What is a Unit Test?http://jesschadwick.blogspot.com/2009/11/what-unit-test.html Qualities of a Good Unit Testhttp://codebetter.com/blogs/jeremy.miller/archive/2005/07/20/129552.aspx