62
1 Alexis Hassler Une nouvelle vision des tests avec MarsJUG septembre 2013

MarsJUG - Une nouvelle vision des tests avec Arquillian

Embed Size (px)

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-ci sont correctes. 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 verrez 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

Citation preview

Page 1: MarsJUG - Une nouvelle vision des tests avec Arquillian

1Alexis Hassler

Une nouvelle vision des tests avec

MarsJUGseptembre 2013

Page 2: MarsJUG - Une nouvelle vision des tests avec Arquillian

2

@AlexisHassler

Développeur, formateur Java

Indépendant

Co-leader du

Page 3: MarsJUG - Une nouvelle vision des tests avec Arquillian

3

Tests

Unitaire Intégration

Page 4: MarsJUG - Une nouvelle vision des tests avec Arquillian

4

Test unitaire

mockmock

mock

new ClassToBeTested()

mock

Page 5: MarsJUG - Une nouvelle vision des tests avec Arquillian

5

ContainerEJB

Other BeanJPA

EntityManagerCDI

Bean

TransactionSécurité Intercepteurs

...

Intercepteurs Sécurité

BeanToBeDeployed

JMSQueue

Page 6: MarsJUG - Une nouvelle vision des tests avec Arquillian

6

Container

Mock

Page 7: MarsJUG - Une nouvelle vision des tests avec Arquillian

7

Mock

Page 8: MarsJUG - Une nouvelle vision des tests avec Arquillian

8

Test d'intégration

EJBOther Bean

JPAEntityManager

CDIBean

TransactionSécurité Intercepteurs

...

Intercepteurs Sécurité

BeanToBeDeployed

JMSQueue

Page 9: MarsJUG - Une nouvelle vision des tests avec Arquillian

9

Tests d'intégration JavaEE

Page 10: MarsJUG - Une nouvelle vision des tests avec Arquillian

10

Tester des composants

pas des classes isolées

pas l'application complète

Page 11: MarsJUG - Une nouvelle vision des tests avec Arquillian

11

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

Page 12: MarsJUG - Une nouvelle vision des tests avec Arquillian

12

@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

Page 13: MarsJUG - Une nouvelle vision des tests avec Arquillian

13

@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

Page 14: MarsJUG - Une nouvelle vision des tests avec Arquillian

14

@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

Page 15: MarsJUG - Une nouvelle vision des tests avec Arquillian

15

@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

Page 16: MarsJUG - Une nouvelle vision des tests avec Arquillian

16

@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

Page 17: MarsJUG - Une nouvelle vision des tests avec Arquillian

17

@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

Page 18: MarsJUG - Une nouvelle vision des tests avec Arquillian

18

@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

Page 19: MarsJUG - Une nouvelle vision des tests avec Arquillian

19

Aucune référence au conteneur

dans les tests

Page 20: MarsJUG - Une nouvelle vision des tests avec Arquillian

20

Weld

Tomcat

OpenWebBeans

OpenEJB

Jetty

Weblogic

Websphere

JBoss AS

Glassfish

TomEE

Page 21: MarsJUG - Une nouvelle vision des tests avec Arquillian

21

RemoteManaged

Embedded

Page 22: MarsJUG - Une nouvelle vision des tests avec Arquillian

22

TomcatJetty

Weblogic

Websphere

JBoss AS

Glassfish

TomEE

Page 23: MarsJUG - Une nouvelle vision des tests avec Arquillian

23

Cloudbees

OpenShift

TomcatJetty

Weblogic

Websphere

JBoss AS

Glassfish

TomEE

Page 24: MarsJUG - Une nouvelle vision des tests avec Arquillian

24

<dependency> <groupId> org.jboss.arquillian.container </groupId> <artifactId> arquillian-glassfish-embedded-3.1 </artifactId></dependency>

Container

Page 25: MarsJUG - Une nouvelle vision des tests avec Arquillian

25

Mettre les

tests dans le conteneur plutôt que

gérer le conteneur dans les tests

Page 26: MarsJUG - Une nouvelle vision des tests avec Arquillian

26

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

arquillian-*.jar MyArquillianIT.class

Page 27: MarsJUG - Une nouvelle vision des tests avec Arquillian

27

@RunWith(Arquillian.class)

@Deployment

@EJB, @Inject, @Resource

@Test

Page 28: MarsJUG - Une nouvelle vision des tests avec Arquillian

28

RemoteManaged

Embedded

Page 29: MarsJUG - Une nouvelle vision des tests avec Arquillian

29

RemoteManaged

EmbeddedDebug

Page 30: MarsJUG - Une nouvelle vision des tests avec Arquillian

30

Avec des données

Page 31: MarsJUG - Une nouvelle vision des tests avec Arquillian

31

@PersistenceContextEntityManager em;

@ResourceUserTransaction tx;

Injection

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

Page 32: MarsJUG - Une nouvelle vision des tests avec Arquillian

32

Transaction Extension

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

Page 33: MarsJUG - Une nouvelle vision des tests avec Arquillian

33

Persistence Extension

@UsingDataSet("msg1.yml")

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

Page 34: MarsJUG - Une nouvelle vision des tests avec Arquillian

34

Comme client

Page 35: MarsJUG - Une nouvelle vision des tests avec Arquillian

35

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

Page 36: MarsJUG - Une nouvelle vision des tests avec Arquillian

36

@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

Page 37: MarsJUG - Une nouvelle vision des tests avec Arquillian

37

@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

Page 38: MarsJUG - Une nouvelle vision des tests avec Arquillian

38

@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,...

Page 39: MarsJUG - Une nouvelle vision des tests avec Arquillian

39

Drone

Page 40: MarsJUG - Une nouvelle vision des tests avec Arquillian

40

Injection Selenium

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

@Drone WebDriver browser; ...

}

Page 41: MarsJUG - Une nouvelle vision des tests avec Arquillian

41

Graphene

Page 42: MarsJUG - Une nouvelle vision des tests avec Arquillian

42

Injection Page Object

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

@Page TalkPage talkPage; ...

}

Page 43: MarsJUG - Une nouvelle vision des tests avec Arquillian

43

Warp

Page 44: MarsJUG - Une nouvelle vision des tests avec Arquillian

44

@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(...); }

}

Page 45: MarsJUG - Une nouvelle vision des tests avec Arquillian

45

@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

Page 46: MarsJUG - Une nouvelle vision des tests avec Arquillian

46

@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

Page 47: MarsJUG - Une nouvelle vision des tests avec Arquillian

47

Warp.initiate( new Activity() {

...

})

.observe(...)

.inspect(...);

Activité Coté client

Page 48: MarsJUG - Une nouvelle vision des tests avec Arquillian

48

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

.observe(...)

.inspect(...);

Page 49: MarsJUG - Une nouvelle vision des tests avec Arquillian

49

Warp.initiate(...)

.observe(...)

.inspect( new Inspection() {

...

});

Inspection Coté serveur

Page 50: MarsJUG - Une nouvelle vision des tests avec Arquillian

50

Warp.initiate(...)

.observe(...)

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

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

Page 51: MarsJUG - Une nouvelle vision des tests avec Arquillian

51

Warp.initiate(...)

.observe( ...

)

.inspect(...);

Filtre des requêtes

Page 52: MarsJUG - Une nouvelle vision des tests avec Arquillian

52

Warp.initiate(...)

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

.inspect(...);

Page 53: MarsJUG - Une nouvelle vision des tests avec Arquillian

53

Au delà de Java EE

Page 54: MarsJUG - Une nouvelle vision des tests avec Arquillian

54

Page 55: MarsJUG - Une nouvelle vision des tests avec Arquillian

55

Page 56: MarsJUG - Une nouvelle vision des tests avec Arquillian

56

GAE/

CapeDwarf

Page 57: MarsJUG - Une nouvelle vision des tests avec Arquillian

57

Conclusion

Page 58: MarsJUG - Une nouvelle vision des tests avec Arquillian

58

VRAISTESTS

Page 59: MarsJUG - Une nouvelle vision des tests avec Arquillian

59

Mock

Mock

Page 60: MarsJUG - Une nouvelle vision des tests avec Arquillian

60

Références

http://arquillian.org

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

http://slideshare.com/sewatech

Page 61: MarsJUG - Une nouvelle vision des tests avec Arquillian

61

@AlexisHassler

http://alexis-hassler.com

[email protected]

http://sewatech.fr

Page 62: MarsJUG - Une nouvelle vision des tests avec Arquillian

62?