jug summer camp - une nouvelle vision des tests avec arquillian

Post on 13-Dec-2014

246 Views

Category:

Technology

4 Downloads

Preview:

Click to see full reader

DESCRIPTION

La réalisation de tests unitaires est fondamentale pour développer des logiciels de qualité. Cependant, tout miser sur eux est illusoire, car il faudra à un moment ou un autre vérifier que les composants interagissent convenablement et que leur intégration dans l'environnement cible fonctionne comme prévu. De plus, si l'application fournit une interface graphique, il faut vérifier si les interactions avec celle-ce sont corrects. Arquillian est une plateforme qui est en train de révolutionner la façon de développer les tests d'intégration et fonctionnels dans le monde Java. Et malgré des défauts de jeunesse, Arquillian permet de faire des tests automatisés de composants et d'applications Java, depuis la persistance jusqu'à l'interface graphique, en couvrant un périmètre qui dépasse largement son cadre initial qui était Java EE. Lors de cette session, vous apprendrez comment Arquillian est capable de tester : - l'intégration de composants Java EE, sur différents serveurs d'applications, - le code de persistance avec l'extension APE, - les interfaces Web, en facilitant l'utilisation de Selenium. Présentation au JUG Summer Camp 2013 : http://www.jugsummercamp.com/edition/4/presentation/1073

TRANSCRIPT

1Alexis Hassler

Une nouvelle vision des tests avec

septembre 2013

2

@AlexisHassler

Développeur, formateur Java

Indépendant

Co-leader du

3

Tests

Unitaire Intégration

4

Test unitaire

mockmock

mock

new ClassToBeTested()

mock

5

ContainerEJB

Other BeanJPA

EntityManagerCDI

Bean

TransactionSécurité Intercepteurs

...

Intercepteurs Sécurité

BeanToBeDeployed

JMSQueue

6

Container

Mock

7

Container

8

Mock

9

Test d'intégration

EJBOther Bean

JPAEntityManager

CDIBean

TransactionSécurité Intercepteurs

...

Intercepteurs Sécurité

BeanToBeDeployed

JMSQueue

10

Tests d'intégration JavaEE

11

Tester des composants

pas des classes isolées

pas l'application complète

12

Aucune référence au conteneur

dans les tests

13

Weld

Tomcat

OpenWebBeans

OpenEJB

Jetty

Weblogic

Websphere

JBoss AS

Glassfish

TomEE

14

RemoteManaged

Embedded

15

TomcatJetty

Weblogic

Websphere

JBoss AS

Glassfish

TomEE

16

Cloudbees

OpenShift

TomcatJetty

Weblogic

Websphere

JBoss AS

Glassfish

TomEE

17

Mettre les

tests dans le conteneur plutôt que

gérer le conteneur dans les tests

18

@RunWith(Arquillian.class)public class GreeterArqIT {

@Deployment public static Archive<?> deploy() { return ShrinkWrap.create(JavaArchive.class) .addClasses(Greeter.class, Location.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); }

@Inject Greeter greeter;

@Test public void testGreet() throws Exception { String who = "World"; String expected = "Hi " + who; String actual = greeter.greet(who);

assertEquals(expected, actual); }}

19

@RunWith(Arquillian.class)public class GreeterArqIT {

@Deployment public static Archive<?> deploy() { return ShrinkWrap.create(JavaArchive.class) .addClasses(Greeter.class, Location.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); }

@Inject Greeter greeter;

@Test public void testGreet() throws Exception { String who = "World"; String expected = "Hi " + who; String actual = greeter.greet(who);

assertEquals(expected, actual); }}

Runner JUnit

Méthode de test

20

@RunWith(Arquillian.class)public class GreeterArqIT {

@Deployment public static Archive<?> deploy() { return ShrinkWrap.create(JavaArchive.class) .addClasses(Greeter.class, Location.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); }

@Inject Greeter greeter;

@Test public void testGreet() throws Exception { String who = "World"; String expected = "Hi " + who; String actual = greeter.greet(who);

assertEquals(expected, actual); }}

Injection de dépendance

21

@RunWith(Arquillian.class)public class GreeterArqIT {

@Deployment public static Archive<?> deploy() { return ShrinkWrap.create(JavaArchive.class) .addClasses(Greeter.class, Location.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); }

@Inject Greeter greeter;

@Test public void testGreet() throws Exception { String who = "World"; String expected = "Hi " + who; String actual = greeter.greet(who);

assertEquals(expected, actual); }}

Déploiement du composant

22

@Deployment public static Archive<?> deploy() {

return ShrinkWrap.create(JavaArchive.class)

.addClasses(Greeter.class, Location.class)

.addAsResource("config.properties")

.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");

}

1. Créer l'archive

23

@Deployment public static Archive<?> deploy() {

return ShrinkWrap.create(JavaArchive.class)

.addClasses(Greeter.class, Location.class)

.addAsResource("config.properties")

.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");

}

2. Ajouter du contenu

24

@Deployment public static Archive<?> deploy() {

return ShrinkWrap.create(JavaArchive.class)

.addClasses(Greeter.class, Location.class)

.addAsResource("config.properties")

.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");

}

3. Déployer

25

@Deployment public static Archive<?> deploy() {

File[] requiredLibraries = Maven.resolver() .loadPomFromFile("pom.xml") .importRuntimeAndTestDependencies() .resolve() .withTransitivity() .asFile();

return ShrinkWrap .create(WebArchive.class) ... .addAsLibraries(requiredLibraries); }

Résolution de dépendances Maven

26

@RunWith(Arquillian.class)

@Deployment

@EJB, @Inject, @Resource

@Test

27

Avec des données

28

@PersistenceContextEntityManager em;

@ResourceUserTransaction tx;

Injection

@Resource(mappedName="java:/jdbc/sample")DataSource ds;

29

Transaction Extension

@Transactional(TransactionMode.ROLLBACK)public class GreeterFromDatabaseIT { ...}

30

Persistence Extension

@UsingDataSet("msg1.yml")

@ShouldMatchDataSet( value="expected-msg.yml", excludeColumns="id")

31

Comme client

32

@RunWith(Arquillian.class)public class GreeterArqIT { @Deployment(testable=false) public static Archive deploy() { ... } @ArquillianResource URL deploymentUrl; @Test public void should_request_get_result() { ... }}

33

@RunWith(Arquillian.class)public class GreeterArqIT { @Deployment(testable=false) public static Archive deploy() { ... } @ArquillianResource URL deploymentUrl; @Test public void should_request_get_result() { ... }}

Déploiement SANS les tests

34

@RunWith(Arquillian.class)public class GreeterArqIT { @Deployment(testable=false) public static Archive deploy() { ... } @ArquillianResource URL deploymentUrl; @Test public void should_request_get_result() { ... }}

Injection de l'URL du déploiement

35

@RunWith(Arquillian.class)public class GreeterArqIT { @Deployment(testable=false) public static Archive deploy() { ... } @ArquillianResource URL deploymentUrl; @Test public void should_request_get_result() { ... }}

HttpUnit, Selenium,...

36

Drone

37

Injection Selenium

@RunWith(Arquillian.class)public class GreeterArqIT { @ArquillianResource URL deploymentUrl;

@Drone WebDriver browser; ...

}

38

Graphene

39

Injection Page Object

@RunWith(Arquillian.class)public class GreeterArqIT { @ArquillianResource URL deploymentUrl;

@Page TalkPage talkPage; ...

}

40

Warp

41

@RunWith(Arquillian.class) @WarpTestpublic class TalkPageWarpIT {

@Deployment(testable = true) public static WebArchive deploy() { return Deployments.prepareDeployment(); }

@ArquillianResource URL baseUrl; @Drone WebDriver browser; @Page TalkPage talkPage;

@Test @RunAsClient public void should_my_talks_have_2_lines() { Warp.initiate(...) .observe(...) .inspect(...); }

}

42

@RunWith(Arquillian.class) @WarpTestpublic class TalkPageWarpIT {

@Deployment(testable = true) public static WebArchive deploy() { return Deployments.prepareDeployment(); }

@ArquillianResource URL baseUrl; @Drone WebDriver browser; @Page TalkPage talkPage;

@Test @RunAsClient public void should_my_talks_have_2_lines() { Warp.initiate(...) .observe(...) .inspect(...); }

}

Drone & Graphene

43

@RunWith(Arquillian.class) @WarpTestpublic class TalkPageWarpIT {

@Deployment(testable = true) public static WebArchive deploy() { return Deployments.prepareDeployment(); }

@ArquillianResource URL baseUrl; @Drone WebDriver browser; @Page TalkPage talkPage;

@Test @RunAsClient public void should_my_talks_have_2_lines() { Warp.initiate(...) .observe(...) .inspect(...); }

}

3 phasesWarp

44

Warp.initiate( new Activity() {

...

})

.observe(...)

.inspect(...);

Activité Coté client

45

Warp.initiate( new Activity() { @Override public void perform() { talkPage.open(); } })

.observe(...)

.inspect(...);

46

Warp.initiate(...)

.observe(...)

.inspect( new Inspection() {

...

});

Inspection Coté serveur

47

Warp.initiate(...)

.observe(...)

.inspect( new Inspection() { @ArquillianResource HttpServletRequest request;

@AfterServlet public void after() { assertEquals(...); } });

48

Warp.initiate(...)

.observe( ...

)

.inspect(...);

Filtre des requêtes

49

Warp.initiate(...)

.observe( HttpFilters.request() .uri() .contains("Hassler") )

.inspect(...);

50

Au delà de Java EE

51

52

53

GAE/

CapeDwarf

54

Conclusion

55

VRAISTESTS

56

Mock

Mock

57

Références

http://arquillian.org

http://github.com/hasalex/arquillian-demo

http://slideshare.com/sewatech

58

@AlexisHassler

http://alexis-hassler.com

alexis.hassler@sewatech.fr

http://sewatech.fr

59?

top related