Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test...

41
PRUEBAS DE SOFTWARE de tipo xUnit PRUEBAS DE SOFTWARE de tipo xUnit Mayo de 2008 1

Transcript of Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test...

Page 1: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

PRUEBAS DE SOFTWARE de tipo xUnit Mayo de 2008

1

Page 2: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

CONCEPTOS .....................................................................................................4 DEFINICIONES ................................................................................................6

ESTRATEGIA MÍNIMA DE AUTOMATIZACION DE TESTS ......................................................6 Proceso de desarrollo ..................................................................................6 Pruebas de usuario .....................................................................................6 Unit Tests ..................................................................................................6 Diseñando para testeabilidad........................................................................6 Organización de los tests .............................................................................6

TEST SMELLS (SÍNTOMAS) ....................................................................................6 En proyectos ..............................................................................................6 En el comportamiento .................................................................................6 En el código ...............................................................................................6

OBJETIVOS, FILOSOFÍA Y PRINCIPIOS DE LA AUTOMATIZACIÓN ...................7 OBJETIVOS ......................................................................................................7

Mejorar la calidad .......................................................................................7 Entender al SUT .........................................................................................7 Reducir los riesgos ......................................................................................7 Tests fáciles de ejecutar ..............................................................................7 Tests fáciles de escribir y mantener ...............................................................8 Tests con mínimo mantenimiento ante evolución del sistema ............................8

FILOSOFÍA.......................................................................................................8 Escribir tests antes o después del código a probar ...........................................8 Probar uno a uno o todo a la vez...................................................................8 Probar desde afuera hacia adentro o desde adentro a afuera.............................8 Probar comportamiento o estados .................................................................8 Establecer condiciones de prueba por test o condiciones para todos ...................8

PRINCIPIOS .....................................................................................................9 ESTRATEGIA ..................................................................................................10

QUÉ CLASE DE TEST AUTOMATIZAR.........................................................................10 CUÁLES HERRAMIENTAS UTILIZAR PARA LA AUTOMATIZACIÓN...........................................11 CÓMO ADMINISTRAR LAS CONDICIONES DE PRUEBA......................................................12 CÓMO ASEGURAR QUE EL SISTEMA SERÁ EFICIENTEMENTE PROBADO...................................13

Fake Object .............................................................................................14 Test Stub y Mock Object ............................................................................14 Pruebas por capas....................................................................................15

XUNIT............................................................................................................16 DESCRIPCIÓN DE LAS PAUTAS INICIALES (REQUERIMIENTOS)...........................................16 DISEÑO DE JUNIT ............................................................................................16

CONDICIONES DE PRUEBA ............................................................................20

2

Page 3: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

CONDICIONES TRANSITORIAS ..............................................................................20 Formas de establecimiento.........................................................................20

CONDICIONES PERSISTENTES...............................................................................20 Desventajas.............................................................................................20 Soluciones ...............................................................................................20 Test encadenados .....................................................................................20

VERIFICACIÓN DE RESULTADOS....................................................................22 VERIFICACIONES BÁSICAS...................................................................................22

Comparación de objetos de tipo ValueObjects ...............................................22 Test de Objetos que crean otros objetos.......................................................24 Verificación de comportamiento ..................................................................25 Verificación de estado................................................................................25

LAS PRUEBAS COMO CRITERIO DE DISEÑO ...................................................26 EJEMPLO.......................................................................................................26

UTILIZANDO PLUGINS...................................................................................27 TESTDOUBLE..................................................................................................27

Creación y configuración ...........................................................................27 Instalación...............................................................................................27 MockObject..............................................................................................29 Subclases ................................................................................................30 SpyObject................................................................................................31 FakeObject ..............................................................................................34

PRUEBAS CON BASES DE DATOS....................................................................35 ORGANIZACIÓN DE LOS TESTS DE UN PROYECTO..........................................36

ESTRATEGIAS .................................................................................................36 TestClass por clase ...................................................................................36 TestClass por funcionalidad ........................................................................37 TestClass por condicón de prueba ...............................................................37

HERRAMIENTAS.............................................................................................39 PRUEBAS DE LAS DISTINTAS CAPAS.........................................................................39 FRAMEWORKS.................................................................................................39

JUnit .......................................................................................................39 ServletUnit ..............................................................................................39 HttpUnit ..................................................................................................39 Watir ......................................................................................................40

REFERENCIAS ................................................................................................41

3

Page 4: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Conceptos • Verificación automatizada: contribuye con aumento de productividad, mejora

de la calidad y mantiene al software robusto a lo largo del proceso de desarrollo

• Realimentación: provee información a lo largo del proceso de desarrollo que es utilizada para realizar cambios y agregar nuevas funcionalidades con mayor confianza.

• Testing: pruebas tradicionales no sirven para mejorar la calidad sino para medirla al ser ejecutadas en forma tardía. Se propondrán pruebas tempranas de unidad, integración y funcionalidad.

• Pruebas de Programadores: de servicios y funcionales. Fomentar las pruebas como parte de las actividades de estos roles crea la cultura de las pruebas como condición indispensable del proceso de desarrollo.

• Automatización: existen sistemas que facilitan la automatización pero cuentan con debilidades. El problema de la fragilidad de los tests utilizando estas herramientas (ej. robots) ha generado opiniones a favor y en contra.

o Comportamiento: cambios a los productos por cambios en requerimientos hacen que las pruebas programadas fallen

o Interfaz: las pruebas basadas en las interfaces de usuario fallan ante cambios menores de las mismas. Las arquitecturas en capas han resuelto algunos problemas de este tipo al desacoplarlas del negocio, pero introdujeron un componente difícil de probar, HTML y el browser cliente.

o Datos: como precondiciones para que el test ejecute. La dependencia de los datos en el sistema pueden hacer que fallen los test.

o Contexto: afecta a los tests de las más diversas formas haciéndolos irrepetibles. Dependen de la fecha, hora, accesos a servidores, etc.

• Uso de automatización de los tests

o Como especificación: a partir del modo de uso de los componentes y su integración al sistema en desarrollo.

o Test Driven Development: conduciendo el diseño a partir de la interacción con los test.

• Patrones: hay suficiente experiencia en el uso de las técnicas de pruebas utilizando xUnit, las cuales fueron agrupadas como patrones de estrategias, diseño y codificación de tests.

• Terminología (ver figura 1) o SUT (system ander test): sistema bajo test

o Fixture: condiciones para que el test sea ejecutado

4

Page 5: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

o DOC (dependend on component): componente del que se depende

o xUnit: familia de frameworks sobre los que se diseña, programa y ejecutan tests.

Figura 1

Figura extraída de [1]

5

Page 6: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Definiciones ESTRATEGIA MÍNIMA DE AUTOMATIZACION DE TESTS

Proceso de desarrollo • Pruebas funcionales definidas a partir de la especificación de requerimientos

• Tests unitarios y de integración cubriendo todo el código

• Testeo continuo como práctica de integración

Pruebas de usuario • Pruebas de aceptación

Unit Tests • Test simples que cubren las instancias de clases en diferentes escenarios

• Condiciones de pruebas diseñadas

• Resultados verificados

Diseñando para testeabilidad Criterios de buen diseño que entre otras cosas facilitan las pruebas de los diferentes componentes a partir del desacoplamiento. Arquitecturas en capas, inversión en la cadena de dependencia, código clausurado ante cambios, segregación de interfaces y dependencias no cíclicas son algunas de estas buenas prácticas.

Organización de los tests Distribución de los tests en conjuntos según los métodos de las clases o según las condiciones de ejecución por ejemplo.

TEST SMELLS (SÍNTOMAS) La mala calidad de los tests se ponen de manifiesto de distintas formas.

En proyectos Afectan a la funcionalidad, calidad, recursos y costo. Se evidencian a partir de métricas tales como el nro de veces que deben ser modificados los tests, el nro de errores encontrados en las pruebas de funcionalidad realizadas por usuarios (aceptación).

En el comportamiento Causan las fallas de los tests o directamente no compilan. Dependen y son frágiles frente a cambios en interfaces, datos, funcionalidad, fecha, hora, accesos a servidores, etc.

En el código Código escrito utilizando malas prácticas, las cuales son reconocidas por inspección.

6

Page 7: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Objetivos, filosofía y principios de la automatización

Escusaspara no probar

Clientes no entienden de pruebas lo qua a veces genera la tentación de que escribir código para probar es opcional

El cliente no paga por el código de prueba

Escribir pruebas es duro

Esto generó la necesidad de convertir a las pruebas an automáticas, fáciles de mantener, vincularlas al desarrollo, robustas y efectivas.

Economía de la automatización de los tests

gráfico

OBJETIVOS • Mejorar la calidad

• Entender al SUT

• Reducir los riesgos

• Tests fáciles de ejecutar

• Tests fáciles de escribir y mantener

• Tests con mínimo mantenimiento ante evolución del sistema

Mejorar la calidad Validación (construimos el producto correcto). Test como especificación refleja cómo será usado el SUT. Prototipos de interfaces ayudan a entender el comportamiento en el ambiente aperacional. Vaildación de requerimientos ambiguos y contradictorios.

Verificación (producto construido correctamente). Previene errores, no los detecta sino que evita su introducción. Testeo continuo -> todos los tests ok antes de checkin. Localización de defectos, Unittest + Tests de Usuarios. Si los útimos fallan -> código no probado por unittest.

Entender al SUT Documentación-> SelfTest -> Resultados Esperados

Reducir los riesgos Mejor documentación + previene errores + mantiene último release funcionando y actualizado (testeo continuo = UnitTest + Ctrol. Versión)

Tests fáciles de ejecutar Fácil -> se corren

No Fácil -> NO se corren

7

Page 8: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Fácil

o Automáticos: edición + compilación + linkeo + ejecución (make, ant, etc)

o Selfchecking: Hollywood Principle, si falla la plataforma avisa

o Repetibles: mismos resultados en múltiples ejecuciones sin intervención manual

o Independientes: posible ejecución aislada

Tests fáciles de escribir y mantener o Centrado en testing y no en código

o No invasivo (no cbios. Al SUT)

o Fácil de leer

o Simples, prueba de una condición a la vez

o Expresivos, desde el negocio por ejemplo

o Separación de incumbencias, 1) separado del código productivo, 2) prueba de aspectos por separado

Tests con mínimo mantenimiento ante evolución del sistema Robustos -> Setup + Teardown y aislados del ambiente

FILOSOFÍA • Escribir tests antes o después del código a probar

• Probar uno a uno o todo a la vez

• Probar desde afuera hacia adentro o desde adentro a afuera

• Probar comportamiento o estados

• Establecer condiciones de prueba por test o condiciones para todos

Escribir tests antes o después del código a probar Escribir primero el test ayuda a pensar la forma en que será utilizado el componente a desarrollar y a la asignación de responsabilidades a las clases, garantiza la testteabilidad, hace más naturla el código de acceso a los estados y a la verificación de resultados y contribuye a la valización de los requerimientos. Esta forma de trabajo es conocida como Test Driven Design (TDD).

Probar uno a uno o todo a la vez Desarrollo incremental -> test, código, test, código

Variante-> conjunto de métodos vacíos cohesivos desde el negocio son llenados de a uno

Probar desde afuera hacia adentro o desde adentro a afuera Ver figura siguiente

Probar comportamiento o estados Afuera -> adentro facilita la prueba de comportamiento. Más costoso por el uso de MockObjects, Test Spies, etc.

Establecer condiciones de prueba por test o condiciones para todos Testing tradicional-> varios tests con DB poblada de datos para todos ellos.

8

Page 9: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Tendencia-> Fresh Fixture, MinimalFixture

PRINCIPIOS AL IGUAL QUE LOS CRITERIOS SON DISCUTIBLES Y SON MÁS ABSTRACTOS QUE LOS PATRONES. EXISTE LA MISMA RELACIÓN QUE EN EL DISEÑO CON LOS CRITERIOS DE BUEN DISEÑO Y LOS PATRONES DE DISEÑO.

Escriba el test primero

Diseñe para que haya testeabilidad

Utilice las interfaces públicas siempre que pueda, antes que accesos no visibles o recursos privados

Comunique el intento, para facilitar la lectura y mantenimiento

No modifique el SUT, para garantizar que se prueba lo desarrollado y lo que irá al ambiente productivo

Mantenga a los tests independientes para eliminar dependencias y facilitar el aislamiento de errores

Aisle al SUT para no depender del ambiente

Minimice el solapamiento de tests para facilitar el mantenimiento

Minimice el código no probado para evitar errores en pruebas funcionales y en ambiente productivo (Ej if prueba uso StubeObject)

Mantenga la lógica de prueba fuera del código productivo para evitar fallas en producción

Verifique una condición a la vez para facilitar el aislamiento de errores con sus fases de establecimiento de condiciones, ejecución, verificación de resultados y desarmado de condiciones. (Un assert por condición o agrupamiento en CustonAssert)

Pruebe incumbencias por sep arado para facilitar el aislamiento de errores y el

Asegure esfuerzo de tests en relación con el desarrollo para que sea sustentable

mantenimiento de los tests

9

Page 10: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Estrategia Una estrategia está dada por un conjunto de decisiones que son difíciles de cambiar. Es por esto que es importante elaborarla con cuidado ya que en ella se basará nuestra planificación de las pruebas de nuestro sistema en desarrollo.

Entre las decisiones que hacen a la estrategia están:

Qué clase de test automatizar

Cuáles herramientas utilizar para la automatización

Cómo administrar las condiciones de prueba

Cómo asegurar que el sistema será eficientemente probado

QUÉ CLASE DE TEST AUTOMATIZAR

Figura extraída de [1]

10

Page 11: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Figura extraída de [1]

CUÁLES HERRAMIENTAS UTILIZAR PARA LA AUTOMATIZACIÓN

Figura extraída de [1]

11

Page 12: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

CÓMO ADMINISTRAR LAS CONDICIONES DE PRUEBA Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos, objetos creados, etc. constituyen las condiciones para las pruebas. Tienen gran impacto sobre el tiempo de ejecución y la robustes de los tests.

Figura extraída de [1]

Frescas y transitorias: son creadas por cada test cuando son ejecutados.

Frescas y persistentes: funcionan en escenarios donde se prueban componentes acoplados por algún medio persistente. Necesitan código que se ocupe de desarmarlas (tear down).

Compartidas: funcionan en escenarios donde se busca optimizar la ejecución de tests cuando se usa la táctica de Fresca y Persistentes. Necesitan código que se ocupe de establecerlas y desarmarlas. Las distintas formas de implementación se muestran en la figura que sigue.

Figura extraída de [1]

12

Page 13: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

CÓMO ASEGURAR QUE EL SISTEMA SERÁ EFICIENTEMENTE PROBADO

Probar lo antes posible: mientras se diseña y desarrolla

Diseñar para testeabilidad: utilizando criterios de buen diseño

Pruebas estructuras de forma de contar con puntos de control y de observación.

Figura extraída de [1]

Utilizar una táctica de prueba para cada caso (patrones), por ejemplo:

Fake Object: para reemplazar componentes de los cuales se depende y mejorar repetibilidad o performance

TestStub: para controlar entradas indirectas

MockObject: para verificar salidas indirectas

SpyTest: para verificar comportamiento a través de salidas indirectas

TestDouble: para reemplazar subsistemas con los que se interactua y obtener entradas indirectas

13

Page 14: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Fake Object

Figura extraída de [1]

Reemplazamos componentes para mejorar la performance del test. Ej. Pruebas por capas, donde las inferiores son reemplazadas por Fakes.

Test Stub y Mock Object

Figura extraída de [1]

Entradas indirectas usadas como punto de control, salidas indirectas usadas como punto de observación. Ej. Stub : Excepciones, Ej. Mock: ResultSet

14

Page 15: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Pruebas por capas

Figura extraída de [1]

Ej. Prueba de una aplicación enterprise desde la capa de presentación, reemplazando al sistema (acceso al negocio, negocio, persistencia) por una FakeObject.

15

Page 16: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

xUnit DESCRIPCIÓN DE LAS PAUTAS INICIALES (REQUERIMIENTOS).

⇒ Pruebas de ejecución automática una vez construidas -> permite su ejecución continua

⇒ Pruebas repetitivas -> genera seguridad

⇒ Facil de construir y ejecutar por los desarrolladores -> permite mismo lenguaje de desarrollo y garantiza que serán construidas

⇒ Verifique resultados y los informe

⇒ Manipulación de casos de prueba como si fueran objetos

DISEÑO DE JUNIT 1. Encapsular en un objeto un test -> Command

public abstract class TestCase implements Test { … }

2. Cada test tendría un nombre para identificarlo cdo. falla por ejemplo

public abstract class TestCase implements Test { private final String fName;

public TestCase(String name) { fName= name; }

public abstract void run(); … }

3. Dónde escribir el código de seteo de condiciones, ejecución, prueba de resultados y destrucción de condiciones. Este es un algoritmo prefijado, luego utilizamos un TemplateMethod

public void run() { setUp(); runTest(); tearDown(); }

4. Necesitamos informar resultados

Recolectamos resultados public class TestResult extends Object { protected int fRunTests;

public TestResult() { fRunTests= 0; } }

modificamos el método run original para utilizarlo

16

Page 17: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

public void run(TestResult result) { result.startTest(this); setUp(); runTest(); tearDown(); }

public synchronized void startTest(Test test) { fRunTests++; }

public TestResult run() { TestResult result= createResult(); run(result); return result; }

protected TestResult createResult() { return new TestResult(); }

5. Distinguir entre fallas y errores

public void run(TestResult result) { result.startTest(this); setUp(); try { runTest(); } catch (AssertionFailedError e) { //1 result.addFailure(this, e); }

catch (Throwable e) { // 2 result.addError(this, e); } finally { tearDown(); } }

protected void assertTrue(boolean condition) { if (!condition) throw new AssertionFailedError(); }

public class AssertionFailedError extends Error { public AssertionFailedError () {} }

public synchronized void addError(Test test, Throwable t) { fErrors.addElement(new TestFailure(test, t)); }

public synchronized void addFailure(Test test, Throwable t) { fFailures.addElement(new TestFailure(test, t)); }

public class TestFailure extends Object { protected Test fFailedTest; protected Throwable fThrownException; }

6. Cómo relaciono a la clase TestCase con el código que escribimos para probar y

con la clase popietaria del código a probar ¿?

17

Page 18: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Una posibilidad es utilizar un adapter, así tendríamos una clase adaptadora por cada tests con la consiguiente proliferación de clases.

class MiTestMetodo_1_claseA extends TestCase {

runTest(){ a.metodo_1();

} A a;

} En lugar de esto usaron clases anónimas

TestCase test= new Test("testMetodo_1 ") { protected void runTest() { A a = new A(); a.metodo_1(); } };

7. Ejecutar todos los test programados como métodos de una clase de prueba

Uncomposite es el patrón indicado

public static Test suite() { TestSuite suite= new TestSuite(); suite.addTest(new MoneyTest("testMoneyEquals")); suite.addTest(new MoneyTest("testSimpleAdd")); }

public static Test suite() { return new TestSuite(MoneyTest.class); }

18

Page 19: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

cd JUnit

«interface»Tets

+ run(TestResult) : void

TestCase

- name: String

+ assertEquals(boolean, boolean) : void+ fail() : void+ run() : TestResult+ run(TestResult) : void# runtest() : void# setUp() : void+ suite() : Test# tearDown() : void+ TestCase(String) : void

public void run(TestResult result) { result.startTest(this); setUp(); try { runTest(); } catch (AssertionFailedError e) { //1 result.addFailure(this, e); } catch (Throwable e) { // 2 result.addError(this, e); } finally { tearDown(); } }

protected void assert(boolean condition) { if (!condition) throw new AssertionFailedError(); }

TestResult

+ startTest(Test) : void

public synchronized void addError(Test test, Throwable t) { fErrors.addElement(new TestFailure(test, t)); } public synchronized void addFailure(Test test, Throwable t) { fFailures.addElement(new TestFailure(test, t)); }

AssertionFailedError

Error

TestFailure

Throwable

MiTest

# runtest() : void+ testAlgo() : void

1 - El adapter estandard requiere una clase por método !!!!!!!!protected void runTest () { testAlgo(); } . Demasiadas clases.

2 - En Java un adapter con clase anónima interna que redefine runTest()TestCase test= new MiTest("algo") { public void runTest() { testAlgo(); } }; test.run();

3 - Reflection (Plugeable Selector)TestCase test = new MiTest("testAlgo"); // busca por nombre test.run();....protected void runTest() throws Throwable { Method runMethod= null; try { runMethod= getClass().getMethod(fName, new Class[0]); } catch (NoSuchMethodException e) { assert("Method \""+fName+"\" not found", false); } try { runMethod.invoke(this, new Class[0]); // en este caso no tenemos parámetros, luego es un array vacío } // catch InvocationTargetException and Il legalAccessException }

Command

Adapter

TestSuite

+ run(TestResult) : void

public void run(TestResult result) { for (Enumeration e= fTests.elements(); e.hasMoreElements(); ) { Test test= (Test)e.nextElement(); test.run(result); } }

Assert

+ assertEquals(boolean, boolean) : void+ fail() : void

Composite

Template MethodFactory Method

Plugeable Selector

19

Page 20: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Condiciones de prueba

CONDICIONES TRANSITORIAS

Formas de establecimiento ⇒ Inline

⇒ Delegada

⇒ Implícita

Son establecidas en y para cada ejecución de cada uno de los tests.

CONDICIONES PERSISTENTES Frescas: Son aquellas establecidas y que persisten más allá de la ejecución del test, por ejemplo datos a una DB, variables de clases, objetos statefull, etc. Esto es así porque al ser frescas se crean y destruyen por cada test.

Desventajas • Tests lentos

Soluciones Reemplazar persistencia en file system y/o DB por memoria, posible uso de FakeObject.

Test encadenados

Figura extraída de [1]

Ejemplo de tests encadanados: pruebas de ABM (alta, baja, modificación)

20

Page 21: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

cd PruebasEncadenadas

TestDataMapperABM

ProyectoDataMapper

testAlta

testModificar

testBaja

TestRunner

TestCase

testConfirmaBorrado

«call»

assert 1

«call»assert 2

«call»

assert 3

«instantiate»

«instantiate»

«instantiate»«call»

assert 4

21

Page 22: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Verificación de resultados VERIFICACIONES BÁSICAS Comparación de Resultados Esperados contra Resultados Obtenidos a partir de Asserts

assertEquals(3, value); donde 3 es el valor esperado y value es el obtenido !!!, value es de tipo primitivo.

Comparación de objetos de tipo ValueObjects Necesita de método de comparación (Object.equals()) adecuadamente redefinido. Debe cumplir con las propiedades de reflexiva, simétrica y transitiva.

Test de constructores

A partir de la verid¡ficación de sus atributos accedidos con get o agregar método isValido() si no se desea dar acceso a los atributos.

Test de get y Set Deberían escribirse solo si además de dar acceso se realiza algo más- Ej. Cálculos, o cualquier indirección. Utilizo los gets asociados o algún acceso indirecto que utilice los atributos seteados.

Test de interfaces

Requiere de un test que permita probar todas las posibles implementaciones. Ej. Iterator.

22

Page 23: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

cd TestInterfaces

AssertJUnit::TestCase

- name: String

+ assertEquals(boolean, boolean) : void+ fail() : void+ run() : TestResult+ run(TestResult) : void# runtest() : void# setUp() : void+ suite() : Test# tearDown() : void+ TestCase(String) : void

IteratorTest

- noMoreElementsIterator: Iterator

+ makeNoMoreElementsIterator() : Iterator# setUp() : void

ListIteratorTest

+ makeNoMoreElementsIterator() : Iterator

SetIteratorTest

+ makeNoMoreElementsIterator() : Iterator

public abstract class IteratorTest extends TestCase {private Iterator noMoreElementsIterator;protected abstract Iterator makeNoMoreElementsIterator();protected void setUp() {noMoreElementsIterator = makeNoMoreElementsIterator();}public void testHasNextNoMoreElements() {assertFalse(noMoreElementsIterator.hasNext());}public void testNextNoMoreElements() {try {noMoreElementsIterator.next();fail("No exception with no elements remaining!");}catch (NoSuchElementException expected) {}}public void testRemoveNoMoreElements() {try {noMoreElementsIterator.remove();fail("No exception with no elements remaining!");}catch (Il legalStateException expected) {}}}

Test de JavaBeans

Consistirían en un conjunto de pruebas de gets y sets. Es más útil probar estado interno a través de métodos de validación tipo isValid().

Test de Excepciones

Requiere la prueba de que se dispare la correcta.

public void testConstructorNull() throws Exception { try {

Fraction oneOverZero = new Fraction(1, 0); fail("Intentó crear la fracción 1/0, este valor es indefinido ¡!"); // si no

se dispara avisa } catch (IllegalArgumentException expected) {

assertEquals("denominator", expected.getMessage()); }

}

23

Page 24: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Test de Colecciones Las colecciones se comparan solas, no recorra todos los elementos comparandolos. Tenga en cuenta que:

Investigar http://www.GBase.sourceforce.com , hay APIs para esto.

Test de Objetos que crean otros objetos

Investigar http://www.easymock.org

Cómo probar un Singleto¿?

Cómo probar un Factory¿?

24

Page 25: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Verificación de comportamiento

Figura extraída de [1]

Realizamos chequeos (asserts) sobre puntos de observación insertados entre el SUT y el DOC a efectos de monitorear su interacción y medir los resultados esperados.

Verificación de estado

Figura extraída de [1]

Chequeos (asserts) después de ejecutarlo, directamente sobre los puntos de observación, sobre datos que los métodos del SUT devuelven.

25

Page 26: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Las Pruebas como criterio de diseño EJEMPLO Capa de persistencia de una aplicació entreprise

cd Persistencia

AbstractMapper

MapperConcreto

«interface»ProyectosFinder

ProyectoJdbcQueryBuilder

JdbcQueryBuilder

+ createPreparedStatementParameters(domainParameters :List, statementName :String) : List+ getSqlString(statementName :String) : String+ getSupportedStatements() : Map+ loadStatements(losStatements :Map) : void+ supportsStatement(statementName :String) : boolean

«interface»PreparedStatementBuilder

+ getPreparedStatementData(domainParameters :List, statementName :String) : PreparedStatementData

PreparedStatementData

JdbcQueryExecuter

+ executeQuery(qc :QueryCallback, preparedStatementData :PreparedStatementData) : Object

«interface»QueryCallback

+ doInQuery(result :int) : Object

Las clases en verde son las correspondientes al diseño original. Las restantes aparecen aplicando criterios de diseño basados en las pruebas.

26

Page 27: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Utilizando plugins TESTDOUBLE

⇒ TestStub

⇒ MockObject

⇒ TestSpy

⇒ FakeObject

⇒ TestSubclass

Creación y configuración Test Stubs y MockObjects necesitan la configuración de los valores a devolver y los valores esperados.

Fake Object y Spy Object no necesitan configuración.

Figura extraída de [1]

Instalación • Por inyección de dependencia

• Utilizando un Service Locator

27

Page 28: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Figura extraída de [1]

Instalación utilizando un Service Locator

cd Serv iceLocator

Registry

MapperConcreto

SpyProyectosDataMapperTestUnitOfWork

UnitOfWork

Proyecto

<?xml version="1.0" encoding="ISO-8859-1"?><configuracion><modofuncionamiento name="modoprueba" /><modoproduccion><mappers><mapper name="Proyecto" class="capaPersistencia.codigo.impl.ProyectosDataMapper" findStatement="SELECT * FROM Proyecto WHERE IdProyecto = ?" ......</mappers></modoproduccion><modoprueba><mappers><mapper name="ProyectoSpy" class="capaPersistencia.codigo.impl.SpyProyectosDataMapper" findStatement="SELECT * .......

</modoprueba></configuracion>

«access»find, create

obtenido, (nuevo, modificado, borrado)

esperado, adaptar

Ej. Esquema utilizado en los ejemplos

28

Page 29: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

MockObject Ejemplo

Capa de persistencia de una aplicación enterprise

Figura extraída de [1]

Dinámica del test utilizando MockObject

cd PruebasResultSet

DataMapperProyectoTest

+ doLoad(ResultSet, Integer) : DomainObject

AbstractMapper

MapperConcreto

MockSingleRowResultSet

ProyectoTestResultSetOjectMapperProyecto

+ testNewProyecto() : void+ setUp() : void+ tearDown() : void

UnitOfWork

Registry

«instantiate»

«instantiate»

obtenido

«instantiate»

esperado

«instantiate»

setUp/tearDown

setUp/tearDown

Ejemplo: Prueba de la conversión de datos, atributos de objetos a campos de ResultSet

29

Page 30: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Subclases

Figura extraída de [1]

Dinámica del test utilizando clases derivadas del SUT

cd PruebasStatements

AbstractMapper

MapperConcreto

TestPreparedStatementMapperProyecto

+ testUpdateStatement() : void+ testFindPreparedStatement() : void

ProyectoJdbcQueryBuilder

ListToFind DataMapperProyectoTest_2

+ getAtributosAsList(DomainObject) : List

Proyecto

ListToUpdate

UnitOfWork Registry

obtenido

«instantiate»

esperado

«instantiate»

esperado

parametersAsToStatement

obtenido

createPreparedStatementParameters domainParameters

domainObject

«instantiate»

esperado

«access»

«instantiate»

getAtributosAsList

setUp / tearDown

setUp / tearDown

Ejemplo: Prueba de los strings asociados a los comandos de SQL

30

Page 31: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

SpyObject

Figura extraída de [1]

Dinámica del test utilizando SpyObject

31

Page 32: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

cd PruebasSpy

Si no se piden proveedores ->getCountInvocacionesProveedores = 0Al hacer getProveedores -> getCountInvocacionesProveedores = 1

Al no salvarlo, si igual descripcion -> viene del cahe

SpyProyectosDataMapper

- countInvocacionesProveedoresLazy: int- idInvocacionesProveedoresLazy: Vector

+ loadProveedores(int) : List+ getCountInvocacionesProveedores() : int+ getIdInvocacionesProvedores() : Vector

AbstractMapper

MapperConcretoRegistryUnitOfWork

TestDataMapperProyecto

+ testIdentityMap() : void+ testLazyLoadProveedores() : void+ testLazyLoadCliente() : void

Proyecto

Proyecto

«access»

find

setUp / tearDown setup / tearDown

esperado , setDescripcion

obtenido, getDescripcion

Ejemplo: Prueba del comportamiento del Identity Map (cache)

32

Page 33: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

cd PruebasUoW

TestUnitOfWork

+ testTransaccion() : void

RegistryUnitOfWork

SpyProyectosDataMapper

- countInvocacionesProveedoresLazy: int- idInvocacionesProveedoresLazy: Vector- objetoEstadoPersistencia: Map<Integer, String>

+ loadProveedores(int) : List+ getCountInvocacionesProveedores() : int+ getIdInvocacionesProvedores() : Vector+ insert(DomainObject) : void+ update(DomainObject) : void+ delete(DomainObject) : void

AbstractMapper

MapperConcreto

Proyecto

Proyecto

Proyecto

«access»find, create

esperado, save

esperado, adaptar

esperado, borrar

obtenido, (nuevo, modificado, borrado)

Ejemplo: Prueba de la dinámica de la UnitOfWork.

33

Page 34: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

FakeObject

Figura extraída de [1]

Dinámica del test utilizando Fake Object

cd PruebasFake

FakeAdminCliente

- clientes: Map<String, ClienteDTO>

+ init() : void

AdminClienteFactoryPresentacion

«interface»IAdminCliente

BrowserWatir

«instantiate»

Ejemplo: Prueba de presentación y comunicación con el cliente.

34

Page 35: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Pruebas con bases de datos Ver DBUnit

35

Page 36: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Organización de los tests de un proyecto ESTRATEGIAS

1. TestClass por clase

2. TestClass por funcionalidad

3. TestClass por condición

TestClass por clase

Figura extraída de [1]

36

Page 37: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

TestClass por funcionalidad

Figura extraída de [1]

TestClass por condicón de prueba

37

Page 38: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Figura extraída de [1]

38

Page 39: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Herramientas

PRUEBAS DE LAS DISTINTAS CAPAS

cd ICPruebas

Pruebas de DBHerramientas: DBUnit

Prueba de Acceso al NegocioHerramientas: JUnit, FakeObject

Prueba de PresentaciónHerramientas: JUnit, ServletUnit

Prueba de Reglas de NegocioHerramientas: JUnit

Prueba con y sin la DBHerramientas: JUnit, MockObject, SpyObject

Web Browser

Web Server

Negocio PersistenciaApp Server

DB

Prueba de ClienteHerramientas: TestWatir

FRAMEWORKS

JUnit Pruebas genéricas

Escrito en Java

Sitio: http://www.junit.org/

ServletUnit Pruebas de capa de presentación

Escrito en Java

Emula en forma simplificada un Java web sever

Sitio: http://httpunit.sourceforge.net/doc/servletunit-intro.html

HttpUnit Pruebas de conectividad y cliente

Emula un web browser

Necesita un web server para funcionar

Sitio: http://httpunit.sourceforge.net/

39

Page 40: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Watir Pruebas de interacción entre el web browser y el web server

Instancia un web browser (Windows Internet Browser)

Necesita un web server para funcionar

Sitio: http://wiki.openqa.org/display/WTR/Tutorial

40

Page 41: Pruebas de Softwarematerias.fi.uba.ar/7548/Pruebas de Software -xUnit.pdf · Condiciones (test fixture): todo lo que se nesecita previamente para ejecutar los tests. Datos externos,

PRUEBAS DE SOFTWARE de tipo xUnit

Referencias

1. xUnit Test Patterns: Refactoring Test Code, Gerard Meszaros, Addison-Wesley, 2007.

2. JUnit Recipes - Practical Methods for Programmer Testing, J.B. Rainsberger

with contributions by Scott Stirling, Manning, 2005.

3. The Craft of Software Testing,Brian Marick , PH, 1995.

4. The Art of Software Testing (2nd edition), Glenford J. Myers, John Wiley & Sons, Inc, 2004.

5. Code Complete (2nd edition), Steve McConnell, Microsoft Press, 1993.

6. A Practical Guide to Testing Object – Oriented Software, John McGregor, David Sykes, Addison Wesley, 2001.

7. Systematic Software Testing, Rick D. Craig, Stefan P. Jaskiel, Artech House

Publishers, 2002.

41