desarrollo de pruebas en entornos java ee

Post on 08-Jul-2015

1.878 Views

Category:

Software

6 Downloads

Preview:

Click to see full reader

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

MADRID · NOV 21-22 · 2014

Desarrollo de pruebas en Java EE

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

MADRID · NOV 21-22 · 2014

MADRID · NOV 21-22 · 2014

EPIC FAIL!

¡Espera! ¿Realmente las necesito?

main()

MADRID · NOV 21-22 · 2014

Si desarrollas pruebas en el código

PRUEBAS DRY, SOLID, ...

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.

MADRID · NOV 21-22 · 2014

Si, si… suena bien, pero...

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

Java developer

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

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

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?

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

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

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)

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

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"); }}

MADRID · NOV 21-22 · 2014

Arquillian: ejecución de test (IDE)

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

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

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.

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

MADRID · NOV 21-22 · 2014

Context and Dependency Injection

● @Inject

● @Produce

● @Alternative, @Specializes

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 { ... }

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;}

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)

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

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

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());

}

MADRID · NOV 21-22 · 2014

Estrategias de pruebas: End-to-End

Backing Bean

JPA

EJB

Arquillian Persistence Derby

Port MockJAX-WS

PruebaArquillian

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

MADRID · NOV 21-22 · 2014

Cobertura: JaCoCo

MADRID · NOV 21-22 · 2014

Cobertura: JaCoCo

MADRID · NOV 21-22 · 2014

Cobertura: Sonar

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

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! }:-)

top related