DeSymfonyDay 2014 - To mock or not to mock - Spanish
TDD y pruebas unitarias para el desarrollo de software
1. TDD (AIS GRAD. ING.
INFORMÁTICA)
Ricardo Valle Ramírez
Daniel Montero Lucena
2. 2
• Es una práctica de programación que consiste en escribir
primero las pruebas software, y después el código fuente
que pasará esas pruebas.
• El TDD no es para hacer pruebas, sirve para diseñar el
código fuente.
1. ¿QUÉ ES EL TEST DRIVEN
DEVELOPMENT?
3. 3
• Son las investigaciones empíricas y técnicas, cuyo objetivo
es proporcionar información objetiva, sobre el
funcionamiento y calidad del software.
• Estas pruebas están basadas en casos de prueba
concretos. código fuente.
1.1. ¿QUÉ SON LAS PRUEBAS
SOFTWARE?
4. 4
1.2. ¿QUÉ SON LOS CASOS DE
PRUEBA?
• Es un conjunto de condiciones o variables, bajo las cuáles
se determina si un software o una parte del mismo, está
correctamente implementado.
• Debe haber al menos un caso de prueba, por cada
requisito del software.
5. 5
• Introducción/Visión general: Contiene información general sobre los
mismos (nombre, versión, propósitos, etc).
• Actividades de los casos de prueba (configuración, inicialización,
finalización y acciones).
• Resultados (salida esperada, salida obtenida, resultado, severidad, etc).
1.2.1. ESTRUCTURA DE LOS CASOS
DE PRUEBA
7. 7
3. PROCESO DE DISEÑO SOFTWARE
BASADO EN TDD.
1. El cliente escribe sus requerimientos para
el usuario.
2. Se escriben junto con el cliente los
criterios de aceptación de estos
requerimientos.
3. Se escoge el criterio de aceptación más
simple y se traduce en una prueba unitaria.
4. Se comprueba que esta prueba falla.
5. Se escribe el código que hace pasar la
prueba.
6. Se ejecutan todas las pruebas
automatizadas.
7. Se refactoriza y se limpia
el código.
8. Se vuelven a pasar todas
las pruebas automatizadas.
9. Volvemos al punto 3 con
los criterios de aceptación
que falten y repetimos el
ciclo una y otra vez hasta
completar nuestra
aplicación.
8. 8
4. ¿CUÁLES SON LOS REQUISITOS
DEL TDD?
• El programa tiene que ser lo suficientemente flexible,
como para permitir las pruebas automáticas.
• Cada prueba será lo suficientemente pequeña, como para
determinar unívoca mente si el código probado pasa o no
la verificación.
9. 9
[Pie de Página]
• Evitar escribir código innecesario. Se intenta escribir el
mínimo código posible.
• Confianza en el código escrito, ya que, habrá que pasar todas
las pruebas escritas.
• El programador debe hacer fallar los casos de prueba, para
garantizar que realmente funcionan.
5. CARACTERÍSTICAS NECESARIAS
PARA LA UTILIZACIÓN DEL TDD
10. 10
• Al utilziar el TDD en un proyecto virgen, reducimos la
necesidad de utilizar un depurador o debugger.
• Después del elevado trabajo inicial, conseguimos
software de más calidad y en menos tiempo.
• El programador se centra en la tarea actual, es decir, en
una primera meta que consiste en pasar la prueba.
• Utilizado correctamente, garantizamos que todo el
código está cubierto por una prueba.
6. VENTAJAS O BENEFICIOS DE
UTILIZAR TDD
11. 11
• Mejora la comunicación. Como los problemas llegan en
cortos periodos de tiempo, fomenta la comunicación
entre el equipo.
• Mayor tranquilidad. Gracias al uso del TDD se
garantiza que el código será puro, claro y limpio.
• Refactorización. Después de encontrar un problema,
pasamos el proceso de refactorización del mismo, sin
tener que esperar a tener el código completo.
6. VENTAJAS O BENEFICIOS DE
UTILIZAR TDD
12. 12
• Escalabilidad. A medida que el proyecto avanza, el
código se hace más complejo.
• Satisfacción del cliente. Los test están pensados desde
el punto de vista del cliente.
• Mejor integración con terceros. Al llevar un minucioso
seguimiento de las tareas, reducimos los costes y el
tiempo.
6. VENTAJAS O BENEFICIOS DE
UTILIZAR TDD
13. 14
• Se deben de poder utilizar sin necesidad de
intervención manual. Es decir, se debe poder
automatizar.
• Tienen que poder ejecutarse independientemente del
estado del entorno.
• La ejecución de una prueba no debe afectar a la
ejecución de otra.
8. PRUEBAS UNITARIAS DEL TDD
14. 15
[Pie de Página]
• Después de las pruebas, el entorno debe
quedar como estaba previamente a la ejecución
de las mismas.
• Conocimiento claro del objetivo de la prueba y
su funcionamiento.
8. PRUEBAS UNITARIAS DEL TDD
15. 16
[Pie de Página]
Implementación de las cuentas corrientes de los
clientes de un banco.
1- Requisitos:
1. El saldo actual de la cuenta debe ser 0.
2. El saldo de la cuenta no puede ser negativo
9. EJEMPLO DE USO DE TDD
16. 17
[Pie de Página]
2- Creación del proyecto “CuentaBancariTDD” y su
carpeta para guardar los test.
3- Escoger uno de los requisitos, “ El saldo actual de
la cuenta debe ser 0”.
4- Hacer el test que garantice este requisito.
Analizando el requisito, vemos que es necesario
ser capaces de crear una cuenta, es decir, crear un
objeto de tipo cuenta.
9. EJEMPLO DE USO DE TDD
17. 18
[Pie de Página]
También es necesario poder obtener el saldo de la
cuenta.
5- Con esto vamos a crear un test que cree un objeto
tipo cuenta, y que su estado sea 0.
Código:
<?php require_once/../src/CuentaBancaria.php';
class CuentaBancaria_Test extends PHPUnit_Framework_TestCase {
public function testBalanceIncialEsCero (){
$this -> cb = new CuentaBancaria();
$this -> assertEquals ( 0 , $this -> cb -> getBalance ();
} }
9. EJEMPLO DE USO DE TDD
18. 19
6- Vamos a probar si falla el código. Creamos una nueva clase
de cuenta bancaria, y nos devolverá el balance de ésta.
<?php
Class CuentaBancaria {
protected $balance = 0;
public function getBalance()
{
return $this -> balance;
} }
9. EJEMPLO DE USO DE TDD
19. 20
7- Ejecutamos el test para ver si funciona.
8- Codificamos el test para el siguiente requisito.
Código:
public function testBalanceNoPuedeSerNegativo ( ) {
$this -> cb = new CuentaBancaria();
try { $this -> cb -> retirarDinero ( 1 ) ; }
catch ( Exception $e ) {
$this -> assertEquals ( 0 , $this -> cb -> getBalance ( ) ) ;
return ;
} }
9. EJEMPLO DE USO DE TDD
20. 21
9. EJEMPLO DE USO DE TDD
9- Creamos el código del segundo requisito. Creamos dos
funciones, una para depositar dinero, y otra para comprobar que
el balance es superior a 0.
protected function setBalance ( $balance )
{ if ( $balance >= 0 ) {
$this -> balance = $balance ;
} else {
throw new Exception();
} }
public function depositarDinero ( $balance ) {
$this -> setBalance ( $this -> getBalance ( ) + $balance ) ;
21. 22
9. EJEMPLO DE USO DE TDD
10- Pasamos el test.
11- Refactorizamos para quitar código duplicado, y depurar lo
12- Código de la clase test:
22. 23
9. EJEMPLO DE USO DE TDD
<?php
require_once '/../src/CuentaBancaria.php';
class CuentaBancaria_Test extends PHPUnit_Framework_TestCase {
protected $cb;
protected function setUp(){$this -> cb = new CuentaBancaria();}
public function testBalanceIncialEsCero ( ){
$this -> assertEquals ( 0 , $this -> cb -> getBalance () ) ;
}
public function testBalanceIncialEsCero ( ) {
$this -> assertEquals ( 0 , $this -> cb -> getBalance () ) ;
23. 24
9. EJEMPLO DE USO DE TDD
13- Test para comprobar que se cumple el requisito 2:
public function testBalanceNoPuedeSerNegativo2(){
try {
$this -> cb -> retirarDinero ( 1 ) ; }
catch ( Exception $e ) {
$this -> assertEquals ( 0 , $this -> cb -> getBalance ( ) ;
return 0 ; } }