• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Introducción a JUnit
 

Introducción a JUnit

on

  • 8,493 views

Introducción a pruebas unitarias con JUnit.

Introducción a pruebas unitarias con JUnit.

Statistics

Views

Total Views
8,493
Views on SlideShare
8,493
Embed Views
0

Actions

Likes
2
Downloads
196
Comments
1

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

11 of 1 previous next

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Introducción a JUnit Introducción a JUnit Presentation Transcript

    • Pruebas unitarias JUnit
    • Pruebas unitariasConceptos 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 unitariasRequisitos  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 unitariasRequisitos  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 unitariasObjetivos  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 unitariasVentajas  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 unitariasVentajas  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 unitariasLimitaciones  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
    • JUnitConceptos 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.
    • JUnitConceptos 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 sencillopackage dominio;import java.util.Vector; ← Representa una lista ordenable de formapublic 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) }}
    • JUnitEjemplo 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"
    • JUnitEjemplo 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"}
    • JUnitEjemplo 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();
    • JUnitEjemplo 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)
    • JUnitEjemplo 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()); }
    • JUnitEjemplo 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.
    • JUnitEjemplo 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()); } }
    • JUnitEl 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 TestRunnerpublic 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()); }
    • JUnitEl TestRunner – Errors vs Failures
    • JUnitEl TestRunner – Test OK
    • JUnitTestRunner - 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.
    • JUnitPruebas 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; }
    • JUnitPruebas 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()); }
    • JUnitPruebas 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 } }
    • JUnitRedefinición de método equals  Todas las clases Java extienden de Object y por lo tanto heredan: Llamado por los assertEquals(...) definidos en Assert
    • JUnitRedefinició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.
    • JUnitEjemplo - 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 - equalspublic 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): booleanpublic 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());}
    • JUnitOtros 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); }
    • JUnitOtros 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); }
    • JUnitMock Objects  Basados en JUnit.  Sustituyen a clases complejas, dispositivos, etc.  Ejemplos: servlets, páginas jsp, bases de datos...
    • JUnit Mock Objects - Ejemplopublic 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); } }}
    • JUnitMock Objects - Ejemploimport 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")); }
    • JUnitMock Objects  Difíciles de usar (poca documentación)  Descargas y más información en www.mockobjects.com
    • JUnitConclusiones  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