TESTS UNITARIOS
“keep the bar green to keep the code clean”
¿Para qué hacer tests unitarios?
� Es imposible hacer software libre de defectos.
� Tiempo del desarrollador:
Diseño
Análisis
� Los tests unitarios aumentan la productividad, mejoran
la calidad y hacen que el software sea más confiable.
Debug
Desarrollo
Diseño
Pruebas que podemos hacer
Testing
Tests del desarrolladorTests del desarrollador
Tests automatizados
Tests unitarios
Los Tests Unitarios deben… (I)
Ayudar a mejorarla calidad
Tests comoespecificación
Ayudar a entenderel “sistema bajoprueba” (SUT)
Tests comodocumentación
Reducir
(no introducir)
riesgos
Tests como red de seguridadespecificación
Repelentes de bugs
Localización de defectos
documentación de seguridad
No causar daño
Los Tests Unitarios deben… (II)
Ser fáciles de ejecutar
Automáticos
Ser fáciles de escribir y mantener
Simples
Requerir mínimo mantenimiento, mie
ntras el sistema evoluciona
RobustosAutomáticos
Self-Checking
Repetibles
Simples
Expresivos
Separaciónde
incumbencias
Robustos
Principios (I)
� Escribir los tests primero (TDD)
� Diseñar para ser testeable
� Usar la puerta de entrada primero
� Comunicar intención
� No modificar el «sistema bajo prueba» (SUT)
� Mantener los tests independientes
� Aislar el SUT (evitar sensibilidad al contexto)
Principios (II)
� Minimizar la superposición de tests
� Minimizar el código no testeable
� Mantener la lógica del test fuera del código
productivoproductivo
� Verificar una condición por test
� Separar incumbencias por test
� Asegurar esfuerzo y responsabilidad
proporcionales
¿Qué tipos de tests podemos automatizar?
Tests por funcionalidad
De aceptación
Tests transversales a la funcionalidad
UsabilidadDe aceptación
(Pruebas de cliente)
De componentes (Diseño del sistema)
Unitarios
(Diseño del código)
Usabilidad
Exploratorios
(Consistencia)
De interfaces
(Prototipos / Integración)
¿Con qué objetivos automatizamos?
� Deben estar alineados con todos los objetivos
de Calidad.
� ¿Deseamos automatizar las pruebas regresivas?¿Deseamos automatizar las pruebas regresivas?
� ¿Deseamos realizar Integración Continua en
nuestro Proceso de Desarrollo?
� ¿Estamos buscando resolver un ítem específico
de Aseguramiento de Calidad?
Estrategias para automatizar tests
� Comenzar a automatizar tests desde el inicio
del proyecto
� Elegir la herramienta adecuada
� xUnit frameworks
� Robot user
� Scripted UI
� Seleccionar los casos de prueba a automatizar
Frameworks
� Java� jUnit http://www.junit.org
� TestNG http://www.testng.org
� .Net� MSTest Incorporada en Visual Studio� MSTest Incorporada en Visual Studio
� MBUnit http://www.mbunit.com
� NUnit http://www.nunit.org
� xUnit.NET http://www.codeplex.com/xuni
� Otros� HttpUnit
� DBUnit
Organizando los Tests Unitarios
xUnit
Test SuiteTest Suite
Test Fixture
Test Fixture
[Set Up] [Tear Down]
Crear el SUT y sus
dependencias
[Set Up]
• Inicializarlas en el estado
requerido
Ejecutar el SUT
Verificar
[Tear Down]
• Finalizar
Estrategias para el Test Fixture
Estrategia
TransientFresh
Set Up
X
Tear DownSet Up /
Tear DownTriggering
Fresh
PersistentFresh
Shared
X
X
X
X
X X
¿El código es testeable?
Dependencias Configuración
TDDEstados internos
¿Cómo testear?
• Set up de un estado “pre-test” simple del SUT
• Ejecutar el SUT, llamando al método a testear
Testear el “camino feliz”
• Llamar métodos de assert sobre las respuestas del SUT
• Llamar métodos de assert sobre el estado “post-test”
Verificar las salidasdirectas del
“camino feliz”
• Variar los argumentos del método SUT
• Variar el estado “pre-test” del SUT
• Controlar las salidas indirectas del SUT via un Test Stub
Verificar caminos alternativos
• Usar Mock Objects o Test Spies para interceptar y verificar las llamadas salientes a métodos
Verificar el comportamiento de
las salidas indirectas
• Hacer que los tests corran rápido
• Hacer que sean fáciles de entender y mantener
• Diseñar el SUT para ser testeable
• Reducir el riesgo de bugs no percibidos
Optimizar la ejecucióny mantenibilidad
Organizando los tests…
� Clase de Test por:
� Clase
� Funcionalidad
� Fixture
� Reutilización de código
de test
� Test superclass
� Test helper� Fixture
� Convenciones de
nombres
� Minimizar tamaño de
métodos de test
� Test helper
� Test Suites
� Independencia de tests
en producción
Recursos de verificación
• Reemplazan componentes de los cualesdepende el SUT, por una implementación liviana
• Mejoran la performance de los testsFakes
• Reemplazan un objeto del SUT para verificar siMocks • Reemplazan un objeto del SUT para verificar siesta siendo correctamente utilizado por el SUTMocks
• Alimentan al SUT con entradas indirectasesperadas
• Permiten verificar salidas indirectas del SUTStubs
• Objetos sin implementación que se pasan comoparámetros de métodos del SUTDummies
Frameworks
� NMock2
http://sourceforge.net/projects/nmock2
� TypeMock
http://www.typemock.comhttp://www.typemock.com
� Rhino Mocks
http://www.ayende.com/projects/rhino-mocks.aspx
Al verificar los resultados…
� Reducir duplicación de código de verificación
� Revelar la intención de la prueba
� Evitar la lógica condicional en los tests
(«ifs» y «loops»)
Integración continua
� Todo el equipo debe trabajar con la versión más reciente
� Permite detectar problemas de compatibilidad de manera tempranamanera temprana
� Reduce los riesgos y
tiempos de integración
� Cada desarrollador es
responsable de integrar
su propio código
Code coverage
� Métrica del grado en que el código de un software es testeado
� Criterios de coverage� Criterios de coverage
� Función
� Sentencia
� Decisión
� Condición (true/false)
� Condición / Decisión
Bibliografía
� xUnit Test Patterns: Refactoring Test Code(Gerard Meszaros)
� http://xunitpatterns.com/
� Integración Continua(Martin Fowler)
� http://www.martinfowler.com/articles/continuousIntegration.html
FIN