MarsJUG - Une nouvelle vision des tests avec Arquillian

660 views

Published on

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

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
660
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
11
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

MarsJUG - Une nouvelle vision des tests avec Arquillian

  1. 1. 1Alexis Hassler Une nouvelle vision des tests avec MarsJUG septembre 2013
  2. 2. 2 @AlexisHassler Développeur, formateur Java Indépendant Co-leader du
  3. 3. 3 Tests Unitaire Intégration
  4. 4. 4 Test unitaire mockmock mock new ClassToBeTested() mock
  5. 5. 5 Container EJB Other Bean JPA EntityManager CDI Bean Transaction Sécurité Intercepteurs ... Intercepteurs Sécurité BeanToBeDeployed JMS Queue
  6. 6. 6 Container Mock
  7. 7. 7 Mock
  8. 8. 8 Test d'intégration EJB Other Bean JPA EntityManager CDI Bean Transaction Sécurité Intercepteurs ... Intercepteurs Sécurité BeanToBeDeployed JMS Queue
  9. 9. 9 Tests d'intégration JavaEE
  10. 10. 10 Tester des composants pas des classes isolées pas l'application complète
  11. 11. 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); } }
  12. 12. 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
  13. 13. 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
  14. 14. 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
  15. 15. 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
  16. 16. 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
  17. 17. 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
  18. 18. 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
  19. 19. 19 Aucune référence au conteneur dans les tests
  20. 20. 20 Weld Tomcat OpenWebBeans OpenEJB Jetty Weblogic Websphere JBoss AS Glassfish TomEE
  21. 21. 21 Remote Managed Embedded
  22. 22. 22 TomcatJetty Weblogic Websphere JBoss AS Glassfish TomEE
  23. 23. 23 Cloudbees OpenShift TomcatJetty Weblogic Websphere JBoss AS Glassfish TomEE
  24. 24. 24 <dependency> <groupId> org.jboss.arquillian.container </groupId> <artifactId> arquillian-glassfish-embedded-3.1 </artifactId> </dependency> Container
  25. 25. 25 Mettre les tests dans le conteneur plutôt que gérer le conteneur dans les tests
  26. 26. 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
  27. 27. 27 @RunWith(Arquillian.class) @Deployment @EJB, @Inject, @Resource @Test
  28. 28. 28 Remote Managed Embedded
  29. 29. 29 Remote Managed Embedded Debug
  30. 30. 30 Avec des données
  31. 31. 31 @PersistenceContext EntityManager em; @Resource UserTransaction tx; Injection @Resource(mappedName="java:/jdbc/sample") DataSource ds;
  32. 32. 32 Transaction Extension @Transactional(TransactionMode.ROLLBACK) public class GreeterFromDatabaseIT { ... }
  33. 33. 33 Persistence Extension @UsingDataSet("msg1.yml") @ShouldMatchDataSet( value="expected-msg.yml", excludeColumns="id")
  34. 34. 34 Comme client
  35. 35. 35 @RunWith(Arquillian.class) public class GreeterArqIT { @Deployment(testable=false) public static Archive deploy() { ... } @ArquillianResource URL deploymentUrl; @Test public void should_request_get_result() { ... } }
  36. 36. 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
  37. 37. 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
  38. 38. 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,...
  39. 39. 39 Drone
  40. 40. 40 Injection Selenium @RunWith(Arquillian.class) public class GreeterArqIT { @ArquillianResource URL deploymentUrl; @Drone WebDriver browser; ... }
  41. 41. 41 Graphene
  42. 42. 42 Injection Page Object @RunWith(Arquillian.class) public class GreeterArqIT { @ArquillianResource URL deploymentUrl; @Page TalkPage talkPage; ... }
  43. 43. 43 Warp
  44. 44. 44 @RunWith(Arquillian.class) @WarpTest public 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(...); } }
  45. 45. 45 @RunWith(Arquillian.class) @WarpTest public 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
  46. 46. 46 @RunWith(Arquillian.class) @WarpTest public 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 phases Warp
  47. 47. 47 Warp.initiate( new Activity() { ... }) .observe(...) .inspect(...); Activité Coté client
  48. 48. 48 Warp.initiate( new Activity() { @Override public void perform() { talkPage.open(); } }) .observe(...) .inspect(...);
  49. 49. 49 Warp.initiate(...) .observe(...) .inspect( new Inspection() { ... }); Inspection Coté serveur
  50. 50. 50 Warp.initiate(...) .observe(...) .inspect( new Inspection() { @ArquillianResource HttpServletRequest request; @AfterServlet public void after() { assertEquals(...); } });
  51. 51. 51 Warp.initiate(...) .observe( ... ) .inspect(...); Filtre des requêtes
  52. 52. 52 Warp.initiate(...) .observe( HttpFilters.request() .uri() .contains("Hassler") ) .inspect(...);
  53. 53. 53 Au delà de Java EE
  54. 54. 54
  55. 55. 55
  56. 56. 56 GAE / CapeDwarf
  57. 57. 57 Conclusion
  58. 58. 58 VRAIS TESTS
  59. 59. 59 Mock Mock
  60. 60. 60 Références http://arquillian.org http://github.com/hasalex/arquillian-demo http://slideshare.com/sewatech
  61. 61. 61 @AlexisHassler http://alexis-hassler.com alexis.hassler@sewatech.fr http://sewatech.fr
  62. 62. 62 ?

×