desarrollo de pruebas en entornos java ee

34
MADRID · NOV 21-22 · 2014 Desarrollo de pruebas en Java EE José Manuel López Doña Arquitecto Software en Sopra @josemanlopez

Upload: jose-lopez

Post on 08-Jul-2015

1.876 views

Category:

Software


6 download

DESCRIPTION

Con el uso de CDI, para la inyección de dependencias, y la consolidación de la plataforma Arquillian, ya no hay excusas en la plataforma Java EE para el desarrollo de pruebas.

TRANSCRIPT

Page 1: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Desarrollo de pruebas en Java EE

José Manuel López DoñaArquitecto Software en Sopra@josemanlopez

Page 2: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Page 3: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

EPIC FAIL!

¡Espera! ¿Realmente las necesito?

main()

Page 4: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Si desarrollas pruebas en el código

PRUEBAS DRY, SOLID, ...

Page 5: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Requisitos previos, conocer bien:

● Las técnicas de desarrollo / frameworks / librerías que se estén utilizando

● Metodologías, conceptos y herramientas para desarrollar pruebas: TDD/BDD, Mocks, Stubs, Spies, Mockito, EasyMocks, etc.

Page 6: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Si, si… suena bien, pero...

Lo intenté y Java EE no me lo puso fácil

Java developer

Page 7: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

JNDICMPEJB2

StrutsHibernate Spring

JSFJPAEJB3

Seam CDI

Evolución del desarrollo en Java EE

Arquillian

Servicios de contenedor

ModeloPOJO

Inyección dedependencias

Integración frameworks

Facilidad enel desarrollo

Facilidad para probar

Fuente: http://www.slideshare.net/nukeevry1/arquillian

Page 8: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Tipos de pruebas (automáticas)

● Pruebas unitarias

● Pruebas de integración

○ Infraestructura (contenedor / servidor de aplicaciones)

○ Con otros sistemas/aplicaciones

● Pruebas funcionales

Page 9: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Java EE 7

CDI Extensions

Web Fragments

Servlet 3.1

JSF 2.2JSP 2.3EL 3.0

JAX-WS 2.2JAX-RS 2.0 JSON 1.0 WebSocket

1.0

CDI 1.1 Interceptors 1.0JTA 1.2

Managed Beans 1.0

JPA 2.1 JMS 2.0

Common Annotations 1.1 Concurrency 1.0

EJB 3.2

JCA 1.7 Batch 1.0

Bean

Val

idat

ions

1.1

¿MOCKS PARA TODO?

Page 10: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Arquitectura de pruebas en Java EE

Test CaseArquillian

Core + Extensions

ShrinkWrap

Unit Testing FrameworkJunit / TestNG

CoverageJaCoCo

Maven

ContainerTomEE Embedded

OpenWebBeans

Embedded DatabaseDerby

Page 11: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Arquillian: características

● Pruebas reales Java EE sin necesidad de mocks

● IDE friendly: ejecución de JUnit (o TestNG) desde el IDE o Maven

● Test enriquecidos: uso de características Java EE y extensiones

● Control del classpath: micro-despliegues en las pruebas

● Depuración de las pruebas desplegadas en servidor

● Contenedor agnóstico: múltiples adaptadores

Page 12: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Arquillian: configuración proyecto

● Incluir dependencias en fichero pom.xml○ Importar arquillian core, extensiones y runtimes

○ Crear maven profiles para tener diferentes runtimes

● Configurar el fichero arquillian.xml para sobrescribir valores por defecto (opcional)

Page 13: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Arquillian: desarrollo de pruebas

● Crear testcase con JUnit

● Incluir las clases bajo prueba usando ShrinkWrap

● Programar los métodos de pruebas @Test

● Ejecutar la prueba JUnit desde Maven / IDE

Page 14: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Arquillian: código ejemplo test@RunWith(Arquillian.class)public class GreeterTest {

@InjectGreeter greeter;

@Deployment (name="GreeterTest") public static JavaArchive createDeployment() { return ShrinkWrap.create(JavaArchive.class) .addClass(Greeter.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); }

@Test public void should_create_greeting() { Assert.fail("Not yet implemented"); }}

Page 15: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Arquillian: ejecución de test (IDE)

Page 16: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

.addPackages(true, Filters.exclude(".*Test.*|.*Mock.*"),"com.project");

Arquillian: ¿cuantas clases meto?

¿Todas? ¿Puedo?

● Tamaño JAR/WAR de pruebas

● Delimitar alcance de la pruebas

● Consideraciones rendimiento (p.e. contexto JPA)

● Si se usa embedded solo incluir clases aplicación

Page 17: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Arquillian: adaptadores runtimes

● Diferentes tipos:

○ Contenedor CDI (Weld, OpenWebBeans)

○ Contenedor EJB (OpenEJB 3.1)

○ Servidor de aplicaciones (Glassfish, JBoss, WAS, WebLogic,

TomEE, etc.)

● Diferentes formas de ejecución

○ Embedded

○ Managed

○ Remote

Page 18: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Arquillian: adaptadores runtimes

Runtime Tiempo total (seg.) Tiempo test (seg.)

glassfish-embedded 3.1.2.2 25 1,3

openwebbeans-embedded 1.1.6 5,8 0,03

jbossas-managed 7.1.1 20,4 0,3

wlp-managed 8.5.1.1 31,9 2,3

tomee-embedded 1.6.0 10,5 0,25

Resultados de ejecutar 10 veces una prueba de una inyección de un EJB con @Inject.

Page 19: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Arquillian modos de ejecución

● Servidor

● Cliente (@RunAsClient).

○ Ejemplo: WS REST (Arquillian REST Extension)

○ Ambos modos son posibles a la vez

Page 20: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Context and Dependency Injection

● @Inject

● @Produce

● @Alternative, @Specializes

Page 21: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Creación de alternativas (deploy)@Alternative@Specializes@Stereotype@Retention(RUNTIME)@Target(TYPE)public @interface Mock {}

<beans> <alternatives> <stereotype>org.mycompany.testing.Mock</stereotype> </alternatives></beans>

@Mockpublic class MockLoginService extends LoginService { ... }

Page 22: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Producción de alternativas (runtime)

@Mock @ProducesLoginService produceMockLoginService() {

LoginService login = mock(LoginService.class);

Mockito.when(login.validate(“user1”, “pass_invalid”) .thenReturn(RESULT.FAIL);

Mockito.when(login.validate(“user1”, “pass_valid”) .thenReturn(RESULT.SUCCESS);

return login;}

Page 23: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Algunos ejemplos de mocks

● FacesContext ➜ valores en la request/session

● Servicios Web (JAX-WS / JAX-RS)

○ Unmarshal (XML/JSON ➜ POJO) con JAXB/Jackson

public static <T> getObjectFromXML(String xmlPath, Class<T> className)

Page 24: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Arquillian Persistence Extension

● Gestión de transacciones

● Inserción de datos en base de datos

● Valida datos tras la prueba

● Se basa en DBUnit

Page 25: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Arquillian Persistence Extension

useraccount: - id: 1 firstname: John lastname: Smith username: doovde password: password - id: 2 firstname: Clark lastname: Kent username: superman password: kryptonite

users.yml

useraccount: - firstname: John lastname: Smith username: doovde password: password - firstname: Clark lastname: Kent username: superman password: LexLuthor

expected-users.yml

Page 26: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Arquillian Persistence Extension

@Test@UsingDataSet("datasets/users.yml")@ShouldMatchDataSet("datasets/expected-users.yml")public void should_change_user_password() throws Exception {

// givenString expectedPassword = "LexLuthor";UserAccount user = em.find(UserAccount.class, 2L); // whenuser.setPassword(expectedPassword);user = em.merge(user); // thenassertEquals(expectedPassword, user.getPassword());

}

Page 27: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Estrategias de pruebas: End-to-End

Backing Bean

JPA

EJB

Arquillian Persistence Derby

Port MockJAX-WS

PruebaArquillian

Page 28: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Estrategias de pruebas: Aisladas

Backing Bean JPAEJB

Arquillian Persistence Derby

Port MockJAX-WS

PruebaArquillian

JPA Mock EJB Mock

PruebaArquillian

PruebaArquillian

Page 29: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Cobertura: JaCoCo

Page 30: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Cobertura: JaCoCo

Page 31: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Cobertura: Sonar

Page 32: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Principales problemas encontrados

● Falta documentación de configuraciones avanzadas

● Diferentes versiones de Arquillian y extensions

● Diferente comportamiento según contenedores

Page 33: Desarrollo de pruebas en entornos Java EE

MADRID · NOV 21-22 · 2014

Algunas lecciones aprendidas

● Utilizar pruebas aisladas para TDD

● Uso de plugin failsafe para pruebas end-to-end

● Uso de @Inject en vez de @EJB

● Probar bien la arquitectura base de pruebas

● Elaborar una metodología de uso para desarrolladores

● Integración continua: ¡Rompe el build! }:-)