Introducción a las pruebas con JUnit .

Anuncio
Pruebas
Una introducción práctica.
Javier Gutiérrez ([email protected])
¿Probar sirve de algo?
Ariane 5.
Lanzado por primera vez el 4 de junio de
1996.
Ariane 5.
36.7 segundos después explotó.
Motivo:
Fallo software. La programación no se había probado lo suficiente.
1
¿… y qué es una prueba?.
Verificación dinámica del
comportamiento del
software a partir de un
conjunto finito de casos de
prueba.
¿… y esto qué significa?.
Para probar un programa
tenemos que ejecutarlo.
Verificación dinámica del
comportamiento del
software a partir de un
conjunto finito de casos de
prueba.
La prueba tiene un límite.
No vale ejecutar el
programa de cualquier
manera.
2
¿… y qué es un caso de prueba?.
Valores de entrada.
Probar es ejecutar un
programa con unos cuantos
casos de prueba.
Acciones.
Resultado esperado.
Ejemplos de casos de prueba
¿Funciona el teléfono?.
Valores de
prueba
123123-4545-6767-89
Acciones
1. Descolgar auricular.
2. Marcar número de Pepote.
Pepote.
3. Esperar contestación.
contestación.
Resultado esperado
(Pepote):
”.
Pepote): “Digameee
“Digameee”.
¿Me está bien esta camisa?
Valores de
prueba
Mi cuerpo.
cuerpo.
Acciones
1. Ponerme la camisa.
camisa.
2. Abrochármela.
Abrochármela.
3. Moverme un poco.
poco.
4. Mirarme al espejo.
espejo.
Cuidado con la etiqueta o con
arrugarla por si hay que devolverla
Resultado esperado
Elegancia y confort.
confort.
3
Un ejemplo
¿Qué casos de prueba podemos escribir?.
public int suma(int a, int b)
{
Valores de
prueba
Acciones
Resultado
esperado
???
Suma(a,
Suma(a, b)
???
return a + b;
}
Los casos de prueba son
finitos (y cuantos menos,
mejor).
Un ejemplo
¿Qué casos de prueba podemos escribir?.
public int suma(int a, int b)
{
Valores de
prueba
Acciones
Resultado
esperado
0, 0
Suma(a,
Suma(a, b)
0
0, b = no 0
Suma(a,
Suma(a, b)
b
return a + b;
}
3, 4
Suma(a,
Suma(a, b)
7
-2, -8
Suma(a,
Suma(a, b)
-10
-3, 6
Suma(a,
Suma(a, b)
Integer.MAX_
VALUE,
VALUE, 6
Suma(a,
Suma(a, b)
3
-2147483643
Y algunas permutaciones más.
4
¿Por qué he elegido esos casos de
prueba?.
5 valores = 25 casos de prueba.
Otro ejemplo I.
public static void Intercambia(List l1, List l2) {
Object b1=null;
Object aux=null;
Collections.sort(l1);
Collections.sort(l2);
ListIterator i1=l1.listIterator();
while (i1.hasNext())
{
b1=i1.next();
int pos=Collections.binarySearch(l2,b1);
if (pos<0) {
1
if (i1.hasNext()){
aux=i1.next();
if (b1.equals(aux)) {
2
i1.remove();
l2.add(b1);
Collections.sort(l2);
}
}
}
}
}
Quita un elemento de la
lista l1 y lo pone en la
lista l2 si:
1. No está en l2.
2. Está repetido en l1.
Entrada:
l1 = {3, 4, 1, 2, 3, 1 }
l2 = {3, 4, 2, 6, 4 }
Salida:
l1 = {1, 2, 3, 3 4}
l2 = {1, 2, 3, 4, 4, 6}
Veamos algunos casos
De prueba.
5
Otro ejemplo II.
Valores de prueba
Acciones
Resultado esperado
l1 = null o l2 = null
Intercambia(l1, l2)
Falla !!!
(Null PointerException)
l1 = {} y l2 = *
…
L2 ordenada
l1 = {1, 2, 3} y l2 = {4, 5, 6}
…
l1 = {1, 2, 3} y l2 = {4, 5, 6}
l1 = {1, 3, 2, 3} y l2 = {4, 5, 6}
…
l1 = {1, 2, 3} y l2 = {3, 4, 5, 6}
l1 = {1, 3, 2, 3, 1, 2}
l2 = {1, 2, 3, 4, 5, 6}
…
l1 = {1, 1, 2, 2, 3, 3}
l2 = {1, 2, 3, 4, 5, 6}
* Significa una lista con cualesquiera valores.
¿Estos casos de prueba (y sus permutaciones)
garantizan que el método funciona bien en
cualquier circunstancia?
Otro ejemplo III.
Valores de prueba
Acciones
Resultado esperado
l1 = {1, 2, 2, 3} y l2 = {4, 5, 6}
Intercambia(l1, l2)
Falla !!!
l1 = {1, 2, 2, 3} y l2 = {4, 5, 6}
l1 = {1, 1, 2, 3, 3} y l2 = {4, 5, 6}
…
Falla !!!
l1 = {1, 2, 3, 3} y l2 = {1, 4, 5, 6}
l1 = Un valor repetido 3 veces
l2 = *
…
Falla !!!
El valor aparece repetido en l1.
* Significa una lista con cualesquiera valores.
6
En conclusión
Probar es ejecutar casos de prueba.
Caso de prueba:
entrada + acciones + salida
salida obtenida == salida esperada
salida obtenida != salida esperada
¿Un programa que pasa todos sus casos
de prueba es un programa sin errores?.
JUnit I.
http://junit.org
Open Source framework for the
automation of unit tests under Java.
Existen muchas versiones para distintos
lenguajes.
Su API es nuestro mapa de carreteras.
7
JUnit II.
IDEs:
„
„
„
„
„
„
„
JDeveloper
Eclipse
Forte / Netbeans
Intelli J
JBuilder
TogetherJ
VisualAge
JUnit III. Nuestra primera prueba
Vamos a probar nuestra función suma
import junit.framework.*;
Los imports no se nos pueden
olvidar.
public class TestSuma extends TestCase {
Cada clase guarda un conjunto
de pruebas relacionadas.
// Atributos
// Pruebas
public void testSumaPositivos() {
int r = Suma.Suma(3, 4);
assertEquals(“Suma de 3 y 4 no es 7",
r, 7 );
}
}
Las clases deben heredar de
TestCase.
Los atributos serán la
información a compartir por las
distintas pruebas.
Cada método que empieze por
“void test…” es una prueba.
Los métodos assertX() permiten
evaluar si la prueba se pasa o
no.
8
JUnit IV. Más cosas.
Inicio y fin de la
prueba.
prueba.
protected void setuUp(){
// Me conecto a una BBDD
}
protected void tearDown(){
//Me desconecto de la BBDD
}
void assertEquals()
Métodos assertX()
assertX()
void assertNull()
void assertNotNull()
Void assertTrue()
JUnit V. Nuestra segunda prueba.
T.A.D. Lista (Lista.java)
// Devuelve el número de elementos de la lista
public int size();
// Vacía la lista.
public void clear();
// Vacía la lista.
public void clear();
// Añade el elemento x en la posición i.
Escribir un conjunto de
pruebas (JUnit) para el
TAD lista.
public void add(int i, Object x):
// Devuelve el elemento en la posición i.
public Object get(int i);
9
JUnit V. Nuestra segunda prueba.
Prueba Lista (TestLista.java)
protected void setUp() {
listaVacia = new Lista();
listaLlena = new Lista();
elems = new Object[4];
listaLlena.add(0, elems[0] = new Integer(1));
listaLlena.add(1, elems[1] = new Integer(2));
listaLlena.add(2, elems[2] = new Integer(3));
elems[3] = new Integer(4);
}
En primer lugar el setUp().
Este setUp() se ejecuta siempre
antes de un nuevo método test*.
2 conjuntos de pruebas: sobre
una lista con elementos y sobre
una lista vacía.
JUnit V. Nuestra segunda prueba.
1
T.A.D. Lista (Lista.java)
public void testIsEmpty() {
assertTrue(listaVacia.isEmpty());
assertTrue(!listaLlena.isEmpty());
}
// Devuelve el número de elementos de lapublic
lista.
void testClear() {
public int size();
listaVacia.clear();
assertTrue(listaVacia.isEmpty());
listaLlena.clear();
assertTrue(listaLlena.isEmpty());
2
// Vacía la lista.
public void clear();
}
// Devuelve true si la lista está vacía.
public void testGetLlena() {
public boolean isEmpty();
assertEquals(listaLlena.get(0),elems[0]);
assertEquals(listaLlena.get(1),elems[1]);
// Añade el elemento x en la posición
i.
assertEquals(listaLlena.get(2),elems[2]);
public void add(int i, Object x): try {
listaLlena.get(3);
// Devuelve el elemento en la posición
i.
} catch (IndexOutOfBoundsException e) {
public Object get(int i);
return;
}
fail("Error. listaLLena no lanzó "+
“excepción indice fuera de límites");
}
3
10
JUnit V. Nuestra segunda prueba.
public void testAddLlena() {
listaLlena.add(3, elems[3]);
assertEquals(listaLlena.get(3), elems[3]);
// Devuelve el número de elementoslistaLlena.add(0,
de la lista. elems[3]);
assertEquals(listaLlena.get(0), elems[3]);
public int size();
}
T.A.D. Lista (Lista.java)
4
// Vacía la lista.
public void clear();
public void testSize() {
assertEquals(listaVacia.size(),
assertEquals(listaLlena.size(),
listaLlena.add(3, elems[0]);
public boolean isEmpty();
assertEquals(listaLlena.size(),
// Añade el elemento x en la posición i.
listaLlena.add(4, elems[0]);
public void add(int i, Object x):
assertEquals(listaLlena.size(),
}
// Devuelve true si la lista está5 vacía.
0);
3);
4);
5);
// Devuelve el elemento en la posición i.
public Object get(int i);
JUnit VI. Ejecución de pruebas.
junit.textui.TestRunner
junit.swingui.TestRunner
11
Un seguro de vida
Probar mientras se codifica.
Siempre que modifiquemos algo hemos de
escribir una nueva prueba que lo verifique y,
además, las pruebas antiguas deben
funcionar.
Además, mejora el diseño.
Una taxonomía de casos de
prueba.
12
Descargar