Está en la página 1de 37

Ingenieria de Software II

Gestión de Pruebas
Pruebas  de  aceptación  
Pruebas  unitarias:  JUnit  

Ing. de Sistemas - Lic. Ivan Fernandez Daza


Índice  
•  Pruebas:  ¿qué  es  probar?  
•  Cómo  hacer  pruebas  con  JUnit  
•  Enfoque  de  las  pruebas  
–  caja  negra  |  caja  blanca  
–  cobertura  
•  Algunas Palabras    

  2  
Pruebas  

fallos  
desarrollo  
informales  

falla  
pruebas   ¿dónde  falla  qué?  
pasa  

pruebas  de  
aceptación   falla  
pasa  

  3  
Obje:vo  
•  El  obje6vo  único  de  las  pruebas  es  
encontrar  errores  en  el  código  
–  antes  de  que  aparezcan  en  ejecución  
•  Una  batería  de  pruebas  es  tanto  mejor  
cuantos  menos  errores  pasan  desapercibidos  

  4  
Probar  es  provocar  

  5  
Aforismos  
•  Probar  es  buscar  fallos  
•  Cuantos  más  fallos  se  encuentran  en  una  unidad,  
más  fallos  6ene  
⇒ cuando  se  iden6fica  un  “bicho  malo”    
hay  que  machacarlo  
•  El  que  desarrolla  está  incapacitado  para  probar:  
deben  ser  equipos  de  trabajo  enfrentados  
•  Es  bueno  “diseñar  para  probar”  
•  Las  pruebas  también  pueden  tener  fallos  

  6  
Enfoque  psicológico  
•  El  que  desarrolla  
–  quiere  comprobar  que  el  programa  funciona  
–  con  todo  lo  que  se  le  ocurre  que  debe  ir  
•  El  que  prueba  
–  intenta  que  el  programa  falle  
–  con  todo  lo  que  se  le  ocurre  que  puede  fallar  

  7  
Caso  de  prueba  
•  Debe  definir  
–  un  obje6vo:  ¿qué  error  buscamos?   /**  javadoc  
–  unos  datos  de  prueba  
–  unos  resultados  esperados   java  
–  un  procedimiento  de  ejecución  
–  un  criterio  para  saber  si  
•  la  prueba  PASA  
•  la  prueba  FALLA   JUnit  

•  la  prueba  no  es  CONCLUYENTE  

  8  
Plan  de  pruebas  
•  batería  de  casos  
–  definir  grupos  de  pruebas  (macro-­‐obje6vos)  
–  definir  casos  de  pruebas  (micro-­‐obje6vos)  

  9  
Índice  
•  Pruebas:  ¿qué  es  probar?  
•  Cómo  hacer  pruebas  con  JUnit  
•  Enfoque  de  las  pruebas  
–  caja  negra  |  caja  blanca  
–  cobertura  
•  Algunas Palabras  

  10  
JUnit  
•  Paquete  ampliamente  u6lizado  
para  automa6zar  pruebas  de  código  Java  
–  h9p://www.junit.org/  
•  h9p://downloads.sourceforge.net/junit/junit-­‐4.5.jar  
–  empotrado  en  BlueJ,  DrJava,  ...  
–  si  su  IDE  no  lo  con6ene  
1.  descargar  de  www.junit.org  
2.  ejecutar  con  main  
•  Un  grupo  de  pruebas  es  una  clase  java  
•  Una  prueba  es  un  método  java  

  11  
ficheros  de  pruebas  

import  junit.framework.TestCase;  

public  class  Test_NOMBRE_DEL_GRUPO  


               extends  TestCase  {  

       public  void  test_NOMBRE_DE_LA_PRUEBA_1  ()  {  


               //  planteamiento  del  escenario  
               assertEquals(valor_esperado,  valor_obtenido);  
       }  

       public  void  test_NOMBRE_DE_LA_PRUEBA_n  ()  {  


               //  planteamiento  del  escenario  
               assertEquals(valor_esperado,  valor_obtenido);  
       }  
}  

  12  
Reglas  
•  extendsTestCase  
•  Métodos  de  prueba  
–  public  void  testXXX()  [throws  …]  
–  1  o  más  aserciones  por  método  
–  se  ejecutarán  en  algún  orden,  no  obligatorio  
•  Aserciones:  colección  muy  amplia  (ver  apuntes)  
–  assertEquals(T  esperado,  T  resultado)  
–  assertNull(Object  resultado)  
–  assertNotNull(Object  resultado)  
–  assertTrue(boolean  resultado);  
–  assertFalse(boolean  resultado);  
–  ...    
–  h9p://junit.org/apidocs/junit/framework/Assert.html  

  16  
Varios  assert  por  test  
•  Pruebas  encadenadas  
–  si  una  prueba  falla,  no  se  ejecutan  las  siguientes  
•  Pruebas  individuales  
–  fallos  singularizados  

•  Si  pasan  todos  los  tests  


–  es  indiferente  
•  Si  falla  alguno  
–  las  pruebas  encadenadas  no  avanzan  

  18  
Excepciones  
•  El  código  puede  lanzar  excepciones  
falla  si  ...  
–  lanza  excepciones  no  previstas  
–  no  lanza  excepciones  previstas  

•  Se  programa  de  forma  que  da  fallo  


si  el  programa  ejecuta  la  sentencia  
–  fail(“mensaje  explica6vo”)  

  19  
Índice  
•  Pruebas:  ¿qué  es  probar?  
•  Cómo  hacer  pruebas  con  JUnit  
•  Enfoque  de  las  pruebas  
–  caja  negra  |  caja  blanca  
–  cobertura  
•  Algunas Palabras  

  23  
Enfoques  
•  De  caja  negra  
–  cuando  conocemos  lo  que  6ene  que  hacer  el  código  
ejercitamos  todo  lo  que  6ene  que  hacer  
–  pruebas  funcionales  
•  De  caja  blanca  
–  cuando  conocemos  el  código  fuente  
forzamos  la  ejecución  de  todo  el  código  
–  pruebas  estructurales  

  24  
caja  negra  
Casos  de  prueba  
•  ¿Qué  hay  que  probar?  
–  todo  lo  que  dice  la  especificación:  
•  manual  
•  instrucciones  
•  otra  documentación  
•  Cobertura  del  100%  
–  si  va  tachando  lo  que  se  va  probando,  
100%  es  cuando  todo  está  tachado  
•  funcionamiento  correcto  
•  detección  y  reporte  de  errores  

  25  
caja  negra  
Datos  de  prueba  
•  ¿Con  qué  datos  se  prueba?  
1.  divida  el  espacio  de  datos  en  clases  de  equivalencia  
•  clase  de  equivalencia:  
datos  que  provocan  el  “mismo  comportamiento”  
•  no  parece  que  deban  provocar  comportamientos  diferentes  
2.  elija  un  dato  “normal”  de  clase  de  equivalencia  
3.  pruebe  con  todos  los  datos  “frontera”:  
valores  extremos  de  la  clase  de  equivalencia  

  26  
caja  negra  
Datos  de  prueba  
•  Añada  aquellos  casos  en  los  que  sospeche  que  el  
programador  puede  haberse  equivocado  
•  Pruebe  todas  las  combinaciones  
{  datos  ×  comportamiento  }  

  27  
caja  blanca  
Casos  de  prueba  
•  ¿Qué  hay  que  probar?  
–  ejecutar  al  menos  una  vez  cada  sentencia  
•  cobertura  de  sentencias  
–  ejecutar  al  menos  una  vez  cada  condición  
con  resultado  cierto  y  falso  
•  cobertura  de  ramas  
•  Método  
–  si  va  tachando  el  código  probado  
100%  es  cuando  todo  esté  tachado  

  28  
caja  blanca  
Casos  de  prueba  
•  if  (...)  
–  si  T,  si  F  
•  switch  (...)  
–  cada  ‘case’  +  ‘default’  
•  cobertura  de  bucles  
–  for  -­‐>  3  pruebas:  0  veces,  1  vez,  n>1  veces  
–  repeat  -­‐>  2  pruebas:  1  vez,  n>1  veces  
–  while  -­‐>  3  pruebas:  0  veces,  1  vez,  n>1  veces  

  29  
Medidas:  cobertura  
•  ¿Cuántas  pruebas  hay  que  hacer?  
–  no  se  puede  probar  con  todos  los  datos  posibles  
–  la  cobertura    
mide  cuánta  variedad  de  casos  hemos  cubierto  
•  En  caja  negra  
–  casos  probados  /  clases  posibles  
•  En  caja  blanca  
–  líneas  probadas  /  líneas  de  código  
–  condiciones  probadas  /  opciones  en  el  código  
–  bucles  probados  /  bucles  presentes  

  30  
Índice  
•  Pruebas:  ¿qué  es  probar?  
•  Cómo  hacer  pruebas  con  JUnit  
•  Enfoque  de  las  pruebas  
–  caja  negra  |  caja  blanca  
–  cobertura  
•  Algunas Palabras  

  31  
Palabras  finales  (1..)  
–  Probar  es  buscarle  los  fallos  a  un  programa  
–  Probar  requiere  pensar  mal  del  programa  
y  provoca  tensiones  humanas  
el  que  prueba  es  como  un  cliente  quisquilloso  
que  no  hace  sino  buscar  razones  
para  no  pagar  

–  Probar  es  muy  costoso  en  6empo  y  esfuerzo  


–  Probar  es  tedioso  
–  Probar  es  un  arte  

  32  
Palabras  finales  (..2)  
•  Hacer  una  buena  batería  de  pruebas  
–  cuesta  6empo  y  trabajo  
–  ayuda  a  entender  el  problema  
–  permite  saber  cuándo  hemos  acabado  
–  permite  repasar  todas  las  pruebas  en  el  futuro  

•  la  experiencia  demuestra  que  


–  a  la  larga  se  ahorra  6empo  
–  se  reducen  los  errores  en  el  producto  final  

  33  
Ejemplo de Pruebas Unitarias

Repasando........

• Un programa es aceptable cuando:


– Hace lo que se acordó que debía hacer en las especificaciones.
– No hace lo que no debe hacer.
• “Un programador jamás debería entregar un programa sin
haberlo probado. Igualmente, quien recibe un programa de
otro jamás debería aceptarlo sin haberlo probado.
• Para aprobar una práctica ésta debe pasar las pruebas
funcionales.
• Cualquier funcionalidad de un programa sin una prueba
automatizada, simplemente no existe” (Extreme Programming
Explained”, de Kent Beck)

JUNIT. Prueba 2

1
Pruebas Unitarias Sistemáticas : Conceptos
• Prueba unitaria: una prueba individual de un método o clase.
• Prueba unitaria ad-hoc: por ejemplo, cuando creamos un objeto de
cierta clase con BlueJ e invocamos manualmente un método del mismo
con distintas entradas para ver si funciona.
• Sin embargo, con este tipo de pruebas no se puede trabajar eficiente y
sistemáticamente.
• Cada vez que cambiamos algo en el método o clase tendríamos que
volver a pasar todas las pruebas para asegurarnos de que “nada se ha
descabalado”. Es decir, realizar pruebas de regresión.
• Para ello, vendría muy bien algo que nos permitiera definir
sistemáticamente una serie de pruebas y ejecutarlas
automáticamente, tantas veces como necesitáramos.
• JUNIT nos permite hacer esto. JUNIT + BlueJ todavía mejor.

Pruebas Unitarias Sistemáticas : Procedimiento


• Antes de implementar una determinada funcionalidad, piensa cómo
deberías probarla para verificar que se comporta correctamente. Esto
permite desarrollar la funcionalidad teniendo las ideas muy claras de lo
que debería hacer.
• Escribe el código que implementa la funcionalidad deseada.
• Escribe el código de las pruebas inmediatamente después.
• Ejecuta las pruebas que hiciste.
• Corrige la unidad de código que implementa la funcionalidad deseada
hasta que pase todas y cada una de las pruebas.
• Al añadir una nueva funcionalidad, repite el ciclo: piensa en cómo
probarla, codifica la funcionalidad, codifica las pruebas, ejecuta todas las
pruebas que hiciste (nuevas y viejas). No sigas hasta que el código pase
absolutamente todas las pruebas.
• Así una y otra vez para cada nueva funcionalidad que implementes. Lo
vemos con un ejemplo.

JUNIT. Pruebas Unitarias 4

2
Ejemplo Procedimiento Prueba con JUNIT (1)
• Desarrollar un método estático que tome un array de enteros como
argumento y devuelva el mayor valor encontrado en el array.

public class MayorNumero {


/**
* Devuelve el elemento de mayor valor de una lista
* @param list Un array de enteros
* @return El entero de mayor valor de la lista
*/
public static int obt_mayorNumero(int lista[]) {
return 0; // para que compile hasta que desarrollemos el método
}
}

JUNIT. Pruebas Unitarias 5

Ejemplo Procedimiento Prueba con JUNIT (2)


• ¿Qué pruebas se te ocurren para el método obt_mayorNumero?
– ¿Qué ocurre para un array con valores cualesquiera (el caso
normal)?
[3, 7, 9, 8] → 9
– ¿Qué ocurre si el mayor elemento se encuentra al principio, en
medio o al final del array?
[9, 7, 8] → 9; [7, 9, 8] → 9; [7, 8, 9] → 9
– ¿Y si el mayor elemento se encuentra duplicado en el array?
[9, 7, 9, 8] → 9
– ¿Y si sólo hay un elemento en el array?
[7] → 7
– ¿Y si el array está compuesto por elementos negativos?
[-4, -6, -7, -22] → -4

JUNIT. Pruebas Unitarias 6

3
Ejemplo Procedimiento Prueba con JUNIT (3)
• Escribimos el código del método obt_mayorNumero:
/**
* Devuelve el elemento de mayor valor de una lista
*
* @param list Un array de enteros
* @return El entero de mayor valor de la lista
*/
public static int obt_mayorNumero(int lista[]) {
int indice, max = Integer.MAX_VALUE;
for (indice = 0; indice < lista.length-1; indice++) {
if (lista[indice] > max) {
max = lista[indice];
}
}
return max;
}

JUNIT. Pruebas Unitarias 7

Ejemplo Procedimiento Prueba con JUNIT (4)


• Escribimos el código de las pruebas (1):
import junit.framework.*;
public class TestMayorNumero extends TestCase {
public TestMayorNumero() {
}
public void testSimple() {
assertEquals(9, MayorNumero.obt_mayorNumero(new int[] {3, 7, 9, 8}));
}
public void testOrden() {
assertEquals(9, MayorNumero.obt_mayorNumero(new int[] {9, 7, 8}));
assertEquals(9, MayorNumero.obt_mayorNumero(new int[] {7, 9, 8}));
assertEquals(9, MayorNumero.obt_mayorNumero(new int[] {7, 8, 9}));
}

// Sigue en la próxima transparencia

JUNIT. Pruebas Unitarias 8

4
Ejemplo Procedimiento Prueba con JUNIT (5)
• Escribimos el código de las pruebas (2):
// Sigue de la transparencia anterior

public void testDuplicados() {


assertEquals(9, MayorNumero.obt_mayorNumero(new int[] {9, 7, 9, 8}));
}
public void testSoloUno() {
assertEquals(7, MayorNumero.obt_mayorNumero(new int[] {7}));
}
public void testTodosNegativos() {
assertEquals(-4, MayorNumero.obt_mayorNumero(new int[] {-4, -6, -7, 22}));
}

} // Fin de la clase

JUNIT. Pruebas Unitarias 9

Ejemplo Procedimiento Prueba con JUNIT (6)


• Ejecutamos las pruebas:

JUNIT. Pruebas Unitarias 10

5
Ejemplo Procedimiento Prueba con JUNIT (7)
• Ejecutamos las pruebas:

JUNIT. Pruebas Unitarias 11

Ejemplo Procedimiento Prueba con JUNIT (8)


• ¿Qué está mal?: PREGUNTAR A ALUMNOS
/**
* Devuelve el elemento de mayor valor de una lista
*
* @param list Un array de enteros
* @return El entero de mayor valor de la lista
*/
public static int obt_mayorNumero(int lista[]) {
int indice, max = Integer.MAX_VALUE;
for (indice = 0; indice < lista.length-1; indice++) {
if (lista[indice] > max) {
max = lista[indice];
}
}
return max;
}

JUNIT. Pruebas Unitarias 12

6
Ejemplo Procedimiento Prueba con JUNIT (9)
• ¿Qué está mal?:
/**
* Devuelve el elemento de mayor valor de una lista
* Integer.MIN_VALUE
* @param list Un array de enteros
* @return El entero de mayor valor de la lista
*/
public static int obt_mayorNumero(int lista[]) {
int indice, max = Integer.MAX_VALUE;
for (indice = 0; indice < lista.length-1; indice++) {
if (lista[indice] > max) {
max = lista[indice];
}
}
return max;
}

JUNIT. Pruebas Unitarias 13

Ejemplo Procedimiento Prueba con JUNIT (10)


• Volvemos a ejecutar las pruebas (hasta que pasen todas):

JUNIT. Pruebas Unitarias 14

7
Ejemplo Procedimiento Prueba con JUNIT (11)
• ¿Qué está mal?:
Falla en este “assert”, devuelve el 8 y no el 9
public void testOrden() {
assertEquals(9, MayorNumero.obt_mayorNumero(new int[] {9, 7, 8}));
assertEquals(9, MayorNumero.obt_mayorNumero(new int[] {7, 9, 8}));
assertEquals(9, MayorNumero.obt_mayorNumero(new int[] {7, 8, 9}));
}

public static int obt_mayorNumero(int lista[]) {


int indice, max = Integer.MAX_VALUE;
for (indice = 0; indice < lista.length-1; indice++) {
if (lista[indice] > max) {
max = lista[indice];
} PREGUNTAR A ALUMNOS
} ejemplo de que siempre hay
return max; que analizar los extremos
}

JUNIT. Pruebas Unitarias 15

Ejemplo Procedimiento Prueba con JUNIT (12)


• ¿Qué está mal?:
Falla en este “assert”, devuelve el 8 y no el 9
public void testOrden() {
assertEquals(9, MayorNumero.obt_mayorNumero(new int[] {9, 7, 8}));
assertEquals(9, MayorNumero.obt_mayorNumero(new int[] {7, 9, 8}));
assertEquals(9, MayorNumero.obt_mayorNumero(new int[] {7, 8, 9}));
}
lista.length

public static int obt_mayorNumero(int lista[]) {


int indice, max = Integer.MAX_VALUE;
for (indice = 0; indice < lista.length-1; indice++) {
if (lista[indice] > max) {
max = lista[indice];
}
}
return max;
}

JUNIT. Pruebas Unitarias 16

8
Ejemplo Procedimiento Prueba con JUNIT (13)
• Otra vez a ejecutar las pruebas (ahora ya pasan todas, podemos seguir):

JUNIT. Pruebas Unitarias 17

Ventajas de Probar Progresivamente


• Este método puede parecer extremo (casi es Extreme Programming),
pero normalmente ahorra tiempo y esfuerzo:

Si pruebas mientras desarrollas Si desarrollas todo y al final pruebas

• Lo mejor es un término medio: cada funcionalidad significativa que


desarrolles pruébala antes de seguir.

JUNIT. Pruebas Unitarias 18

9
Pruebas con JUNIT: Explicación Formal (1)
Marco para desarrollar pruebas unitarias (1)
línea 1 import junit.framework.*;
-
línea 3 public class Pruebas extends TestCase {
- // variables_privadas
-
- public Pruebas ( ) {
- // inicialización
- }
-
línea 10 public void testXXX ( ) {
- // código para verificar que el método a probar funciona correctamente
- }
-
- public static void main (String[ ] args) {
línea 15 junit.textui.TestRunner.run(Pruebas.class); // ejecución consola texto
- // junit.swingui.TestRunner.run(Pruebas.class); // ejecución ventana
- }
- } // fin de clase

JUNIT. Pruebas Unitarias 19

Pruebas con JUNIT: Explicación Formal (2)


Marco para desarrollar pruebas unitarias (2):
a) (línea 1). Importar las clases de JUNIT necesarias.
b) (línea 3). Toda clase que contenga pruebas ha de heredar de la clase
“TestCase”. Ésta contiene la mayoría de funcionalidad necesaria para
realizar pruebas, incluyendo los “assert”.
c) (línea 10). Todo método que empiece por “test” en la clase será
ejecutado automáticamente por JUNIT. Así han de empezar todos
los métodos con casos de prueba.

Otros detalles:
a) Cada método que sólo trate un caso o aspecto a probar.
b) (línea 15). Si no usas BlueJ puedes ejecutar las pruebas por consola.

JUNIT. Pruebas Unitarias 20

10
Herramientas para Pruebas
• PHPUnit • JWebUnit • Cactus
• JUnitPerf • JFCUnit • JXUnit
• HttpUnit • Jester • JUnit

Su uso depende en su mayoria del lenguaje de programación sobre el


cual se trabaja.

JUNIT. Pruebas Unitarias 27

14

También podría gustarte