Pruebas unitarias
      JUnit
Pruebas unitarias

Conceptos básicos
    Es una forma de probar el correcto funcionamiento
   de un módulo de código.
    Sirve para asegurar que cada uno de los módulos
   funcione correctamente por separado.
    Con las Pruebas de Integración, se podrá
   asegurar el correcto funcionamiento del sistema o
   subsistema en cuestión.
    Escribir casos de prueba para cada método en el
   módulo → cada caso sea independiente del resto.
Pruebas unitarias

Requisitos
    Automatizable: no debería requerirse una
   intervención manual. Esto es especialmente útil para
   integración continua.
    Completas: deben cubrir la mayor cantidad de
   código.
    Repetibles o Reutilizables: no se deben crear
   pruebas que sólo puedan ser ejecutadas una sola
   vez. También es útil para integración continua.
Pruebas unitarias

Requisitos
    Independientes: la ejecución de una prueba no
   debe afectar a la ejecución de otra.
    Profesionales: las pruebas deben ser
   consideradas igual que el código, con la misma
   profesionalidad, documentación, etc.
Pruebas unitarias

Objetivos
    Aislar cada parte del programa.
    Mostrar que las partes individuales son correctas.
    Proporcionan un contrato escrito, que el trozo de
   código debe satisfacer.
    Controlar el impacto de los cambios. Las pruebas
   unitarias aseguran funcionamiento de código tras
   cambios del mismo.
Pruebas unitarias

Ventajas
    Fomentan el cambio: Facilitan al programador
   cambios de código para mejorar su estructura
   (refactorización) → Asegura que los nuevos cambios
   no han introducido errores.
    Simplifica la integración: Llegar a fase de
   integración con seguridad de que el código está OK
   → Se facilitan las pruebas de integración.
    Documenta el código: Las propias pruebas son
   documentación del código → ahí se puede ver cómo
   utilizarlo.
Pruebas unitarias

Ventajas
    Separación de la interfaz y la implementación:
   La lógica se prueba a través de los casos de prueba
   y no con interfaz → objetos mock (mock object) para
   simular el comportamiento de objetos complejos.
    Los errores están más acotados y son más
   fáciles de localizar: Tenemos pruebas unitarias que
   pueden desenmascararlos.
Pruebas unitarias

Limitaciones
    Las pruebas unitarias no descubrirán todos los
   errores del código.
    Por definición, sólo prueban las unidades por sí
   solas → no descubrirán:
       • errores de integración
       • problemas de rendimiento
       • otros problemas que afectan a todo el sistema
       en su conjunto
    Puede no ser trivial anticipar todos los casos
   especiales de entradas.
JUnit
JUnit

Conceptos básicos
    Framework para pruebas unitarias.
    Conjunto de librerías creadas por Erich Gamma y
   Kent Beck que son utilizadas en programación para
   hacer pruebas unitarias de aplicaciones Java
    El framework incluye formas de ver los resultados
   (runners) que pueden ser en modo texto, gráfico
   (AWT o Swing) o como tarea en Ant.
    Plug-ins para principales IDEs como Eclipse y
   NetBeans.
JUnit

Conceptos básicos
    Open Source, disponible en http://www.junit.org
    Los casos de prueba son realmente programas
   Java. Quedan archivados y pueden (DEBEN) ser re-
   ejecutados tantas veces como sea necesario.
JUnit

      Ejemplo sencillo
package dominio;
import java.util.Vector;
                                               ← Representa una lista
                                                 ordenable de forma
public class Lista extends Vector {              creciente.
  public Lista() { ... }
                                               Se ordena llamando al
    public Lista(String[] elementos) {...}
                                                 método público
    public Lista ordenar() {...}                 ordenar(), que llama
                                                 a su vez a ordenar(0,
    protected void ordenar(int iz, int de) {
       ...                                       size()-1)
    }
}
JUnit

Ejemplo sencillo
             •Un posible caso de prueba es
             el siguiente:
             String[] e3={"e", "d", "c", "b", "a"};
             Lista reves=new Lista(e3);
             Lista derecha=reves.ordenar();



             ...y el resultado esperado:

                     "a", "b", "c", "d", "e"
JUnit

Ejemplo sencillo
  String[] e3={"e", "d", "c", "b", "a"};
  Lista reves=new Lista(e3);
  Lista derecha=reves.ordenar();

    Si derecha es igual al resultado esperado, entonces
   el caso de prueba ha sido superado
    {"a", "b", "c", "d", "e"}
JUnit

Ejemplo sencillo
    Construcción manual de un objeto expected y
   comparación con el obtenido:
       String[] e3={"e", "d", "c", "b", "a"};
       Lista reves=new Lista(e3);
       Lista derecha=reves.ordenar();
       Lista expected={"a", "b", "c", "d", "e"};
       if (derecha.equals(expected))
         ResultadoCorrecto();
       else
         ResultadoIncorrecto();
JUnit

Ejemplo sencillo
    El ejemplo anterior (obtained frente a expected) es
   una idea fundamental de JUnit
   ¿ Qué nos ofrece JUnit?
       • JUnit permite mantener de forma separada los
       casos de prueba
       • Permite ejecutarlos (y re-ejecutarlos) de forma
       automática
       • Nos permite construir "árboles de casos de
       prueba" (suites)
JUnit

Ejemplo sencillo
    El ejemplo anterior con JUnit:
  public void testOrdenarReves() {
     String[] ex={"a", "b", "c", "d", "e"};
     Lista expected=new Lista(ex);

      String[] e3={"e", "d", "c", "b", "a"};
      listaAlReves=new Lista(e3);



      this.assertEquals(expected, listaAlReves.ordenar());
  }
JUnit

Ejemplo sencillo
    ¿Dónde está el código anterior? En la clase
   ListaTester, creada para realizar las pruebas de Lista.
    ListaTester extiende de TestCase definida en Junit.
    En TestCase está definido el método assertEquals
   antes mencionado, y muchos otros más.
JUnit

Ejemplo sencillo
  public class ListaTester1 extends TestCase
  {
    public ListaTester1(String sTestName)
    {
      super(sTestName);
    }

      public void testOrdenarReves() {
       String[] ex={"a", "b", "c", "d", "e"};
       Lista expected=new Lista(ex);

      String[] e3={"e", "d", "c", "b", "a"};
      Lista listaAlReves=new Lista(e3);

          this.assertEquals(expected, listaAlReves.ordenar());
      }

  }
JUnit

El TestRunner
                 public class ListaTester1 extends TestCase
                 {
                   public ListaTester1(String sTestName)
                   {
                     super(sTestName);
                   }

                     public void testOrdenarReves() {
                      String[] ex={"a", "b", "c", "d", "e"};
                      Lista expected=new Lista(ex);

                         String[] e3={"e", "d", "c", "b", "a"};
                         Lista listaAlReves=new Lista(e3);

                         this.assertEquals(expected,
                               listaAlReves.ordenar());
                     }

                 }
JUnit

       El TestRunner
public void testOrdenarReves() {              public void testOrdenarNula1() {
   String[] ex={"a", "b", "c", "d", "e"};        Lista listaNula1=null;
   Lista expected=new Lista(ex);                 this.assertNull(listaNula1);
                                               }
     String[] e3={"e", "d", "c", "b", "a"};
     Lista listaAlReves=new Lista(e3);         public void testOrdenarNula2() {
                                                 String[] e4=null;
     this.assertEquals(expected,                 Lista listaNula2=new Lista(e4);
     listaAlReves.ordenar());                    String[] ex=null;
 }                                               Lista expected=new Lista(ex);
                                                 this.assertEquals(expected,
 public void testOrdenarTodosIguales() {         listaNula2.ordenar());
   String[] e2={"a", "a", "a", "a", "a"};      }
   Lista listaTodosIguales=new Lista(e2);
                                               public void testOrdenarListaVacia() {
     String[] ex={"a", "a", "a", "a", "a"};      String[] e5={};
                                                 Lista listaVacia=new Lista(e5);
     Lista expected=new Lista(ex);
     this.assertEquals(expected,                 String[] ex={};
     listaTodosIguales.ordenar());               Lista expected=new Lista(ex);
 }                                               this.assertEquals(expected,
                                                 listaVacia.ordenar());
                                               }
JUnit

El TestRunner – Errors vs Failures
JUnit

El TestRunner – Test OK
JUnit

TestRunner - Consideraciones
    Es importante notar que todos los métodos test
   que implementados se están en ListaTester.
    Si añadimos, borramos o modificamos el código de
   Lista, los casos de prueba habidos en ListaTester
   siguen disponibles y pueden volver a ser ejecutados.
    Se aconseja/OBLIGA re-ejecutarlos cada vez que
   se modifique el código.
JUnit

Pruebas de Excepciones (fail)
     Es necesario comprobar el comportamiento en
    situaciones idóneas, pero se deben probar
    situaciones en las que se producen errores.
     A veces el comportamiento correcto de nuestro
    programa consisten en se produzca un error → una
    excepción.
JUnit

 Pruebas de Excepciones (fail)
       Por ejemplo, puede ser deseable que ordenar()
      lance un error cuando la lista esté vacía:
public Lista ordenar() throws Exception {
     if (size()==0)
       throw new Exception("No se puede ordenar una lista vacía");
     ordenar(0, size()-1);
     return this;
   }
JUnit

Pruebas de Excepciones (fail)
                      public void testOrdenarNula2()
                                        throws Exception {
                          String[] ex=null;
                          Lista expected=new Lista(ex);
                          this.assertEquals(expected,
                                   listaNula2.ordenar());
                      }


                      public void testOrdenarListaVacia()
                                          throws Exception {
                           String[] ex={};
                           Lista expected=new Lista(ex);
                           this.assertEquals(expected,
                                       listaVacia.ordenar());
                      }
JUnit

Pruebas de Excepciones (fail)
     Se modificarán los métodos test de la siguiente
    manera:
 public void testOrdenarNula2() throws Exception {
     try
     {
       String[] ex=null;
       Lista expected=new Lista(ex);
       this.assertEquals(expected, listaNula2.ordenar());
       fail("Debería haberse lanzado una excepción");
     }
     catch (Exception e)
     {
       // Capturamos la excepción para que el caso no falle
     }
   }
JUnit

Redefinición de método equals
    Todas las clases Java extienden de Object y por lo
   tanto heredan:                    Llamado por los
                                     assertEquals(...)
                                     definidos en Assert
JUnit

Redefinición de método equals
    Por tanto, en muchos casos habrá que redefinir el
   método equals(Object):boolean en la clase que se
   quiera probar.
JUnit

Ejemplo - equals




                   ¿Cuándo son dos cuentas son iguales?
                   a) Los saldos son los mismos
                   b) Tienen el mismo nº de
                      movimientos
                   c) Opción b y todos son iguales
                   d) ...
JUnit

     Ejemplo - equals
public void testIngresarYRetirarloTodo() throws Exception
 {
   Cuenta expected=new Cuenta("Pepe", "123");

    Cuenta obtained=new Cuenta("Macario", "123456");
    obtained.ingresar(1000.0);
    obtained.retirar(1000.0);

    assertEquals(expected, obtained);
}
JUnit

     Ejemplo - equals
                               Si redefinimos equals(Object): boolean
public void  testIngresarYRetirarloTodo() throws Exception modo...
                                       en Cuenta de ese
 {
   Cuenta expected=new Cuenta("Pepe", "123");

     Cuenta obtained=new Cuenta("Macario", "123456");
     obtained.ingresar(1000.0);
     obtained.retirar(1000.0);

     assertEquals(expected, obtained);
 }




public boolean equals(Object o){
  if (!Cuenta.class.isInstance(o))
      return false;
  Cuenta c=(Cuenta) o;
  return getSaldo()==c.getSaldo());
}
JUnit

Otros métodos assert
    assertTrue(boolean)
    public void testIngresar()
      {
        Cuenta obtained=new Cuenta("Pepe", "123");
        obtained.ingresar(100.0); obtained.ingresar(200.0);
        obtained.ingresar(300.0);
        assertTrue(obtained.getSaldo()==600.0);
      }

    assertNull(Object)
      public void testNull()
        {
          Cuenta c=null;
          assertNull(c);
        }
JUnit

Otros métodos assert
       assertSame(Object, Object)/assertNotSame(Object,
      Object)
public void testDiferentesReferencias() throws Exception
  {
    Cuenta cuenta1=new Cuenta("Macario", "123456");
    cuenta1.ingresar(1000.0);
    cuenta1.retirar(1000.0);

     Cuenta cuenta2=new Cuenta("Macario", "123456");
     cuenta2.ingresar(1000.0);
     cuenta2.retirar(1000.0);

     assertEquals(cuenta1, cuenta2);
     assertNotSame(cuenta1, cuenta2);
 }
JUnit

Mock Objects
    Basados en JUnit.
    Sustituyen a clases complejas, dispositivos, etc.
    Ejemplos: servlets, páginas jsp, bases de datos...
JUnit

    Mock Objects - Ejemplo
public class temperature extends HttpServlet
{
  private static final String CONTENT_TYPE = "text/html";

    public void init(ServletConfig config) throws ServletException {
      super.init(config);
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException
    {
       response.setContentType(CONTENT_TYPE);
       PrintWriter out = response.getWriter();
       String str_f=request.getParameter("Fahrenheit");

        try {
          int temp_f=Integer.parseInt(str_f);
          double temp_c=(temp_f-32)*5/9.0;
          out.println("Fahrenheit: " + temp_f + ", Celsius: " + temp_c);
        }
        catch (NumberFormatException e) {
          out.println("Invalid temperature: " + str_f);
        }
    }
}
JUnit

Mock Objects - Ejemplo
import   com.mockobjects.servlet.*;
import   junit.framework.Test;
import   junit.framework.TestCase;
import   junit.framework.TestSuite;

public class TemperatureTester extends TestCase
{
  public TemperatureTester()
  {
  }

 public void test_bad_parameter() throws Exception {
    temperature s = new temperature();
    MockHttpServletRequest request=new MockHttpServletRequest();
    MockHttpServletResponse response=new MockHttpServletResponse();
    request.setupAddParameter("Fahrenheit", "boo!");
    response.setExpectedContentType("text/html");
    s.doGet(request, response);
    response.verify();
    assertTrue(response.getOutputStreamContents().startsWith("Invalid
   temperature"));
 }
JUnit

Mock Objects
    Difíciles de usar (poca documentación)
    Descargas y más información en
   www.mockobjects.com
JUnit

Conclusiones
    Marco de automatización de pruebas.
    Automatiza las pruebas de regresión.
    Los casos de prueba documentan el propio código
   fuente.
    Adecuado para Desarrollo dirigido por las pruebas.
    Extensible (p.ej.: Mock), abierto, gratuito :)
Pruebas Unitarias - JUnit


          FIN
                              Iker Canarias
                  iker.canarias@gmail.com

Introducción a JUnit

  • 1.
  • 2.
    Pruebas unitarias Conceptos básicos  Es una forma de probar el correcto funcionamiento de un módulo de código.  Sirve para asegurar que cada uno de los módulos funcione correctamente por separado.  Con las Pruebas de Integración, se podrá asegurar el correcto funcionamiento del sistema o subsistema en cuestión.  Escribir casos de prueba para cada método en el módulo → cada caso sea independiente del resto.
  • 3.
    Pruebas unitarias Requisitos  Automatizable: no debería requerirse una intervención manual. Esto es especialmente útil para integración continua.  Completas: deben cubrir la mayor cantidad de código.  Repetibles o Reutilizables: no se deben crear pruebas que sólo puedan ser ejecutadas una sola vez. También es útil para integración continua.
  • 4.
    Pruebas unitarias Requisitos  Independientes: la ejecución de una prueba no debe afectar a la ejecución de otra.  Profesionales: las pruebas deben ser consideradas igual que el código, con la misma profesionalidad, documentación, etc.
  • 5.
    Pruebas unitarias Objetivos  Aislar cada parte del programa.  Mostrar que las partes individuales son correctas.  Proporcionan un contrato escrito, que el trozo de código debe satisfacer.  Controlar el impacto de los cambios. Las pruebas unitarias aseguran funcionamiento de código tras cambios del mismo.
  • 6.
    Pruebas unitarias Ventajas  Fomentan el cambio: Facilitan al programador cambios de código para mejorar su estructura (refactorización) → Asegura que los nuevos cambios no han introducido errores.  Simplifica la integración: Llegar a fase de integración con seguridad de que el código está OK → Se facilitan las pruebas de integración.  Documenta el código: Las propias pruebas son documentación del código → ahí se puede ver cómo utilizarlo.
  • 7.
    Pruebas unitarias Ventajas  Separación de la interfaz y la implementación: La lógica se prueba a través de los casos de prueba y no con interfaz → objetos mock (mock object) para simular el comportamiento de objetos complejos.  Los errores están más acotados y son más fáciles de localizar: Tenemos pruebas unitarias que pueden desenmascararlos.
  • 8.
    Pruebas unitarias Limitaciones  Las pruebas unitarias no descubrirán todos los errores del código.  Por definición, sólo prueban las unidades por sí solas → no descubrirán: • errores de integración • problemas de rendimiento • otros problemas que afectan a todo el sistema en su conjunto  Puede no ser trivial anticipar todos los casos especiales de entradas.
  • 9.
  • 10.
    JUnit Conceptos básicos  Framework para pruebas unitarias.  Conjunto de librerías creadas por Erich Gamma y Kent Beck que son utilizadas en programación para hacer pruebas unitarias de aplicaciones Java  El framework incluye formas de ver los resultados (runners) que pueden ser en modo texto, gráfico (AWT o Swing) o como tarea en Ant.  Plug-ins para principales IDEs como Eclipse y NetBeans.
  • 11.
    JUnit Conceptos básicos  Open Source, disponible en http://www.junit.org  Los casos de prueba son realmente programas Java. Quedan archivados y pueden (DEBEN) ser re- ejecutados tantas veces como sea necesario.
  • 12.
    JUnit Ejemplo sencillo package dominio; import java.util.Vector; ← Representa una lista ordenable de forma public class Lista extends Vector { creciente. public Lista() { ... } Se ordena llamando al public Lista(String[] elementos) {...} método público public Lista ordenar() {...} ordenar(), que llama a su vez a ordenar(0, protected void ordenar(int iz, int de) { ... size()-1) } }
  • 13.
    JUnit Ejemplo sencillo •Un posible caso de prueba es el siguiente: String[] e3={"e", "d", "c", "b", "a"}; Lista reves=new Lista(e3); Lista derecha=reves.ordenar(); ...y el resultado esperado: "a", "b", "c", "d", "e"
  • 14.
    JUnit Ejemplo sencillo String[] e3={"e", "d", "c", "b", "a"}; Lista reves=new Lista(e3); Lista derecha=reves.ordenar();  Si derecha es igual al resultado esperado, entonces el caso de prueba ha sido superado {"a", "b", "c", "d", "e"}
  • 15.
    JUnit Ejemplo sencillo  Construcción manual de un objeto expected y comparación con el obtenido: String[] e3={"e", "d", "c", "b", "a"}; Lista reves=new Lista(e3); Lista derecha=reves.ordenar(); Lista expected={"a", "b", "c", "d", "e"}; if (derecha.equals(expected)) ResultadoCorrecto(); else ResultadoIncorrecto();
  • 16.
    JUnit Ejemplo sencillo  El ejemplo anterior (obtained frente a expected) es una idea fundamental de JUnit ¿ Qué nos ofrece JUnit? • JUnit permite mantener de forma separada los casos de prueba • Permite ejecutarlos (y re-ejecutarlos) de forma automática • Nos permite construir "árboles de casos de prueba" (suites)
  • 17.
    JUnit Ejemplo sencillo  El ejemplo anterior con JUnit: public void testOrdenarReves() { String[] ex={"a", "b", "c", "d", "e"}; Lista expected=new Lista(ex); String[] e3={"e", "d", "c", "b", "a"}; listaAlReves=new Lista(e3); this.assertEquals(expected, listaAlReves.ordenar()); }
  • 18.
    JUnit Ejemplo sencillo  ¿Dónde está el código anterior? En la clase ListaTester, creada para realizar las pruebas de Lista.  ListaTester extiende de TestCase definida en Junit.  En TestCase está definido el método assertEquals antes mencionado, y muchos otros más.
  • 19.
    JUnit Ejemplo sencillo public class ListaTester1 extends TestCase { public ListaTester1(String sTestName) { super(sTestName); } public void testOrdenarReves() { String[] ex={"a", "b", "c", "d", "e"}; Lista expected=new Lista(ex); String[] e3={"e", "d", "c", "b", "a"}; Lista listaAlReves=new Lista(e3); this.assertEquals(expected, listaAlReves.ordenar()); } }
  • 20.
    JUnit El TestRunner public class ListaTester1 extends TestCase { public ListaTester1(String sTestName) { super(sTestName); } public void testOrdenarReves() { String[] ex={"a", "b", "c", "d", "e"}; Lista expected=new Lista(ex); String[] e3={"e", "d", "c", "b", "a"}; Lista listaAlReves=new Lista(e3); this.assertEquals(expected, listaAlReves.ordenar()); } }
  • 21.
    JUnit El TestRunner public void testOrdenarReves() { public void testOrdenarNula1() { String[] ex={"a", "b", "c", "d", "e"}; Lista listaNula1=null; Lista expected=new Lista(ex); this.assertNull(listaNula1); } String[] e3={"e", "d", "c", "b", "a"}; Lista listaAlReves=new Lista(e3); public void testOrdenarNula2() { String[] e4=null; this.assertEquals(expected, Lista listaNula2=new Lista(e4); listaAlReves.ordenar()); String[] ex=null; } Lista expected=new Lista(ex); this.assertEquals(expected, public void testOrdenarTodosIguales() { listaNula2.ordenar()); String[] e2={"a", "a", "a", "a", "a"}; } Lista listaTodosIguales=new Lista(e2); public void testOrdenarListaVacia() { String[] ex={"a", "a", "a", "a", "a"}; String[] e5={}; Lista listaVacia=new Lista(e5); Lista expected=new Lista(ex); this.assertEquals(expected, String[] ex={}; listaTodosIguales.ordenar()); Lista expected=new Lista(ex); } this.assertEquals(expected, listaVacia.ordenar()); }
  • 22.
    JUnit El TestRunner –Errors vs Failures
  • 23.
  • 24.
    JUnit TestRunner - Consideraciones  Es importante notar que todos los métodos test que implementados se están en ListaTester.  Si añadimos, borramos o modificamos el código de Lista, los casos de prueba habidos en ListaTester siguen disponibles y pueden volver a ser ejecutados.  Se aconseja/OBLIGA re-ejecutarlos cada vez que se modifique el código.
  • 25.
    JUnit Pruebas de Excepciones(fail)  Es necesario comprobar el comportamiento en situaciones idóneas, pero se deben probar situaciones en las que se producen errores.  A veces el comportamiento correcto de nuestro programa consisten en se produzca un error → una excepción.
  • 26.
    JUnit Pruebas deExcepciones (fail)  Por ejemplo, puede ser deseable que ordenar() lance un error cuando la lista esté vacía: public Lista ordenar() throws Exception { if (size()==0) throw new Exception("No se puede ordenar una lista vacía"); ordenar(0, size()-1); return this; }
  • 27.
    JUnit Pruebas de Excepciones(fail) public void testOrdenarNula2() throws Exception { String[] ex=null; Lista expected=new Lista(ex); this.assertEquals(expected, listaNula2.ordenar()); } public void testOrdenarListaVacia() throws Exception { String[] ex={}; Lista expected=new Lista(ex); this.assertEquals(expected, listaVacia.ordenar()); }
  • 28.
    JUnit Pruebas de Excepciones(fail)  Se modificarán los métodos test de la siguiente manera: public void testOrdenarNula2() throws Exception { try { String[] ex=null; Lista expected=new Lista(ex); this.assertEquals(expected, listaNula2.ordenar()); fail("Debería haberse lanzado una excepción"); } catch (Exception e) { // Capturamos la excepción para que el caso no falle } }
  • 29.
    JUnit Redefinición de métodoequals  Todas las clases Java extienden de Object y por lo tanto heredan: Llamado por los assertEquals(...) definidos en Assert
  • 30.
    JUnit Redefinición de métodoequals  Por tanto, en muchos casos habrá que redefinir el método equals(Object):boolean en la clase que se quiera probar.
  • 31.
    JUnit Ejemplo - equals ¿Cuándo son dos cuentas son iguales? a) Los saldos son los mismos b) Tienen el mismo nº de movimientos c) Opción b y todos son iguales d) ...
  • 32.
    JUnit Ejemplo - equals public void testIngresarYRetirarloTodo() throws Exception { Cuenta expected=new Cuenta("Pepe", "123"); Cuenta obtained=new Cuenta("Macario", "123456"); obtained.ingresar(1000.0); obtained.retirar(1000.0); assertEquals(expected, obtained); }
  • 33.
    JUnit Ejemplo - equals Si redefinimos equals(Object): boolean public void testIngresarYRetirarloTodo() throws Exception modo... en Cuenta de ese { Cuenta expected=new Cuenta("Pepe", "123"); Cuenta obtained=new Cuenta("Macario", "123456"); obtained.ingresar(1000.0); obtained.retirar(1000.0); assertEquals(expected, obtained); } public boolean equals(Object o){ if (!Cuenta.class.isInstance(o)) return false; Cuenta c=(Cuenta) o; return getSaldo()==c.getSaldo()); }
  • 34.
    JUnit Otros métodos assert  assertTrue(boolean) public void testIngresar() { Cuenta obtained=new Cuenta("Pepe", "123"); obtained.ingresar(100.0); obtained.ingresar(200.0); obtained.ingresar(300.0); assertTrue(obtained.getSaldo()==600.0); }  assertNull(Object) public void testNull() { Cuenta c=null; assertNull(c); }
  • 35.
    JUnit Otros métodos assert  assertSame(Object, Object)/assertNotSame(Object, Object) public void testDiferentesReferencias() throws Exception { Cuenta cuenta1=new Cuenta("Macario", "123456"); cuenta1.ingresar(1000.0); cuenta1.retirar(1000.0); Cuenta cuenta2=new Cuenta("Macario", "123456"); cuenta2.ingresar(1000.0); cuenta2.retirar(1000.0); assertEquals(cuenta1, cuenta2); assertNotSame(cuenta1, cuenta2); }
  • 36.
    JUnit Mock Objects  Basados en JUnit.  Sustituyen a clases complejas, dispositivos, etc.  Ejemplos: servlets, páginas jsp, bases de datos...
  • 37.
    JUnit Mock Objects - Ejemplo public class temperature extends HttpServlet { private static final String CONTENT_TYPE = "text/html"; public void init(ServletConfig config) throws ServletException { super.init(config); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(CONTENT_TYPE); PrintWriter out = response.getWriter(); String str_f=request.getParameter("Fahrenheit"); try { int temp_f=Integer.parseInt(str_f); double temp_c=(temp_f-32)*5/9.0; out.println("Fahrenheit: " + temp_f + ", Celsius: " + temp_c); } catch (NumberFormatException e) { out.println("Invalid temperature: " + str_f); } } }
  • 38.
    JUnit Mock Objects -Ejemplo import com.mockobjects.servlet.*; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; public class TemperatureTester extends TestCase { public TemperatureTester() { } public void test_bad_parameter() throws Exception { temperature s = new temperature(); MockHttpServletRequest request=new MockHttpServletRequest(); MockHttpServletResponse response=new MockHttpServletResponse(); request.setupAddParameter("Fahrenheit", "boo!"); response.setExpectedContentType("text/html"); s.doGet(request, response); response.verify(); assertTrue(response.getOutputStreamContents().startsWith("Invalid temperature")); }
  • 39.
    JUnit Mock Objects  Difíciles de usar (poca documentación)  Descargas y más información en www.mockobjects.com
  • 40.
    JUnit Conclusiones  Marco de automatización de pruebas.  Automatiza las pruebas de regresión.  Los casos de prueba documentan el propio código fuente.  Adecuado para Desarrollo dirigido por las pruebas.  Extensible (p.ej.: Mock), abierto, gratuito :)
  • 41.
    Pruebas Unitarias -JUnit FIN Iker Canarias iker.canarias@gmail.com