Estado del arte y tendencias en Test-Driven Development

46  10  Descargar (2)

Texto completo

(1)

Facultad de Informática

Trabajo Final Integrador de la

Especialización en Ingeniería de Software

Estado del arte y tendencias en

Test-Driven Development

Autor: Moisés Carlos Fontela

(2)
(3)

&' * ()

Estado del arte y tendencias en

Test-Driven Development

Autor

! + ," ,

Palabras clave

! - ! " " ! " ! !

" ! " ,

Resumen

! ' " ! " " '

- ! " "

, ! - ! . " " ,

. " / . 0" - " " 0"

. ! " 0" "

-" , 1 . 0" " " .

0" , 2 3 - .

. " / " " ,

. " " " " !

(4)
(5)

&' 4 ()

Índice

' 5555555555555555555555555555555555555555555555555555555555555 6

7 8 9 5555555555555555555555555555555555 :

7 " 555555555555555555555555555555555555555555555555 %*

7 " ;& 555555555555555555555555555555555555555555555555555555 %(

< = 55555555555555555555555555555555555555555555555555555555555555555555 %(

> = 555555555555555555555555555555555555555555555555555555555555555555555 %)

> , < 55555555555555555555555555555555555555555555555555555555555555555555555555 %?

= " " 5555555555555555555555555555555555555555 %:

7 ' 555555555555555555555555555555555555555555 #%

5555555555555555555555555555555555555555555555555555555555555 ##

! " # $ %&& ''

555555555555555555555555555555555555555555555555555555555555 ## 9 " " = @ 555555555555555555555555555555555555555555555555555555555555 #*

" 55555555555555555555555555555555555555555555555555555555555555 #6

(&& ')

& " " " 5555555555555555555555555555555555555555555555555555555555555555 #?

7 " 555555555555555555555555555555555555555555555555555555555555555 #:

7 " 55555555555555555555555555555555555555555555555555555 #:

( * +

A"/ " 55555555555555555555555555555555555555555555555555555555555555555555555555 *$ " 555555555555555555555555555555555555555555555555555555555555555555 *$

, (&& - - ./

B 0" . / 555555555555555555555555555555555555555555555555 *%

B 55555555555555555555555555555555555555555555555555555555555555 **

B 0" / > 555555555555555555555555555555555555555555555 **

B " 55555555555555555555555555555555555555555555555555555 *(

< " . 555555555555555555555555555555555555555555555555555555555555 *(

(&& ! 0

(&&

-C " 9 555555555555555555555555555555555555555555555555555555555 *6

0" " 55555555555555555555555555555555555555555555555555555555555555 *?

" D 555555555555555555555555555555555555555555555555 *?

" ' ' 9 555555555555555555555555555555555555555555555 *:

1 (&& - ! +

- (&&

E 555555555555555555555555555555555555555555555555555555555555555555555555555555 (% " 555555555555555555555555555555555555555555555555555555555555555555555555555555 (# " 5555555555555555555555555555555555555555555555555555555555555555555555 (*

2

(6)
(7)

&' 6 ()

Introducción

TDD como práctica metodológica

% F G " '

-! 0" " # H > 8 I " . D

& *F;&G J%K,

>' ! " " ' =

• <" = " . . !

" 0" "

,

• = " ,

• E ( = - !

-" ! " " ,

" " 4=

%

! L " " M, " ' ! " / ,

#

! " ' " , . " '

/ %:)$! " 0" ." " " ,

*

! L& D M, " ' ;&! " / ,

(

B " / L M " / / L M! 0" "

L& ' M ,

4

0" L " M " .

, < ! " " "

(8)

&' ? ()

" " ' =

• 7 " ." ! "

" ,

• 7 " / " ! "

" " ,

! " " ,

• " "

" , / ' . . 0"

0" " ,

• "

" 3 ,

• 7 " "

-0" ! . ! ,

B " ! 0" ! 0" = L@" "

" " " 0" M J#K, 1 = L " " "

0" ' ! M J*4K,

0" " " " " !

" " 0" " , " 0"

" " ! " D !

(9)

&' : ()

@ 0" . " ' - ! " F

G! 0" " "

! 0" " ,

! " D 0" - , > 8 J%K

0" " " " ! "

- ! ' 0" .

' " ' ,

! " . . " ! 0" "

" ! " ! " 0"

. " . 0" " 4$N "

,

< 0" ! ' "

! / 0" , / " "

;&! " " !

' ,

La aparición de los frameworks y el corrimiento de TDD a UTDD

6

- ! " " "

,

" ' ! 8 " " = 9

8 O9 O , 7 " " '

. ! 0" / D9 ,

B = . . 0" .

" ! . . 0" . 0" " ,

! 0" " L M,

! " 0" " / - " !

, " . 0" " " !

" ' ! 0" 0" " "

/ " "

F @9 ( O9 ! "

0" " G, @ 0" " " " "

! " ! ' "

,

" " 0" 0" " !

0" - ! " . " " , < !

. " = O9 ! 9 ! @9 ! , 2 " > 8

" J#K " " , & 0"

0" " D " . " " ,

0" ! ! 9 . /D ,

" . ! ' =

• 7 " " "

/ " ,

)9 " . " ! 0" L9 M, "

(10)

&' %$ ()

• 7 " P 0" /

. ,

• 7 " " 0" '

! ,

• 7 " " " ' " 0"

0" ,

! / " ' =

• 0" - " ! "

" , B " ' 9 0" " "

" " / " / " ,

• E ! " . . 0" 0" "

" 6! . - ,

• @ " " ,

• " ' ! "

, 7 ,

• ' " " !

- " D " " ,

< " " " "

9 =

6

;& J%K 0" - ! 0" "

0" " ! 0" "

(11)

&' %% ()

" 0" ! " " !

0" ,

" 0" " ? ,

" 8 D9 " " " "

0" " =

• " ,

• ,

• 0" . 0"

" ! 0" "

,

• ! ,

& ! " " !

O9 0" " =

import org.junit.*;

import static org.junit.Assert.*;

? 7 ' L M .

(12)

&' %# ()

public class PruebaCuentaBancaria {

private final int NUMERO_VALIDO = 1234; private final int NUMERO_INVALIDO = -1234;

@Test

public void debeCrearUnaCuentaValidaConDatosSuministrados( ) { CuentaBancaria cuenta = crearCuentaValida();

assertEquals ("El número de cuenta se guardó mal",

NUMERO_VALIDO, cuenta.getNumero() ); assertEquals ("El nombre del titular se guardó mal",

"Carlos", cuenta.getTitular() ); assertEquals ("El saldo no comenzó siendo cero",

0, cuenta.getSaldo() ); }

@Test (expected = IllegalArgumentException.class)

public void creacionConNumeroInvalidoDebeArrojarExcepcion ( ) { CuentaBancaria cuenta =

new CuentaBancaria (NUMERO_INVALIDO, "Carlos"); }

@Test (expected = IllegalArgumentException.class)

public void creacionConTitularVacioDebeArrojarExcepcion ( ) { CuentaBancaria cuenta =

new CuentaBancaria (NUMERO_VALIDO, ""); }

@Test (expected = IllegalArgumentException.class)

public void creacionConTitularNuloDebeArrojarExcepcion ( ) { CuentaBancaria cuenta =

new CuentaBancaria (NUMERO_VALIDO, null); }

@Test

public void depositoDebeIncrementarSaldo ( ) { int montoDepositado = 100;

CuentaBancaria cuenta = crearCuentaValida(); int saldoPrevio = cuenta.getSaldo();

cuenta.depositar(montoDepositado);

assertEquals("El depósito funcionó mal",

saldoPrevio + montoDepositado, cuenta.getSaldo() ); }

@Test (expected = IllegalArgumentException.class)

public void depositoConMontoNegativoDebeArrojarExcepcion ( ) { CuentaBancaria cuenta = crearCuentaValida();

cuenta.depositar(-100); }

@Test

public void extraccionDebeDisminuirSaldo ( ) { CuentaBancaria cuenta = crearCuentaValida(); int montoDepositado = 100;

int montoAextraer = 50;

cuenta.depositar(montoDepositado); cuenta.extraer (montoAextraer);

assertEquals("La extracción funcionó mal",

(13)

&' %* ()

@Test (expected = IllegalArgumentException.class)

public void extraccionConMontoNegativoDebeArrojarExcepcion ( ) { CuentaBancaria cuenta = crearCuentaValida();

cuenta.extraer(-100); }

@Test (expected = SaldoInsuficiente.class)

public void extraccionConSaldoInsuficienteDebeArrojarExcepcion( ) { CuentaBancaria cuenta = crearCuentaValida();

cuenta.depositar(50); cuenta.extraer(100); }

private CuentaBancaria crearCuentaValida() {

return new CuentaBancaria (NUMERO_VALIDO, "Carlos"); }

}

@ 0" ! " '

D ! 0" ! " ,

. " . 0"

" ' ! , 2 ,

Los primeros intentos de pruebas de integración

0" " . 9 0" "

0" - ! ,

" " "

! ' ,

0" . ! 0"/

" 3 , 7 '

" " ! " 0" ,

< ! " " 0" " "

! ,

< " "

! 0" 0" Q J%(K ! 0" :=

• F ! L MG= 0" 0"

" " ! 0" " " , & ! " "

/ " ' ! / " " ,

• F ! L "- MG= 0" !

" " 0"

' , & ! 0"

" ,

• F ! L MG= " 0"

0" ' ! " " ,

• F ! L MG= 0"

,

:

Q . " " " ! " . "

0" . . . " " F J%4KG! ! " 0" " .

! . 0" "

(14)

&' %( ()

• F ! L MG= 0"

" , & ! " "

- ,

@ 0" 0" " " " 0" '

! " , " ! 0" '

" " " " ! "

" " ,

& ! " ! " 0" ' ,

0" "

0" " , 2 "

" " " ,

Q" . " 0" . 3 , <

" 0" " " " "

" D , & ! / /

,

& " " ! 0" " / ! " " / 8 0"

" " 0" " ,

La visión de las pruebas de cliente de XP

" H > 8 ;&! " " ' 0"

/ ' ! 0" "

" " 0" ,

" . 0" > 8 0" ,

! 0" " " ! 0" > 8

" , 7 " 0" " / 8

" %$! / " ! " / !

- " ! " ,

2 0" 8 " " . "

! D ! / " 0" "

" ,

" / ! 0" " . 0"

8 D9 ! / " !

- ! 0" " " " ! 0"

0" , / ,

El punto de vista de los requerimientos y del

comportamiento

ATDD: TDD ampliado

< %% F< G " ' - 0"

" " ,

%$

H > 8 9 ! " ! " . R ! O9 ,

%% ! L " " M, " ' < ! "

(15)

&' %4 ()

! " " ! 0" " !

" " " ! " ,

7 0" ! " ! " "

" " ! " " " ' !

" ,

< 0" " F 0"

. 9 " G=

7 " 0" / 0"

! 0" / 0"/ 0"/, & 0"

0" ! 0" ,

7 " "

,

< ! < " " / ' , "

" " < = <

(16)

&' %) ()

7 " 0" - !

' ! 0" "

, < ! ! "' . . "

0" ! = . 0" "

" ' " , < !

0" 0" %# !

" ,

" 0"/ D " " , 7 "

/ " " ! " 0"

! " ,

BDD: TDD mejorado

" 0" ! @ . J( 4K .

> . " %*F> G,

7 " @ .! 0" " "

%(

J)K F G! 0" ! / " !

/ , ! " ' '

, 2 "

! " " " !

" ,

< ' ! @ . " 0" " /

0" - ! , . . ! "

0" . 0" " " " " !

" / ! 0" '

,

7 . 0" " > ! " " . /

! " / ' !

0" " " ,

& / > ' ! " "

0" F " G " / , > !

/ " ! . 0"

/ " , 7 " 3

" / ,

3 , 0" 0" " " "

" , @ 0"

' , < ' ! . " "

! ,

" " 0" " ! . ' !

" ! 0" "

" ! " 0" 0" , 7 !

0" " . " 0" . " !

,

%#

L M! ! " "

" " ! " 0" . ,

%* ! L " M, " ' > ! " / ,

%(

(17)

&' %6 ()

" > ! " "

@ . " " ! F < " !

" G=

> ! ! " " , ! =

• 7 0" 0" > " ! " "

" , " " ,

• 7 0" 0" > . . J6K,

7 ' ! " 0" > / ! 0" ! 0"

. 0" ! " 0" , <

! 0" " . ,

& ! " F " . " / !

G=

As a [X] Como [X]

I want [Y] Deseo [Y]

(18)

&' %? ()

2 " " ! S " ;

0" " ,

> ' ! @ . " 0" " !

! D =

Given [un contexto inicial]

When [ocurre un evento]

Then [asegurar que se obtiene lo siguiente]

2 . > " " , & !

O> . ! . > O !

! ! 3 ,

7 . " >

, 0"

" . ' , " L"

" M J6K,

& " > ! ' < ! . " " > !

' . , ' . " "

" ! 0" D ! " ! !

,

BDD vs. ATDD

< > ' ' ! " #$$# "

#$$*,

2 " F> " !

0" < " G! " " ,

! 0" " " !

" " ,

! ' < > , ! " '

. ,

Q 0" > ! .

< 0" " /

, " . " ! 0"

" ' ! " "

, 8 " < "

" " ' ! . "

" ! " F" # G! "

" > , & 0" " 0" . > " !

" ! 0" "

' = " ! . < ,

7 0" ! > < " / 0" "

0" - 0" ! 0"

" , 2 9 " / - ! >

" - ! < " 0" , < /

0" " ! "

/ ! ' " / ' ,

! 9 " - ! 0" < >

(19)

&' %: ()

7 > < ' " =

• Q

• "

• Q " = ! " " ! !

• Q 0"

• "

• 9 " " 3 ! ' "

• " ! "

-7 0" > < "

! > Q ! " - " ,

3 / J?K! 0" - " , " " 0" !

" " " ! !

0" " " " "

" %4,

7 " . " ! D I " . J:K! 0"

' 0" " ! 3 !

! ' '

, 7 H 8 J%$K 0"

' ! ' ' ,

0" ' ! < > ,

STDD: ejemplos como pruebas y pruebas como ejemplos

A" . " " H > 8 J%K > < ! " "

/ . " %) F G,

L M! 0" Q" J#(K H 8 '

. " ! ' " ,

7 " " ! 0"

! . 0" / ,

< ! . " " ! 0"

, 7 " " "

" ! " , 7 ! "

! " ! 0" " , " !

! 0"

, " . 0"

! 0" 0" 0"

,

! . 0" 0" ! " !

0" , 0" " .

%4

. " " " "

-! " " . J*#K! 0" " "

F G,

%) ! L " . " M, " ' ! "

(20)

&' #$ ()

! - 0"

,

0" ! " ' =

• . " ,

• D D ! !

,

• ' ! ' ,

• 0" ! " ! " ,

• " ,

@ 0" " ,

" . ! " ! / " "

" " " ! 0" "

- ,

0" ! ' " =

• . L " M ! " !

! , " . D ! !

0" ,

• 0" " , E !

" " " ,

. ! 0" " " ,

• - " " , E !

" - ! " " " "

/ , " ! .

! / ,

• " " ! " ! . ,

0" ! =

• " ,

• " '

! 0" " " " / ,

• ! 0"

" ,

• " ' ! " "

! ,

" ! " ,

! ' " " 3 '

! " " " J)K, / "

0" 0" 0" ." ! 0" "

. 0" " , . 0" .

" 0" ' 0" 0" " . 0"

" " ,

Q' ' 0" " / 0" D

" ! . ! . !

" ,

! " !

(21)

&' #% ()

" " ! " ! " " ! . 0" 0"/

" ,

. =

• > Q 8 "- L M%6 J#$K! 0"

' . " ' ! / . "

L " M%?J#%K,

• R I R " J%:K! . . L 0" M%:,

• R 8 < J%*K = Q 8!

L M! L 0" " " M#$ '

L " ' M#%,

Q' ' ! " 0" " /

" 0" , 2 0" ! > 8

J%#K! L ' " "

0" " M,

Limitaciones de la práctica de especificar con ejemplos

0" D , ! . 0" 0"

0" " D " 0"

, & ! 0"

- " !

0" " " ! 0"

" ! " 0" " ,

< " 0" 0"

, ! ! J%*K!

##

! " ,

& ! 0" " , &

! " 3 ! 0"

" " , " '

" / - ,

1 ' " 0" " 0"

' 0" ! " " " , 2

,

0" ! 0"/

" =

• = " ! . . 0" ,

• = " ,

• = " ,

• Q = " ! ,

%6

L > D M,

%?

L>" M,

%:

L> 8 D 0" M

#$

L E 0" M,

#%

L< < M

##! F ! L MG / 0" " 0" . "

(22)

&' ## ()

• = " !

D ,

• E = " " ,

• @ " = " " ,

• = " " ,

• C D " " = " ,

• C = " ,

• = " ,

• < " = " !

D ,

Formatos de las especificaciones

B 0" .

= ! D ! , " !

! . . " ,

7 " " " " " ! " 0"

" " ! 0"

" " ' ,

D " " !

0" " " 0" " , & !

0" " ,

" ! 0" " D " !

, & ! . "

" 0" ! !

0" " " " ' ,

" ! "

" " ' ! " " " , ! "

. " "

/ ,

& ! . 0" " 0" " ! "

0" / . ,

El foco en el diseño orientado a objetos: NDD

El problema del comportamiento

" ! 8, 2

" ' ! " "

,

<. ! " ! ! . " /

' 0" ,

! 0" " " ! 0" "

! " " "

=

(23)

&' #* ()

// depósito de 1000 pesos:

cuentaBancaria.setSaldo ( cuentaBancaria.getSaldo ( ) + 1000 );

// si el cliente y la sucursal están en la misma localidad: if ( cliente.getDomicilio().getLocalidad().equals(

sucursal.getDomicilio().getLocalidad() ) ) { ... }

! 0" " ' ! 0" D /

=

punto.moverHorizontalPixeles ( 2 );

cuentaBancaria.depositar ( 1000 );

if ( cliente.estaEnMismaLocalidad (sucursal) ) { ... }

" " $ #*! 0"

" ! " ,

0" . "

" " 0" , & ! "

,

7 8 9 " !

!

" " , <. !

,

" ! " " " "

0" " , & ! T0"/ "

0" " ! "

" U . 0" "

" ,

" " ! . 0" 0" 0" " " "

! . 0" / " 0" !

" , !

" ! " ,

Una propuesta de solución: NDD

" " ! 11& 7< #$$(!

" " J##K! 0" 0"

/ ! '

" " " ! 3 9 ,

! ' @ #( F@ G,

& ! " . " "

@ J#*K! " " > , " !

" " J%?K " , / "

! . " % ! " 0"

#*

& 11& 7< %:??! 7 ! & "

, C . =VV , , ", "V .V V V V ??

, . =VV , , ", "V. V V7 ,. ,

#(

(24)

&' #( ()

0" 0" " " , & ! "

! ' @ ,

" " " - "

" ! =

• Q / ,

• & " ,

• E " ,

• ,

C / ! " 9 ! 0" !

0" 0"/ ' " "

" " ,

0" 0" " "

! . "

" ! @

0" , ! 9 !

0" @ / 0" ! " !

" 3 , 7 @ ! 0" / .

. Q 8! " ,

& ! " " " 9 =

(25)

&' #4 ()

(26)

&' #) ()

' ( 0" ) " *% + '

) " *% + (! 0" 8 ,

" " / @ =

• D 0" 0"

,

• E ! " ,

• D 0" " ,

• 0" ,

• C D ,

! ! "

" / " , . . . Q 8 #,

import org.junit.*;

import org.junit.runner.RunWith;

import org.jmock.integration.junit4.*; import org.jmock.*;

@RunWith(JMock.class)

public class PruebaInteraccion {

private final Mockery contexto = new JUnit4Mockery(); private final CuentaBancaria cuenta =

new CuentaBancaria (1234, new Cliente ("Carlos"));

@Test

public void deberiaPagarCreditoAsociado ( ) { final int MONTO_A_PAGAR = 5000;

// vinculación de objetos Cuenta y Credito:

cuenta.setCreditoAsociado(contexto.mock(Credito.class));

// expectativas:

contexto.checking(new Expectations() {{

oneOf(cuenta.getCreditoAsociado()).pagar(MONTO_A_PAGAR);

}});

// método que se va a probar:

cuenta.pagarCredito(MONTO_A_PAGAR); }

}

/ , - ! 0" ! " 0"

/ " " ! " /

! , @ 0" " ! "

. " 0" F Q 8 0" ! "

8 ! " . G,

9 @ " , ! 0"

. ! / " 0" "

(27)

&' #6 ()

" " !

0" . 0" . ! 0" " , 7

0" . 0" " ' ! 0" D

,

B " " " " @ =

• R 0" , 7

" 0" ' " " ' ,

• ! 0"

" ! " #4,

• R ,

• " " , !

0" ,

• " / " , "

! " " - ' ,

• " " . " " ! " 0"

,

Discusión sobre pros y contras

9 " " / 0" ! !

' 0" " ! "

, 2 0" ! "

, < ! "

,

7 . 0" "

" , 2 ! 0" " ! "

,

& ! 0" @ " " ! 0"

" ! ,

/ 0" " " !

0" !

,

! ,

0" @ 0"

, ! . "

8 " / " D #)! 0"

" / ! " " , ! 0"

@ = ' 0" 9 ! 0" 3 0"

" " 0" . ' " " "

0" ,

< ! @ " D "

,

1 " ! ! 0" " 0"

,

#4

<" 0" D " 0" " "

,

#) 7 L D M F / L MG 0" "

(28)

&' #? ()

& ! . 0" D , 0" ! 0" /

" , ! " .

" . " "

" , ! " 9 ,

Pruebas de interacción y TDD

Pruebas e interfaz de usuario

' F ! < ! > ! ! @ G "

! - , @ . "

" " " ! ,

" E 8 Q" I " . J:K 0" .

" " " " ! 0" / " "

" " . " , / @ . J*K! R 8 < J%*K!

@ & J%?K / 0"/ ! 0"

' ! ! "

" ,

< ! " 0" " " " " "

" ! " . /

/ ' 0" H > 8 ;& J%K,

! . " 0" " " " " ." , &

! " ! ! " !

' " , 2 " " 0" "

,

& ' " = ! 0"

" ! D. ! /

" " " ! /

" " ,

& - " ! " " 0"

" / " " " , ! "

! 0" "

" " " ,

! " " " ,

! 0" D . "

" ' , . . ! . / 0" D "

" " ,

. " " "/ "

! . 0" " " . "

, ' =

" " " " ' !

' ,

& ! . . . " " 0"

" " ! 7 <#6 J#)! #6 #?K,

/ Q J#4K,

#6

(29)

&' #: ()

La falta de una visión integral

! ! " / ! 0" "

" " " " !

,

! " ! . "

! ! " " ,

0" " " " ' ,

& " ! " ' ! "

D ,

" ! " " ! 0" ! .

" " , ! " ! /

" ! " ,

! . 0" " " , 2 0" " " /

! ! / " ,

& 0" . . " > , '

" , J%%K,

! " " . " " ! .

" , . . ! " "

0" ' " . ! ' 0" !

0" " " /

" " ,

Limitaciones de las pruebas de interacción

7 " " ! " 0"

. " = L " ' M#?, 7 0" "

" " ! =

• =

" " ! 0" . 0" " " ,

• = 3 0" - " " "

0" " ,

• = " . 0" "

! " 0" / ! 0" . 0" . 0"

,

• D = " 0" ! " "

D ,

! ' D " " " /

" " 0" ' 0" . ,

" ! . " " 0" "

" =

• " ! " " !

,

• . " " ' "

,

#?

(30)

&' *$ ()

• 0" " ' ' 0" ! . 0"

F " 0"

> ! " 0" " @ G,

Tipos de pruebas y automatización

Qué automatizar

< . " !

" , ! ! " 0" "

" ,

0" " . " !

' " , & ! R Q J%(K "

! 0" " " 0" " =

• & " = D .

" ,

• & " = - D

0" W " / ,

• & " " = - D

,

• & " " = " F " G

" " " ,

• & " D = "

,

• & " = " !

" ! ! " ! ,

7 Q 0" / 0" " "

" " ! 0" ' . " ,

! ! ! " ! "

" , 7 3 " " " .

! 0" " " "

. D9 " , ! " "

D ! . " ,

Q' ' " ! " " " !

! " ! ! 0"

" ." " " '

" = ! " " 0" 0" " ,

Formas de automatización

<. ! 0" " . ,

" ! 0" " "

, 9 " 0" " . "

, " ! . "

=

• Q " " ! " " " " ."

(31)

&' *% ()

7 " / " " 3 ! 0"

0" -,) / " " ,

7 " 0" " =

• " F " J%(KG

• " " . " F 3

% J%(KG

@ . . . " / " , !

" . ' " 0" !

" / " " ,

" ,

7 . D9 " " 0" "

/ -,) ,

D ! 0" " " " ! "

0" " " " ,

& . " , & ! / -,) "

" . 0" !

/ " , 2 / " " /

. " " ,

Herramientas de TDD más allá de xUnit

Herramientas que hacen énfasis en la legibilidad

9 " " " " 0"

! 0" F - ! 0" G 0" 0"

" " . ,

2 " " 0" " ! " '

,

& ! ! 9 O9 *! 0" " D

" " 0" "

, 1 0" / " "

0" ! ' ' ! 0" !

0" " ,

" @9 ! " !

. , O9 ( " ! "

O 4,

& ! " O9 *=

public class PruebaCuentaBancaria extends TestCase {

// la clase debe derivar de TestCase

...

// el método debe empezar con la palabra “test”: public void testDepositoDebeIncrementarSaldo ( ) {

int montoDepositado = 100;

CuentaBancaria cuenta = crearCuentaValida(); int saldoPrevio = cuenta.getSaldo();

(32)

&' *# ()

assertEquals("El depósito funcionó mal",

saldoPrevio + montoDepositado, cuenta.getSaldo() ); }

... }

" O9 ( =

public class PruebaCuentaBancaria {

...

@Test

public void depositoDebeIncrementarSaldo ( ) { int montoDepositado = 100;

CuentaBancaria cuenta = crearCuentaValida(); int saldoPrevio = cuenta.getSaldo();

cuenta.depositar(montoDepositado);

assertEquals("El depósito funcionó mal",

saldoPrevio + montoDepositado, cuenta.getSaldo() ); }

... }

! " . "

' D #:, ! ' B ! .

O9 ( Q 8 #,

! " ! " " D ! 0" "

,

& ! " O9 =

assertEquals (x, y);

" D B =

assertThat (x, equalTo (y) );

< ! " " 3 " ! . ' 0"

B 0" ' 0" "

' ! ! 0" " " ! 0" " "

" ! 0" " 3 " ! 0"

" 0" ! 3 " !

,

& B 0" " , & !

" O9 " 0" " " =

assertTrue( universidades.contains("UNLP") ||

universidades.contains("Universidad Nacional de La Plata") );

#:C " L . M! " L .M! 0" L. " M,

(33)

&' ** ()

& B 0" ' =

assertThat(universidades, or( contains("UNLP"),

contains("Universidad Nacional de La Plata") ));

" " " , & !

0" " ! 0" " " 3

" ! " =

assertThat(Math.sqrt(-1), is(notANumber()));

O9 " ! B " . "

) . -. ,

< D B ! . . " ,

Herramientas para crear dobles

' ! ! 0"

! " 8 0"

,

B . " . 8 ! ,

0" 3 . " 0"

" , 7 ! . 0" 0"

8 ' 0" "

0" , 7 0" '

' ! " "

Q 8! ! ' " O =

private void initiallyLoads(Object value) { checking(new Expectations() {{

oneOf (clock).time(); will(returnValue(loadTime)); oneOf (loader).load(KEY); will(returnValue(value)); }});

}

private void cacheHasNotExpired() { checking(new Expectations() {{

oneOf (clock).time(); will(returnValue(fetchTime));

allowing (reloadPolicy).shouldReload(loadTime, fetchTime); will(returnValue(false));

}}); }

&" 0" 0" ! , 7

0" " O " 0"/ . !

,

Herramientas que ponen el énfasis en BDD y STDD

B " . . 0" " "

0" , " .

(34)

&' *( ()

7 " ! J%(K! . 0" " " ,

! 0" 0" . 0" 0" "

0" ! 0" . 0" " =

! ! " ,

Herramientas para pruebas de interacción

B " . . " / " " ,

D . % J%(K, 7 " '

" ! D . / , & / 3 ! " "

" 0" " " ,

& " " ! . . D = . " . 0" "

, 2 " " 8! /

" ,

" . " " "

" , < ! "

= 0" " " ,

0" ! " ! " 0" 0" " ! 0"

3 ,

<. ! " " " . !

. " , & 0" H 8 J:K 8

" . < ,

Algunas herramientas específicas

" 0" . 0" . " !

" ' , ! " " " ' ,

Herramienta Tipo de

TDD Estrategia de prueba Formato pruebas Se accede a través de Observaciones

Fit ATDD y

STDD

Scripted Test

Tablas API, con ayuda de código de vinculación desarrollad o por programad or

Desarrollado por Ward Cunningham. Bueno para resultados calculables, los flujos se pueden construir con la API FitLibrary, aunque complica una herramienta sencilla.

FitNesse ATDD y

STDD Scripted Test Tablas en wiki API con ayuda de código de vinculación desarrollad o por programad or

(35)

&' *4 ()

Herramienta Tipo de

TDD Estrategia de prueba Formato pruebas Se accede a través de Observaciones

JBehave BDD y

STDD Scripted Test Texto con plantilla de user story

API Primera herramienta de BDD para Java. Es una extensión de JUnit. Corre bien en conjunto con IDEs. Muy amigable para desarrolladores. No requiere código para vincular

especificaciones con pruebas. Menos amigable para perfiles no técnicos.

RSpec BDD y

STDD Scripted Test Texto con plantilla de user story

API Primera herramienta de BDD para Ruby, muy similar en pros y contras a JBehave

Concordion BDD y

STDD Scripted Test Texto libre en HTML API, mediante código de vinculación entre pruebas y especificaci ón

Es una extensión de JUnit. Corre bien en conjunto con IDEs. Muy amigable para desarrolladores. Relativamente amigable para perfiles no técnicos. Hay versiones para .NET, Ruby y Python.

TextTest ATDD y

STDD Scripted Test Texto en una interfaz gráfica

GUI o API Especial para probar workflows y regresiones. Para cualquier lenguaje.

easyb BDD Scripted

Test

Texto con plantilla de user story

API Basado en Groovy

Cucumber BDD Scripted

Test

Texto con plantilla de user story

API Basado en Ruby y RSpec, tiene una extensión para Java llamada Cuke4Duke

Selenium Interacción Recorded

Test Editable en varios lenguajes de programaci ón Interfaz web

Para aplicaciones web

CubicTest Interacción Recorded

Test Editable en formato gráfico Interfaz web Usa Selenium

StoryTestIQ Interacción Recorded

Test Editable en formato wiki Interfaz web Usa Selenium

HttpUnit Interacción Scripted

Test

Texto Interfaz web

TDD y enfoques metodológicos

" 0" 0" ;&! D ,

! . " ! " " . " 0" .

. / " ,

9 " " " - 0"

-, & " " ! " ' ! " " "

' ! 0" , &

! 0" / !

-" " . !

(36)

&' *) ()

<. ! T "' 0" U 7 0" . " . ,

! ,

J%4K . 0" / L - " . M,

! " " ! " ,

" 0" 0" " . 3 , @

" ! " " ,

0" > ! " 0" / = 0"/! " 0"

, @ ! D . " " " J:K,

@ J%?K ! . < 9 ! "

" 0" " " , /

" " " J%?K,

7 " 0" 0" / 0" " 0"

! " ' " / ' ! 0" " "

0" - " ! ,

9 " - " 0" Q J%(K

, 0 ! " . " " 0"

, 7 D - 0" Q " 0" #

J%(K ' ' > ! " >

0" 0" " " "

, & " 0" "

-J%6K,

7 < J#)! #6 #?K ' I ! " 0"

' " , 7

0" " , < " ! " " "

I ! 0" ! " 0"

! " " , I

0" " " " '

" 0" ! 0"

,

I " " " !

" ! 0" " 9 !

. . ' "

-" -" ,

" " " " ,

0" D 0" ' ! >

" " ! " @ & J%?K

" 9 ' , " "

0" "/ ! " " , & " " ! " 0" ' !

0" . " ,

Q J%(K " 0" $ 0" . "

! . " " 0" " !

" " ,

Q" . . . . " " " ,

(37)

&' *6 ()

" " " , & "

' ! " " ,

" " " !

! " " ,

! D " = ! > F "

9 @ " - G! '

W ! " " " ,

" / " " 0" . 0"

D ,

Estudios del uso de TDD en la práctica

Validez de los estudios sobre UTDD

. . ! " " / "

9 , & ! D " . " 9

" , ! ! 0" ' ' H

> 8! #$$# J#K! 0" . " !

" " ,

7 ! , " ! 0" " 0" .

. . , & !

0" ! " !

' 3 ' ! " " 0" " ' ,

& " " ! 0"

" , B "

0" D " " !

" " D W

" " , & !

" ! " ! ! "

,

" " ! . " 0" . ! !

" 3 =

! " . " " ,

9 0" ! " "

" , " . . ,

! " D 0" " '

0" " , 2 0"

0" ' " " ,

1 0" "

! " ' " ' ! D

" , . . ! " " "

" D 0" . "

" , & . 0" . ! ! 0"/

" " " 0" . "

" ,

& ! " 0" " 0"

" ! ! " , @ !

" . ! " , < !

(38)

&' *? ()

D L 0" - M! 0" '

D , & . . . !

' ,

Trabajos que fueron analizados

7 ' 0" . . =

• " " " J#:K! 0" D " "

" 0" " (? 0" D

' ,

• 9 " ( " " ! >Q Q !

" " ' ' , 9 0"

' J*$K,

• 9 D " - !

0" " " " !

' 4 - D

O ! 0" " J*%K,

• D " O Q J**K,

• 9 0" ! " " "

;& ! " 0"

-" ' . 0" " J*(K,

• 2 . " #$ 0" . " ! 0"

,

Conclusiones extraídas de la evidencia analizada

7 " " " =

• " D ! /

" " 0" " " 0"

! . " ($N :$N,

/ . " " 0" ! ' "

%?N 3 J*$K,

• " ! . " ! %4N

*4N! " 0" " " "

" = ' D 0" '

" ! ! 0" 0" " " ,

B 0" ! !

" ! " ' , 2 "

0" " ! 0"

- , & " " ! ' ,

• " 0" . 0" " !

! / " " ,

" 0" . ! ! 0" "

/ - ! " - ! "

" ! . - = "/

,

• " " "

" ! "

(39)

&' *: ()

• " "

,

• " ! J*(K . - !

. " " - " ,

B / " 0" ,

=

• 0" " . . "

0" . " ,

• 7 " !

"

' " " ' " ,

• " " . ! ." ! ! .

! " ' ,

• 7 " 0" "

0" " , " " !

" 0" . ,

• . ! "

. " " !

" 0"

0" ' , A" ' . . 0"

" " 0" . !

" " , 7 D

! "

J*)K 0" F " G ($

' 0" ,

< ! . " 0" ! . !

" , & =

• E " " ! .

" " ! 0" ,

' " " 0" /

" " ! 0"

, " ! ! "

,

• 7 D ! " 0"

" " 0" ! . "

" 0" ! " 0"

! " " 0" '

,

• @ . " .

" ,

• " . D ! '

! " - !

0" " ' ,

Estudios sobre variantes de TDD más allá de UTDD

. D 9 ! .

(40)

&' ($ ()

" 0" . " & 8 Q " J*6K! 0"

0" . " F #$$:G . 3 "

' " , 0"/

" ! (: " ,

7 ' =

• E ! " " 0" "

" ! " 0" / . " 0" 0"

" " , 7 0" " 0"

" " ,

• E ! ' ! "

/ 0" !

" ! 0"

,

• " " ! 0" "

" ! . . / 0" " "

! " ,

• " " ! . "

" 0" , ! 0"

. "

0" ,

• Q" . " . "

" ! 0" . 0" 0" ,

• " 3 . " ! "

" ! . " !

. " ,

• ,

" . 0" " " " !

! " " ! ,

• Q" . " . - ! " "

0" " ' !

,

Limitaciones de TDD y prácticas afines

" 0" ' ! " , & ! "

" " " 0" " " =

• & " " ! 0"

. " " , 7 0" " 0" ! . "

" ! .

0" , "

" ' " " ! " "

,

• & - " " " ! " " . . .

. . " ! ' , & " " ! !

" 0" " 0" ' ,

• & , / "

! " " . " " .

(41)

&' (% ()

" , D . " "

,

• & " " , <" " " " 0" "

" " ! . " !

!

" & 3 ! ! ,! 0"

0" "

,

B " ,

"

-F> 9 *$! H > 8 J%KG! "

! 0" " - ! " 0" , <

D " " ,

D " . ' . 9 0" ! ' 0"

' ' " , " " ! "

= . ,

" 9 " " " "

' ! " " . . 0" " " 0"

" %$$N " , " 0" 9

. , A" ' 'D H > 8 J%K!

L 0" 0" " 0" " M, ! " /

0" " " FL M L MG! " " ,

" " ' " ,

7 " 0" " " " " D

0" " " , 7 0" . 0" . 0" ! " 0" " ' ! "

." ! " " , 1 !

0" " " " ! /

' ,

Prácticas relacionadas con TDD

Refactoring

E " / . " ;& 0"

"/ ! " ,

! ! " / - ,

9 - "/ "

" ! 0" " . . "

" - ,

7 " " 0" " / " " 1 8 O .

J*?K,

7 =

• " " " . 0" "

D ! " - 0" " 0" " .

" " " 3 0" " ,

*$

(42)

&' (# ()

• 7 " D D " " '

! 0" 0" D

" 0" ,

7 ' ! . ! , <

!

" - ,

< ' " ! " " , &

! " 0" " "

-! " / 0" - ,

! 0"

" = 0" . " F

" G! 0" / . ,

<. ! " . - !

. " , T 0" " " '

- U 2 ! T0"/ 0"

" " U

>" ! " ! " , "

" ! 0" ! " ' ' "

0" ! ' ' " "

-" ,

! 0" ! 0" "

! 0" " > ! < , 7 " '

" 0" , 7

" ! " "

-! 0" , 2 3 " !

" " ! ,

' ', " !

/ " ! " " , & ! T "'

" " U " ! "

" , ! " ' 0"

" " " ! 0" D !

" " " ! ,

Debugging

" " / 0" " "

, !

" " " ,

7 " = '

" D " " 0" . ,

. . ! " ! 3 "

" " " " D ,

& D 'D 0" ! " " !

" " 0" ! / ,

! 0" " " " D !

(43)

&' (* ()

! = 0"

" ,

3 " 0" .

= " ! " ' " ! "

" ." , < ! " 0"

" 0" ! " 0" ." ! " ,

Integración continua

7 " " ' " > 8 ;& J%K " " "

J*:K, " ! " "

! ! " " "

! " 3 ! , D

" . . ! ! ' ! 0"

' ,

7 " " =

. " " ,

Conclusiones

" & J%?K! 0" L " / 0"

" ! - " 3 . M! 0" "

,

7 0" ! " 3 & J%?K! =

• 0" ,

• < . ' !

,

• @ " " 0" . ,

• @ " " ,

• D ' " ,

• @ "' ! "

,

<. ! . " . , 9 ' - !

. 0" " " " 0" ,

> - ! ' . 0"

/ , @ " 0" ,

7 0" " 0" . = " ! 0"

! D ! 0" " " , 9 @ "

! 0" > " D ,

! ! D " / 0" " D

, 7 . " ! 0" D

" . " 3 , < ! 9 ! .

" " !

0" !

. " " ,

9 " " ' " " 0" "

0" " *%=

*%

(44)

&' (( ()

Tipo de

prueba Técnica de TDD relacionada Pregunta que responde Observaciones

Aceptación STDD, ATDD, BDD

¿Funciona el sistema de acuerdo a los requerimientos?

No debe pecar por defecto ni por exceso respecto de los requerimientos

Integración NDD ¿Cada parte del sistema interactúa correctamente con las demás partes?

Tiene que ver con el bajo acoplamiento y las interfaces entre módulos

Unitarias UTDD ¿Las clases hacen lo que deben hacer y es conveniente trabajar con ellas?

(45)

&' (4 ()

Bibliografía y referencias

J%K H > 8! L D & D = . M! < I

& ! %:::,

J#K H > 8! L = > D M! < I & ! #$$#,

J*K @ .! LI. X M! . =VV , ., V . V!

" #$%%,

J(K @ .! L " > M! . =VV , ., V " V!

" #$%%,

J4K @ .! L " > M! > ! #$$)! J(K,

J)K ! L = 8 D . B M!

< I & ! #$$*,

J6K < R ! L > E . UM! . =VV . , V#$$6V$?V#?V

. V! " #$%%,

J?K > Q ! L U U YM!

. =VV , , V V " V#$$(V ,. ! " #$%%,

J:K E 8 Q" I " . ! L = 8

M! & B ! #$$4,

J%$K 7 H 8 ! L = < O M! Q

&" ! #$$6,

J%%K F3 " G! L& 1 M!

. =VV , , V V " V 8 V& 1 ! " #$%%,

J%#K 8 &, > 8 O ,! L . Q . Q Q .= !

< F# GM! < I & ! %::4,

J%*K R 8 < ! L> . " R , D

M! @ " ! #$$:,

J%(K R Q ! LD9 & M! < I & ! #$$6,

/ . =VVD" , V " #$%%,

J%4K Q ! LQ 8 < X " M!

. =VV , V V 8 < " ,. ! " #$%%,

J%)K ! Q 8 ! @ & ! O I ! LQ 8 E ! @ 1 M!

11& 7< #$$(! C " ! ',

J%6K 8 < " ! Q 8 ! O . " ! L O# & ! = > & ! & B ! #$$*,

J%?K ! @ & ! LR 1 1 ! R" M!

< I & ! #$%$,

J%:K , R " ! R Q, I ! L D E 0" = A" >

M! B " ! %:?:,

J#$K > Q 8! L> " 1 M!. =VV , D , V V V 8

" , ! " #$%%,

J#%K > Q 8! L D . " . D M! . =VV , D , V

V#$$*V$?V#%V! " #$%%,

J##K ! @ & ! Q 8 ! O I ! LQ 8 E ! 1 M!

11& 7< #$$(! / . =VV , 8, V #$$), "

#$%%,

J#*K ! @ & ! L 7 " O M!

11& 7< #$$)! / . =VV , 8, V #$$), "

(46)

&' () ()

J#(K E 8 Q" ! LQ < & E 0" .

M! #4! )? 64 F#$$?G,

J#4K R Q ! E . > . ! O < ! L< E 9 E

Z & 8M! 11& 7< #$$*,

J#)K O" >" ! R" E ! E 7" ! O" ' R ! L .

@ E 0" . > I < .M!

& . . %% . < !

C ! 7@ ! #$%$,

J#6K E 7" ! R ! R" E ! L " C

& E 0" I < M! & . % I 8 . .

I E 0" FI E #$%$G,

J#?K E 7" ! O" >" ! O" ' R ! R" E ! L< D "

. < I < M! & .

< QV *# F #$%$G,

J#:K < " ! " 8! 8" &" 88 ! L 7 "

< M! !

C C ! > ! R ! /

. =VV , , ., V D, . U . [ " Z [#*)6 " #$%%,

J*$K @ . @ ! Q . Q D ! . " . >. ! 7 " I !

LE A" . " . = E " D

" " M! O " ! C " %*! @" *! O" !

#$$?! #?: *$#! \ >" Q ! 77 #$$?! /

. =VV ., , V " V " V V 5 , " #$%%,

J*%K R ! < ! / D R ! Q & ! < C !

L " < = D .

& M! $) & . #$$) < QV "

,

J*#K . ! L " F > . GM!

. =VV , , V < , D " #$%%,

J**K & 88 < . ! < B . ! O". O]] ! L >" <

. " . . " = < " Q

M! & & ! #$$4! C "

%?$V#$$4! ##6 #(*! 1 = %$,%$$6V$ *?6 #44:$ 65%(! / . =VV ,

, V " V V < <R 7 #,65 %,$, " #$%%,

J*(K 7 S. ! ." "8 <8 " ! H " H ! " . Q 8 ! L >

I & M! D

& < & ! 6 . ! ;&

#$$)! 1" "! ! " #$$),

J*4K . ! L & M! . S ! #$$%,

J*)K I B" . ! LQ . & M! < I ! %:?:,

J*6K . & 8! 8 Q " ! L< 7 " E M!

" ! 9 ! 7 " @ >"

& ! #$%$! C " (?! & #! #$? #%*! 1 = %$,%$$6V:6? * )(# %*$4( $5#$!

C ! /

. =VV , ," , V" V&" V& 8Q " ;&#$%$, " #$%%,

J*?K I , 1 8 ! E . , O . ! LE = < < <

8 1 1 M! & . " 1

1 & . & < F 11&&<G! %::$!

< Q,

J*:K Q ! L " " M!

Figure

Tablas API, con

Tablas API,

con p.34

Referencias

Actualización...

Related subjects :