JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

588 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-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

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

  • Be the first to like this

No Downloads
Views
Total views
588
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

JUG Summer Camp - Une nouvelle vision des tests avec Arquillian

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

×