Pruebas unitarias en Haskell - PowerPoint PPT Presentation

About This Presentation
Title:

Pruebas unitarias en Haskell

Description:

La programaci n extrema o eXtreme Programming (XP) fue formulada por Kent Beck, ... http://sf.gds.tuwien.ac.at/00-pdf/z/zinc-project/manual-tecnico-1.0.0.pdf ... – PowerPoint PPT presentation

Number of Views:161
Avg rating:3.0/5.0
Slides: 49
Provided by: josed5
Category:

less

Transcript and Presenter's Notes

Title: Pruebas unitarias en Haskell


1
Pruebas unitarias en Haskell
  • José Daniel Pérez Vigo
  • Juan Diego Ruiz Perea

2
Indice
  • Introducción
  • eXtreme Programming (XP)
  • Test Driven Development (TDD)
  • Pruebas Unitarias
  • Pruebas Unitarias en otros lenguajes
  • Junit
  • Otros
  • Pruebas unitarias en Haskell
  • Hunit
  • Ventajas e Inconvenientes
  • Otro tipo de pruebas en haskell
  • QuickCheck
  • Ventajas
  • Conclusiones
  • Bibliografía

3
Introducción
  • eXtreme Programming (XP)
  • Test Driven Development (TDD)
  • Pruebas Unitarias

4
eXtreme Programming
  • La programación extrema o eXtreme Programming
    (XP) fue formulada por Kent Beck, autor del
    primer libro sobre la materia, Extreme
    Programming Explained Embrace Change en 1996.
  • Se trata del proceso ágil de desarrollo de
    software más famoso y también el más trasgresor y
    polémico.
  • Es el más popular entre los MAs 38 del mercado.

5
Características fundamentales
  • Desarrollo iterativo e incremental pequeñas
    mejoras, unas tras otras.
  • Pruebas unitarias continuas, frecuentemente
    repetidas y automatizadas, incluyendo pruebas de
    regresión. Se aconseja escribir el código de la
    prueba antes de la codificación.
  • Programación por parejas
  • Frecuente interacción del equipo de programación
    con el cliente o usuario. Se recomienda que un
    representante del cliente trabaje junto al equipo
    de desarrollo.

6
  • Corrección de todos los errores antes de añadir
    nueva funcionalidad. Hacer entregas frecuentes.
  • Refactorización del código, es decir, reescribir
    ciertas partes del código para aumentar su
    legibilidad y mantenibilidad pero sin modificar
    su comportamiento.
  • Propiedad del código compartida.
  • Simplicidad en el código es la mejor manera de
    que las cosas funcionen.

7
Test Driven Development (TDD)
  • O desarrollo guiado por pruebas es una
    metodología, utilizada de XP, consistente en
    escribir las pruebas antes que el código.
  • TDD es muy efectiva gracias a la automatización
    de las pruebas de programador (programmer unit
    test) y al hecho de que las herramientas para
    implementar está técnica son gratis y totalmente
    funcionales.

8
  • Para que funcione el desarrollo guiado por
    pruebas, el sistema tiene que ser lo
    suficientemente flexible como para permitir el
    testeo automático de software.
  • Estas propiedades permiten una rápida
    retroalimentación en el diseño y la corrección.

9
Pruebas unitarias
  • O pruebas de unidad, consisten en comprobaciones
    (manuales o automatizadas) que se realizan para
    verificar que el código correspondiente a un
    módulo concreto de un sistema software funciona
    de acuerdo con los requisitos del sistema.
  • Primero escribimos un caso de prueba y sólo
    después implementamos el código necesario para
    que el caso de prueba se pase con éxito.

10
Ventajas
  • Al escribir primero los casos de prueba,
    definimos de manera formal los requisitos que
    esperamos que cumpla nuestra aplicación.
  • Al escribir una prueba de unidad, pensamos en la
    forma correcta de utilizar un módulo que aún no
    existe.
  • Los casos de prueba nos permiten perder el miedo
    a realizar modificaciones en el código.

11
Pruebas Unitarias en otros lenguajes
  • JUnit
  • Otros

12
JUnit
  • JUnit es la biblioteca de pruebas de unidad
    estándar de facto para Java, sus dos propósitos
    básicos son ofrecer una estructura que permita
    la especificación de casos de prueba, y
    proporcionar un controlador capaz de llevar a
    cabo las pruebas de forma automática.
  • Fue desarrollado por Kent Beck y Erich Gamma, y
    es sin lugar a dudas la biblioteca más importante
    de Java perteneciente a terceras empresas.

13
  • Gracias a JUnit, los códigos Java tienden a ser
    mucho mas robustos, fiables, y libres de errores.
  • JUnit (a su vez inspirado en Smalltalk SUnit) ha
    inspirado una familia entera de herramientas
    xUnit, trasladando los beneficios de las pruebas
    de unidad a una amplia gama de lenguajes.

14
Diagrama UML de JUnit
15
Ejemplo Junit Clase Divisa
  • public class Divisa
  • private int importe
  • private String denominación
  • public Divisa(int imp, String den)
  • importe imp
  • denominación den
  • public int importe() return importe
  • public String denominación()
  • return denominación
  • public Divisa sumar (Divisa d) throws Exception
  • Divisa res
  • if (d.denominación denominación)

16
  • public class DivisaTest extends TestCase
  • private Divisa d5EUR, d12EUR ,
    d17EUR, d8USD, expected
  • public static void main(String args)
  • junit.textui.TestRunner.run(DivisaTest.class)
  • public void setUp()
  • d5EUR new Divisa(5, "EUR")
  • d12EUR new Divisa(12, "EUR")
  • d8USD new Divisa(8, "USD")
  • d17EUR new Divisa(17, "EUR")
  • public void testSumar()
  • try
  • expected (Divisa) d5EUR.sumar(d12EUR)
  • /assertEqual(expected,d17EUR)/
  • assertTrue(expected.equals(d17EUR))
  • expected (Divisa) d5EUR.sumar(d5EUR)

SetUp() se ejecuta antes de cada
test TearDown() se ejecutan despues de cada test
TestSuite ts new TestSuite(DivisaTest.class) //t
s.add(otroTest) junit.textui.TestRunner.run(ts)
17
Herramientas para otros lenguajes
  • NUnit (.NET C,J,VB y C)
  • CPPUnit (C)
  • DUnit (Delphi)
  • pyUnitPerf(python)
  • accessUnit(Access)
  • NEunit(cualquier lenguaje Unix)
  • CUnit (C)
  • ETester (Eiffel)
  • (para ver más http//www.xprogramming.com/software
    .htm)

18
Pruebas unitarias en Haskell
  • Hunit
  • Ventajas e Inconvenientes

19
HUnit
  • HUnit es un framework para pruebas de unidad
    realizado para Haskell, e inspirado por la
    herramienta de Java JUnit.
  • Fue creado en 2002 por Dean Herington estudiante
    graduado en la Universidad de Carolina del Norte,
    en el departamento de Ciencias de la computación.
  • Con HUnit, como con JUnit, podemos fácilmente
    crear test, nombrarlos, agruparlos dentro de
    suites, y ejecutarlos con el marco de trabajo que
    valida los resultados automáticamente.

20
  • De la misma manera que en Junit, el programador
    especifica una serie de pruebas del tipo
  • assertEqual "nombre_prueba" ltresultadogt
    ltfuncion_a_probargt
  • Luego se llama a la funcion que ejecuta las
    pruebas
  • runTestTT ltpruebasgt
  • Ésto muestra por pantalla los resultados de las
    pruebas.

21
  • En el módulo donde se creen los test debemos
    importar el módulo de Hunit.
  • Import Hunit
  • Definir los casos de prueba
  • test1 TestCase (assertEqual para (foo 3),"
    (1,2) (foo 3) )
  • test2 TestCase (do (x,y) lt- partA 3
  • assertEqual para el primer
    resultado," 5 x
  • b lt- partB y
  • assertBool ("(partB " show y ") failed")
    b)

22
  • Nombrar los test y agruparlos
  • tests TestList TestLabel "test1" test1,
    TestLabel "test2" test2
  • Ejecutar un grupo de casos de prueba.
  • gt runTestTT tests
  • Cases 2 Tried 2 Errors 0 Failures 0
  • gt runTestTT tests
  • Failure in 0test1
  • para (foo 3),
  • expected (1,2)
  • but got (1,3)
  • Cases 2 Tried 2 Errors 0 Failures 1

23
Escribiendo Test
  • Los asertos (Assertions) se combinan creando
    casos de prueba (TestCase), y los casos de prueba
    se combinan en tests.
  • Hunit también provee de características avanzadas
    para especificaciones de test más adecuadas.

24
Asertos
  • Es el bloque básico para construir test.
  • data Assertion IO ()
  • assertFailure String -gt Assertion
  • assertFailure msg ioError (userError ("HUnit"
    msg))
  • assertBool String -gt Bool -gt Assertion
  • assertBool msg b unless b (assertFailure msg)
  • assertString String -gt Assertion
  • assertString s unless (null s) (assertFailure
    s)

25
  • assertEqual (Eq a, Show a) gt String -gt a -gt a
    -gt Assertion
  • assertEqual preface expected actual
  • unless (actual expected) (assertFailure msg)
  • where msg (if null preface then "" else
    preface "\n") "expected " show
    expected "\n but got " show actual
  • Dado que los asertos son computaciones IO pueden
    ser combinados usando los operadores (gtgt) y
    (gtgt), y la notación do para formar asertos
    colectivos. Esta combinación fallará si
    cualquiera de los asertos que lo componen falla y
    terminará su ejecución con el primero de los
    mismos.

26
Caso de Prueba(CdP)
  • Es la unidad de una ejecución de prueba, es
    decir, CdP distintos, son ejecutados
    independientemente. El fallo de uno es
    independiente del fallo de cualquier otro.
  • Un CdP consiste en un aserto simple o
    posiblemente colectivo. Un CdP puede involucrar
    una serie de pasos, cada uno terminado en un
    aserto, donde cada paso debe tener éxito para
    poder continuar con el CdP.

27
  • Para crear un CdP desde un aserto se aplica el
    constructor TestCase. Ejemplos
  • TestCase (return ())
  • TestCase (assertEqual para x, 3 x)
  • Se han implementado también operadores para crear
    CdP de manera mas sencilla, estos son _at_?, _at_?,
    _at_? ?, ?, ? ,

28
Tests
  • Cuando se tiene más de un CdP se hace necesario
    nombrarlos y agruparlos en listas, para ello
    usamos
  • data Test TestCase Assertion
  • TestList Test
  • TestLabel String Test
  • Para conocer el número de CdP que componen un
    test podemos usar la función
  • testCaseCount Test -gt Int

29
Ejecución de Pruebas
  • HUnit esta estructurado para soportar múltiples
    controladores de test.
  • Todos los controladores comparten un modelo común
    de ejecución de test. Sólo difieren en como son
    mostrados los resultados.
  • La ejecución de un test implica la ejecución
    monádica de cada uno de sus CdP

30
Ejecución de Pruebas (cont)
  • Durante la ejecución 4 contadores sobre los casos
    de prueba son mantenidos
  • data Counts Counts cases, tried, errors,
    failures Int deriving (Eq, Show, Read)
  • cases número de CdP incluidos en el test. 
  • tried número de CdP que han sido ejecutados.
  • errors número de CdP cuya ejecución termina con
    una excepción no esperada.
  • failures número de CdP cuya ejecución termina en
    fallo.

31
Ejecución de Pruebas (cont)
  • Tal y como procede la ejecución de una prueba,
    son tres las clases de eventos de informe que se
    comunican al controlador de la prueba. 
  • start Antes de la inicialización del test, se le
    manda este evento al controlador para reportar
    los contadores (excluyendo el CdP actual).
  • error Cuando un CdP finaliza con un error, el
    mensaje de error es reportado, junto con el
    camino del CdP y os contadores actuales
    (incluyendo el CdP actual).
  • failure Cuando un CdP finaliza con un fallo, el
    mensaje de fallo es reportado, junto con el
    camino del CdP y os contadores actuales
    (incluyendo el CdP actual).

32
Ventajas e Inconvenientes
  • Ventajas
  • La especificación de pruebas en HUnit es incluso
    más concisa y flexible que en JUnit gracias a la
    naturaleza del lenguaje Haskell.
  • El diseño del tipo Test es conciso, flexible y
    conveniente para la especificación de pruebas. Es
    más la naturaleza de Haskell aumenta
    significativamente estas cualidades.
  • Combinar asertos y otro tipo de código para
    construir casos de prueba es fácil con la mónada
    IO.
  • Usando funciones sobrecargadas y operadores
    especiales, la especificación de asertos y
    pruebas es extremadamente compacto.
  • Estructurando un árbol de pruebas por valor, más
    que por nombre como en JUnit, provee de una
    especificación de juego de test más conveniente,
    flexible y robusto. En particular, un juego de
    test puede ser computado más fácilmente sobre la
    marchar que en otros test frameworks.
  • Las facilidades de poderosa abstracción de
    Haskell provee de un sopote sin igual para la
    refactorización de test

33
Ventajas e Inconvenientes (cont)
  • Inconvenientes
  • Según Diego Berrueta 1 la limitación más
    importante encontrada al escribir las pruebas
    unitarias consiste en la imposibilidad de
    comprobar las situaciones de error debido a que
    Haskell no dispone de un mecanismo común para
    tratar las condiciones anormales en funciones
    puras.
  • Otra dificultad viene determinada por la
    necesidad, en muchas ocasiones, de crear
    estructuras de datos complejas necesarias para su
    uso en todos los casos de prueba que componen las
    pruebas unitarias.

34
Otro tipo de pruebas en haskell
  • QuickCheck
  • Ventajas

35
Quickcheck
  • Fue creado por Koen Claessen y John Hughes 2
    (Chalmers University of Technology) en el 2000.
  • Es una herramienta para el chequeo automático de
    programas Haskell.
  • El programador proporciona una especificación del
    programa a través de propiedades que las
    funciones deberían satisfacer.
  • QuickCheck entonces prueba que las propiedades se
    cumplan en un gran número de casos generados
    aleatoriamente.

36
  • Definir una propiedad
  • ltnombre_propgt ltvblesgt ltpropgt
  • where ltsupuestogt ltvblegtlttipogt
  • Para ejecutar la prueba de la propiedad
  • quickCheck lt nombre_prop gt
  • verboseCheck lt nombre_prop gt

37
Propiedades
  • Las propiedades son expresadas como definiciones
    de funciones en Haskell, con nombres que
    comienzan por prop_.
  • Estan universalmente cuantificadas sobre sus
    parámetros.
  • Deben tener tipos monomórficos
  • Propiedades polimórficas deben ser restringidas a
    un tipo particular mediante
  • where supuestos (x1 t1, x2 t2, ...)
  • El tipo del resultado de una propiedad debe ser
    Bool, a menos que sea definida usando
    combinadores que veremos más adelante.

38
Propiedades Condicionales y Cuantificadas
  • Las propiedades pueden tomar la forma
  • ltcondicióngt gt ltpropiedadgt
  • La propiedad condicional se cumplirá si para
    todos los casos que la condición se cumple, la
    propiedad también se cumple.
  • O esta otra forma
  • forAll ltgeneradorgt \ltpatrongt -gt ltpropiedadgt
  • Donde generador es un generador de datos de
    prueba que veremos más adelante.

39
Propiedades triviales
  • Sirven para mostrar estadísticas del número de
    casos triviales que han aparecido y tienen la
    forma
  • ltcondicióngt trivial ltpropiedadgt
  • Los casos de prueba cuya condición es True son
    clasificados como triviales, y la proporción de
    casos triviales sobre el total es mostrada.

40
Clasificando Casos de Prueba
  • Se pueden clasificar de la forma
  • classify ltcondicióngt ltstringgt ltpropiedadgt
  • Los casos de prueba que satisfacen la condición
    son asignados a la clasificación dada, y después
    del test se informa de la distribución de la
    clasificación.

41
Recolectando valores de datos
  • Otra propiedad seria
  • collect ltexpresióngt ltpropiedadgt
  • El primer argumento de collect es evaluado en
    cada caso de prueba, y la distribución de valores
    es reportada.
  • Todas las observaciones vistas hasta ahora pueden
    ser combinadas libremente.

42
Generadores de datos de prueba Tipo Gen
  • QuickCheck define generadores por defecto para
    una amplia colección de datos
  • ..
  • El programado puede usar los suyos propios con
    forAll.
  • Los generadores tienen como tipo Gen a
  • Se pueden construir mediante la función
  • choose Random a gt (a,a) -gt Gen a
  • do ilt-choose (0,length xs-1) return (xs!!i)

43
Ventajas e inconvenientes
  • Ventajas
  • QuickCheck da valor a las especificaciones
    ofreciendo recompensas a corto plazo.
  • QuickCheck fomenta formular especificaciones
    precisas y formales, en Haskell. Como otras
    especificaciones formales, las propiedades de
    QuickCheck tienen un significado claro y no
    ambiguo.
  • QuickCheck chequea el programa intentando
    encontrar contraejemplos de sus especificaciones.
    Aunque esto no puede garantizar que el programa y
    la especificación son consistentes, reduce
    enormemente el riesgo de que no lo sean.
  • Es fácil validar las especificaciones con cada
    cambio que hagamos a un módulo.
  • Las especificaciones de QuickCheck documentan
    como validar tu programa de manera que cualquier
    programador que vea tu código sabrá que
    propiedades han sido validadas y cuales no.
  • QuickCheck reduce el tiempo invertido en validar,
    generando muchos CdP automaticamente.

44
  • Inconvenientes
  • Es importante tener cuidado con la distribución
    de los casos de prueba si los datos de prueba no
    están bien distribuidos entonces las conclusiones
    de los resultados de los test pueden no ser
    válidas.
  • En particular el operador gt puede torcer la
    distribución de los datos de prueba, ya que solo
    los datos de prueba que satisfagan la condición
    dada serán utilizados.

45
Conclusiones
  • Las pruebas unitarias son una herramienta muy
    útil en el desarrollo y diseño de SW ya que
    ayudan a garantizar que el programa hace justo lo
    se especifica en los CdP que lo definen.
  • No obstante, hay algunos casos en los que no
    pueden ser usadas.
  • Herramientas de pruebas unitarias están
    implementadas en casi cualquier lenguaje de
    programación.

46
  • Los CdP son útiles en cualquier momento del
    desarrollo del SW aunque cambiemos la
    implementación siempre que se mantenga la
    interfaz.
  • Si los CdP son correctos y completos podremos
    modificar sin ningún miedo nuestro código y saber
    si sigue funcionando tal y como debe funcionar.
  • Existen otros tipos de prueba de programa además
    de las pruebas unitarias.

47
Bibliografía
  • 1 Clases de tipo en un lenguaje
    lógico-funcional, Diego Berrueta Muñoz. Tutor
    Jose Emilio Labra Gayo (Universidad Politécnica
    de Oviedo 2004)
  • http//sf.gds.tuwien.ac.at/00-pdf/z/zinc-project/m
    anual-tecnico-1.0.0.pdf
  • Refactoring Improving the Design of Existing
    Code. Martin Fowler, Kent Beck, John Brant,
    William Opdyke. The Addison-Wesley Object
    Technology Series.(1999)
  • TDD y Nunit
  • www.willydev.net web sin animo de lucro con
    recursos gratuitos sobre la plataforma .NET y
    otros contenidos
  • Pruebas unitarias
  • http//elvex.ugr.es web de Fernando Berzal
    Galiano con software y cursos de libre
    disposición.
  • http//www.lawebdejm.com información sobre
    pruebas unitarias, CPPUnit y DUnit

48
  • Programación extrema (XP)
  • http//www.xprogramming.com
  • http//www.xprogramming.com/software.htm
    encontramos software para el desarrollo de
    pruebas unitarias en prácticamente todos los
    lenguajes existentes.
  • http//www.asturlinux.org Asociación de
    Usuarios Asturianos de Linux.
  • HUnit
  • http//www.di.uniovi.es/labra Jose E. Labra.
    Profesor titular de la Universidad de Oviedo.
    Información sobre Pruebas Unitarias, Junit y
    Hunit
  • http//hunit.sourceforge.net/ página principal
  • http//sourceforge.net/projects/hunit sitio web
    sobre el proyecto
  • http//www.informatik.uni-bremen.de/agbkb/lehre/ws
    04-05/fmsd/ ejercicios propuestos para resolver
    en hunit (universidad de bremen)
  • QuickCheck
  • http//www.cs.chalmers.se/rjmh John Hughes
    profesor de la Universidad de Tecnológica de
    Chalmers en Suecia
  • Junit
  • http//www-128.ibm.com/developerworks/java/library
    /j-junit4.html
  • http//www.junit.org/
Write a Comment
User Comments (0)
About PowerShow.com