59
1 Alexis Hassler Une nouvelle vision des tests avec septembre 2013

JUG Summer Camp - 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-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

Citation preview

Page 1: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

1Alexis Hassler

Une nouvelle vision des tests avec

septembre 2013

Page 2: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

2

@AlexisHassler

Développeur, formateur Java

Indépendant

Co-leader du

Page 3: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

3

Tests

Unitaire Intégration

Page 4: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

4

Test unitaire

mockmock

mock

new ClassToBeTested()

mock

Page 5: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

5

ContainerEJB

Other BeanJPA

EntityManagerCDI

Bean

TransactionSécurité Intercepteurs

...

Intercepteurs Sécurité

BeanToBeDeployed

JMSQueue

Page 6: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

6

Container

Mock

Page 7: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

7

Container

Page 8: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

8

Mock

Page 9: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

9

Test d'intégration

EJBOther Bean

JPAEntityManager

CDIBean

TransactionSécurité Intercepteurs

...

Intercepteurs Sécurité

BeanToBeDeployed

JMSQueue

Page 10: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

10

Tests d'intégration JavaEE

Page 11: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

11

Tester des composants

pas des classes isolées

pas l'application complète

Page 12: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

12

Aucune référence au conteneur

dans les tests

Page 13: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

13

Weld

Tomcat

OpenWebBeans

OpenEJB

Jetty

Weblogic

Websphere

JBoss AS

Glassfish

TomEE

Page 14: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

14

RemoteManaged

Embedded

Page 15: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

15

TomcatJetty

Weblogic

Websphere

JBoss AS

Glassfish

TomEE

Page 16: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

16

Cloudbees

OpenShift

TomcatJetty

Weblogic

Websphere

JBoss AS

Glassfish

TomEE

Page 17: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

17

Mettre les

tests dans le conteneur plutôt que

gérer le conteneur dans les tests

Page 18: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

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

Page 19: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

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

Page 20: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

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

Page 21: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

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

Page 22: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

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

Page 23: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

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

Page 24: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

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

Page 25: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

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

Page 26: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

26

@RunWith(Arquillian.class)

@Deployment

@EJB, @Inject, @Resource

@Test

Page 27: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

27

Avec des données

Page 28: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

28

@PersistenceContextEntityManager em;

@ResourceUserTransaction tx;

Injection

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

Page 29: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

29

Transaction Extension

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

Page 30: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

30

Persistence Extension

@UsingDataSet("msg1.yml")

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

Page 31: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

31

Comme client

Page 32: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

32

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

Page 33: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

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

Page 34: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

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

Page 35: JUG Summer Camp - 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() { ... }}

HttpUnit, Selenium,...

Page 36: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

36

Drone

Page 37: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

37

Injection Selenium

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

@Drone WebDriver browser; ...

}

Page 38: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

38

Graphene

Page 39: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

39

Injection Page Object

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

@Page TalkPage talkPage; ...

}

Page 40: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

40

Warp

Page 41: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

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

}

Page 42: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

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

Page 43: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

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

Page 44: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

44

Warp.initiate( new Activity() {

...

})

.observe(...)

.inspect(...);

Activité Coté client

Page 45: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

45

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

.observe(...)

.inspect(...);

Page 46: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

46

Warp.initiate(...)

.observe(...)

.inspect( new Inspection() {

...

});

Inspection Coté serveur

Page 47: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

47

Warp.initiate(...)

.observe(...)

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

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

Page 48: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

48

Warp.initiate(...)

.observe( ...

)

.inspect(...);

Filtre des requêtes

Page 49: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

49

Warp.initiate(...)

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

.inspect(...);

Page 50: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

50

Au delà de Java EE

Page 51: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

51

Page 52: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

52

Page 53: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

53

GAE/

CapeDwarf

Page 54: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

54

Conclusion

Page 55: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

55

VRAISTESTS

Page 56: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

56

Mock

Mock

Page 57: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

57

Références

http://arquillian.org

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

http://slideshare.com/sewatech

Page 58: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

58

@AlexisHassler

http://alexis-hassler.com

[email protected]

http://sewatech.fr

Page 59: JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

59?