Ce diaporama a bien été signalé.
Le téléchargement de votre SlideShare est en cours. ×

Formation Gratuite Total Tests par les experts Java Ippon

Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Prochain SlideShare
Tests Logiciel
Tests Logiciel
Chargement dans…3
×

Consultez-les par la suite

1 sur 163 Publicité

Formation Gratuite Total Tests par les experts Java Ippon

Télécharger pour lire hors ligne

Garantissez la qualité des vos applications par des tests efficaces : unitaire, d'intégration, de performance... Apprenez à mettre en oeuvre un harnais de tests complet et efficace avec Junit, AssertJ, Mockito, Spring Test, Arquillian, ... et assimilez les concepts du TDD et du BDD, illustré avec Cucumber. La formation Total Test Training ira encore plus loin en vous présentant l'utilisation de Sonar et le rôle des tests dans un système d'intégration continue. Enfin, les aspects liés à la mesure de la performance (instrumentation avec Metric et stress test avec JMeter et Gatling) et à l'optimisation ciblée vous permettront d'être en mesure de produire un code "propre", protégé des risques de regressions.

Garantissez la qualité des vos applications par des tests efficaces : unitaire, d'intégration, de performance... Apprenez à mettre en oeuvre un harnais de tests complet et efficace avec Junit, AssertJ, Mockito, Spring Test, Arquillian, ... et assimilez les concepts du TDD et du BDD, illustré avec Cucumber. La formation Total Test Training ira encore plus loin en vous présentant l'utilisation de Sonar et le rôle des tests dans un système d'intégration continue. Enfin, les aspects liés à la mesure de la performance (instrumentation avec Metric et stress test avec JMeter et Gatling) et à l'optimisation ciblée vous permettront d'être en mesure de produire un code "propre", protégé des risques de regressions.

Publicité
Publicité

Plus De Contenu Connexe

Diaporamas pour vous (20)

Similaire à Formation Gratuite Total Tests par les experts Java Ippon (20)

Publicité

Plus par Ippon (20)

Publicité

Formation Gratuite Total Tests par les experts Java Ippon

  1. 1. Formation « Total Tests »
  2. 2. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Licence ● Cette formation vous est fournie sous licence Creative Commons Attribution- NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) ● Vous êtes libres de : – copier, distribuer et communiquer le matériel par tous moyens et sous tous formats ● Selon les conditions suivantes : – Attribution : Vous devez créditer l'Oeuvre, intégrer un lien vers la licence et indiquer si des modifications ont été effectuées à l'Oeuvre. Vous devez indiquer ces informations par tous les moyens possibles mais vous ne pouvez pas suggérer que l'Offrant vous soutient ou soutient la façon dont vous avez utilisé son Oeuvre. – Pas d’Utilisation Commerciale : Vous n'êtes pas autoriser à faire un usage commercial de cette Oeuvre, tout ou partie du matériel la composant. – Pas de modifications : Dans le cas où vous effectuez un remix, que vous transformez, ou créez à partir du matériel composant l'Oeuvre originale, vous n'êtes pas autorisé à distribuer ou mettre à disposition l'Oeuvre modifiée. http://creativecommons.org/licenses/by-nc-nd/4.0/deed.fr
  3. 3. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Sommaire ● Jour 1 – Garantir la qualité de son code avec les tests (5h) ● Introduction aux tests ● Les stubs ● Les mocks ● Les assertions ● Les tests d'intégration ● Le TDD / le BDD ● TP 1 : exercice sur le TDD/BDD ● TP 2 : utilisation des stubs/mocks/tests d'intégration – Sonar, tests automatisés et couverture de test (2h) ● L'outillage ● TP : installation de Sonar et analyse d'un projet
  4. 4. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Sommaire ● Jour 2 – Les tests de performance (2,5h) ● Problèmes habituels de performance ● Gatling vs JMeter ● Monitoring et profiling ● TP : Réalisation d'un plan de test et découverte de 3 problèmes classiques – Les tests fonctionnels « classiques » (2,5h) ● Présentation de Selenium ● TP : Réalisation d'un plan de test avec Selenium – Les tests fonctionnels « modernes » (2h) ● Présentation d'AngularJS, Karma et phantom.js ● TP : Réalisation d'un test avec Karma
  5. 5. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Objectifs ● Comprendre l'intérêt d'une méthodologie pilotée par les tests ● Comprendre les différents types de tests : stubs, mocks, tests d'intégration, etc... ● Connaître les principales APIs ● Avoir une vue d'ensemble des pratiques et outils disponibles
  6. 6. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Installation des TPs ● L'installation des TPs nécessite de télécharger des dépendances Maven – A la racine des TPs, lisez le fichier README – Exécutez « mvn dependency:go-offline » pour tout télécharger (cela va prendre du temps) – Exécutez « mvn clean compile » ● Les TPs sont tous de la même forme – Un projet « exercice » avec à la racine un fichier README vous expliquant l'exercice à réaliser – Un projet « solution » avec la solution – Vous pouvez tricher en faisant un « diff » des deux projets
  7. 7. Jour 1 : garantir la qualité de son code
  8. 8. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Pourquoi faire des tests ? ● Les tests permettent – D'éviter les bugs – D'avoir le courage de refactorer – De mieux coder ● Et surtout ils facilitent la maintenance – Plus vous voyez un bug tardivement, plus il vous coûtera cher – Sur la durée, faire des tests doit coûter moins cher que de ne pas en faire !
  9. 9. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Objectifs des tests ● Les tests doivent couvrir un maximum de lignes de code de l’application – Il ne s’agit pas de tout tester, mais de bien tester les lignes importantes – Si une méthode utilise des branchements conditionnels, il faut plusieurs tests pour valider tous les cas possibles ● Ces tests doivent être rapides et automatisés
  10. 10. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Tests unitaires contre tests d’intégration ● Il y a deux types de tests – Test d’un composant unique (métier ou technique), en isolation du reste des autres composants : ce sont les tests unitaires ● Cela exclut l’utilisation de Spring, Hibernate, etc – Test d’un ensemble de composants dans un environnement comparable à la production : ce sont les tests d’intégration ● Cela inclut l’utilisation de Spring, etc, sans doute avec une configuration d’infrastructure spécifique ● Les tests unitaires et les tests d’intégration ne sont pas exclusifs : il faut utiliser les deux conjointement pour bien tester
  11. 11. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Tests unitaires ● Les tests unitaires permettent de tester une méthode ou une classe en isolation du reste de l’application – D'où le succès des architectures basées sur Spring ● IoC : les composants n'ont pas de lien « en dur » les uns vers les autres ● AOP : une seule fonctionnalité par méthode. Par exemple, pas de code technique gérant la sécurité ou les transactions ● Une méthode = une fonctionnalité
  12. 12. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Exemple de test «simple» ● JUnit permet de lancer facilement toutes les méthodes marquées @Test – Maven les lance ensuite dans sa phase «test» – On utilise des assertions pour valider – Astuce : les imports statiques permettent d’utiliser directement les méthodes JUnit dans la classe à tester @Test public void testEquals() { Todo todo1 = new Todo(); todo1.setTodoId("001"); Todo todo2 = new Todo(); todo2.setTodoId("001"); assertEquals(todo1, todo2); Todo todo3 = new Todo(); todo3.setTodoId("003"); assertNotSame(todo1, todo3); }
  13. 13. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Les assertions ● Les assertions servent à valider une instance d'objet ou une valeur ● Par exemple, on va valider que le prénom de l'utilisateur est bien « John » ● JUnit fournit des assertions de base (égalité, erreur, etc...) ● Mais pour réaliser facilement des assertions complexes, mieux vaut s'équiper d'un outillage spécialisé – Hamcrest, FEST-Assert, AssertJ
  14. 14. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Quelques exemples d'assertions ● Ces assertions sont fournies par JUnit – assertEquals – assertSame – assertTrue – assertNotNull – fail assertEquals(expected, printedCart);
  15. 15. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Hamcrest ● La librairie la plus ancienne, encore très populaire ● Permet d'ajouter des « Matchers » ● Plus riche que les « assertEquals » de JUnit – Teste des String, Collections, nombres, JavaBeans, ou même equals et toString – Simple à étendre, pour créer vos propres « Matchers » métier assertThat(expectedPrice, comparesEqualTo(shoppingCart.getNetPrice()));
  16. 16. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr FEST-Assert ● Se veut être un successeur de Hamcrest, mais n'est plus activement développé aujourd'hui ● Permet de faire le même type de tests, mais avec une API « fluent » – Plus simple à coder avec son IDE (auto- complétion) – Vous pouvez enchaîner les assertions assertThat(shoppingCart.getNetPrice()) .isEqualByComparingTo(expectedPrice);
  17. 17. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr AssertJ ● La librairie la plus récente, et actuellement la plus populaire ● C'est donc notre recommandation ● Fork de FEST-Assert, auquel il ressemble beaucoup assertThat(shoppingCart.getGrossPrice()) .isEqualByComparingTo(expectedPrice);
  18. 18. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Exemples avec AssertJ ● Test de la taille d'une collection ● Test de la présence d'une instance dans la collection ● Enchaînement d'assertions assertThat(userRepository.findAll()).contains(joh n); assertThat(userRepository.findAll()) .hasSize(2) .contains(john); assertThat(userRepository.findAll()).hasSize(2) ;
  19. 19. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Les fixtures ● Il est fréquent d'avoir plusieurs tests qui utilisent le même ensemble d'objets – Créer des variables de classe (communes pour tous les tests) – Annoter une méthode @Before pour initialiser les variables – Annoter une méthode @After si vous voulez nettoyer des ressources après un test
  20. 20. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Exemple de fixture @Before public void setup() { User user = new User(); user.setLogin("user"); user.setFirstName("John"); user.setLastName("Testeur"); user.setPassword("test"); userRepository.saveAndFlush(user); }
  21. 21. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Les suites de tests ● Il est utile de regrouper ses tests : un ensemble de tests est une « Test Suite » – Permet de lancer tous les tests d'un coup depuis son IDE @RunWith(Suite.class) @Suite.SuiteClasses({ TestClass1.class, TestClass2.class}) public class TestSuite { // Vide }
  22. 22. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Les plugins dans les IDEs ● JUnit est intégré dans tous les IDEs majeurs (Eclipse, Netbeans, Intellij) – Un simple clic droit sur un test doit permettre de le lancer – Vous devez aussi avoir une interface graphique spécialisée pour voir l'évolution des tests – Vous devez pouvoir également débugger les tests directement, voire même les profiler ou avoir leur couverture de code
  23. 23. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Exemple ● Exemple d'un test en erreur dans IntelliJ IDEA :
  24. 24. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Pause ● Questions/Réponses sur les notions « de base » que nous venons de voir – Différence entre test unitaire et test d'intégration – Assertions – Utilisation dans un IDE
  25. 25. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Allons plus loin ● Pour l'instant nous n'avons vu que des tests simples – Avec des objets Java basiques ● Dans un « vrai » projet, vous allez avoir des dépendances plus complexes – Base de données, serveur JMS... ● Pour que votre test unitaire fonctionne, il va falloir « bouchonner » ces dépendances externes
  26. 26. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Astuce: comment injecter dans un champ ? (1/2) ● Pour tester unitairement un Bean Spring ayant des dépendances – Il ne faut pas utiliser Spring (sinon ce ne serait plus un test unitaire) – Il faut donc injecter manuellement ses dépendances ● Cette injection est évidente si l’on utilise l’injection par Setter ou par Constructeur ● Mais comment faire dans le cas d'une injection de dépendances dans un champ : @Inject private TodoListsService todoListsService
  27. 27. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Astuce: comment injecter dans un champ ? (2/2) ● Spring propose cet utilitaire : ● Il injecte une variable «todoListsService» dans le champ nommé «todoListsService» du Bean «todosService» ● Comme quoi les variables privées ne sont pas si privées que ça... ReflectionTestUtils.setField(todosService, "todoListsService", todoListsService);
  28. 28. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Des Stubs ou des Mocks ? ● En Français on confond les deux termes sous le nom de «bouchon» ● Ils sont nécessaires pour tester les dépendances, en particulier celles injectées par Spring ● Un Stub : une implémentation «vide» d’une dépendance – Exemple : pour un DAO, faire une implémentation qui n’accède pas en base de données mais renvoie toujours les mêmes valeurs ● Un Mock : une implémentation générée par une librairie spécialisée, qui la crée à la volée en fonction de l’interface à respecter. – Le mock vérifie également le comportement (nombre d'appels, etc) http://martinfowler.com/articles/mocksArentStubs.html
  29. 29. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Exemple de Stub ● Le Stub implémente la même interface que la dépendance injectée – Le Stub peut être une classe anonyme (exemple ci- dessous), pour éviter de créer trop de fichiers – Cela peut être également une vraie classe, afin de pouvoir le réutiliser sur plusieurs tests AccountService accountService = new AccountService(); accountService.setUserService(new UserService() { public User getCurrentUser() { User user = new User(); user.setLogin("test"); user.setFirstName("Julien"); return user; } }); assertEquals(accountService .getCurrentUser().getFirstName(), "julien");
  30. 30. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Choix d'un framework de Mock ● 3 frameworks principaux – EasyMock – JMock – Mockito ● Mockito est aujourd'hui le plus populaire – Syntaxe plus simple à apprendre – Plus concis ● EasyMock et Mockito peuvent être étendus avec PowerMock – Permet de mocker les méthodes statiques
  31. 31. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Utilisation de EasyMock ● EasyMock permet de générer automatiquement une implémentation à partir d’une interface ● Cette implémentation fonctionne ensuite comme un magnétoscope : – On liste les méthodes qui vont être appelées : ce sont les méthodes «expect()» – On dit ensuite à EasyMock que l’on va jouer ce scénario : c’est la méthode «replay()» – En fin de test, on demande à EasyMock de valider que le scénario s’est déroulé comme prévu : c’est la méthode «verify()»
  32. 32. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Exemple de Mock avec EasyMock@Test public void testCreateTodo() { TodosService todosService = EasyMock.createMock(TodosService.class); TodoListsService todoListsService = EasyMock.createMock(TodoListsService.class); EntityManager em = EasyMock.createMock(EntityManager.class); ReflectionTestUtils.setField(todosService, "em", em); ReflectionTestUtils.setField(todosService, "todoListsService", todoListsService); TodoList todoList = new TodoList(); todoList.setListId("001"); todoList.setName("Test Todo List"); ....
  33. 33. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Exemple de Mock avec EasyMock.... Todo todo = new Todo(); todo.setTodoId("0001"); todo.setDescription("Test description"); EasyMock.expect(todoListsService.findTodoList("001")) .andReturn(todoList); todoListsService.updateTodoList(todoList); em.persist(todo); EasyMock.replay(em); EasyMock.replay(todoListsService); todosService.createTodo("001", todo); assertNotNull(todo.getCreationDate()); assertEquals(todoList, todo.getTodoList()); assertTrue(todoList.getTodos().contains(todo)); EasyMock.verify(em); EasyMock.verify(todoListsService); }
  34. 34. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Utilisation de Mockito ● Mockito reprend les principes d'EasyMock – Génération d'un Mock à partir d'une classe ou interface – Ajout des comportements prévus – Vérification des attentes ● Son API est plus concise ● Il n'y a pas de phase de « replay »
  35. 35. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Exemple de Mock avec Mockito@Test public void testAdminAuthentication() { // mock repository UserRepository userRepository = mock(UserRepository.class); // stubbing when(userRepository.findOne("admin")).thenReturn(admin); // test UserDetails userDetails = userDetailsService.loadUserByUsername("admin"); // verification verify(userRepository).findOne("admin"); }
  36. 36. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Les mocks partiels avec Mockito● Vous pouvez créer un mock partiel (appelé « spy »), permettant de simuler uniquement une méthode d'un objet existant List list = new LinkedList(); List spy = spy(list); //optionally, you can stub out some methods: when(spy.size()).thenReturn(100); //using the spy calls real methods spy.add("one"); spy.add("two"); //prints "one" - the first element of a list System.out.println(spy.get(0)); //size() method was stubbed - 100 is printed System.out.println(spy.size());
  37. 37. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Les Mocks, en résumé ● Les Mocks sont aujourd’hui très populaires – Ils évitent d’avoir à coder des Stubs – Ils sont plus simples à maintenir que des Stubs : on ne code que les méthodes nécessaires au test – Il est plus simple de les faire changer de comportement – Ils permettent des tests plus puissants : on vérifie que les Mocks ont bien été appelés comme on l’a défini ● Ils restent plus complexes à coder ● Il faut utiliser une librairie spécialisée – Mockito : https://github.com/mockito/mockito – EasyMock : http://easymock.org/
  38. 38. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Les tests d'intégration ● On peut également lancer des tests d'intégration depuis JUnit – C'est un abus de langage de les appeler « tests unitaires » – Mais il est commun de les catégoriser comme des tests unitaires : ● Ils sont lancés depuis JUnit ● « mvn test » ne permet pas non plus de faire la différence
  39. 39. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Rappel ● Il y a deux types de tests – Test d’un composant unique (métier ou technique), en isolation du reste des autres composants : ce sont les tests unitaires ● Cela exclut l’utilisation de Spring, Hibernate, etc – Test d’un ensemble de composants dans un environnement comparable à la production : ce sont les tests d’intégration ● Cela inclut l’utilisation de Spring, JPA, etc... sans doute avec une configuration d’infrastructure spécifique ● Si vous utilisez Java EE, cela inclut votre serveur d'application
  40. 40. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Tests d'intégration avec Spring ● Les tests d’intégration incluent Spring – Avec un application context réduit, comprenant uniquement un ensemble de classes que l’on veut tester – Avec une configuration d’infrastructure spécifique : une base de données en mémoire ou une instance spécifique de la base de données cible ● Spring propose une intégration à JUnit qui simplifie grandement ce type de configuration – Les alternatives à Spring ont généralement des mécanismes similaires
  41. 41. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Support des tests d’intégration dans Spring ● SpringJUnit4ClassRunner permet d’intégrer Spring dans un test JUnit ● L’annotation @ContextConfiguration permet alors de localiser la configuration de Spring et de lancer l’application context ● On peut ainsi tester son application Spring avec JUnit, sans serveur d’applications – Toutes les fonctionnalités gérées par Spring fonctionnent de manière identique : connexion à la base de données, transactions... – On peut activer le debugging et le profiling, qui peuvent être faits directement dans l’IDE – C’est évidemment beaucoup plus rapide à exécuter que de déployer l’application sur un serveur d’applications
  42. 42. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Exemple de test d’intégration @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations= {"classpath*:/META-INF/application-context-test.xml"}) public class IntegrationTest { @Inject private UserService userService; @Test public void createUser() { User user = new User(); user.setLogin("test_user"); user.setFirstName("First name"); userService.createUser(user); User userFoundInDatabase = userService.findUser("test_user"); assertEquals("First name", userFoundInDatabase.getFirstName()); } }
  43. 43. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Utilisation avec Spring Boot ● Cette configuration est similaire avec Spring Boot, utilisant la configuration Java (souvent appelée JavaConfig), au lieu de la configuration XML « classique » @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @ActiveProfiles("dev") public class IntegrationTest { @Inject private UserService userService; @Test public void createUser() { ... } }
  44. 44. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Astuce 1 : lancer l’application context une seule fois ● Spring ne lance qu’un seul application context par classe – Toutes les méthodes de test d’une classe donnée utilisent la même instance ● Cela permet d'accélérer les tests : sinon on lancerait beaucoup plus d’application contexts ● Cela ne doit pas avoir d’autre impact – En effet, vos Beans sont sensés être thread safe
  45. 45. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Astuce 2 : rollback des transactions dans les tests d’intégration ● Par défaut, toute méthode de test annotée @Transactional va être rollbackée à la fin du test – Inutile de nettoyer la base de données après un test – Le test sera également plus performant – Le rollback n’est possible qu’à la condition que personne ne commite explicitement pendant le test ! @Test @Transactional public void createUser() { // Même code que précédemment }
  46. 46. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Les tests d'intégration avec Arquillian ● Dans un contexte Java EE, on ne peut pas simuler le serveur d'applications ● Arquillian est un framework permettant de déployer ses tests sur un serveur d'applications, et de les exécuter à distance – Les tests sont toujours réalisés avec JUnit – Ils sont lancés depuis votre IDE, ou depuis Maven – Mais ils vont s'exécuter sur un serveur distant ● Arquillian fonctionne aujourd'hui avec JBoss et Glassfish
  47. 47. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Exemple de test d'intégration avec Arquillian @RunWith(Arquillian.class) public class PersonRepositoryIT { @Inject private PersonRepository personRepository; // Code de gestion des déploiements et gestion des transactions // enlevés pour plus de lisibilité @Test public void shouldCreateAPerson() { Person person = new Person(); person.setLogin("test-login"); person.setFollowersCount(10); person.setAvatarUrl("http://avatar.url"); personRepository.createOrUpdatePerson(person); Person testPerson = personRepository.findPerson("test-login"); assertNotNull(testPerson); assertEquals(10, testPerson.getFollowersCount()); assertEquals("http://avatar.url", testPerson.getAvatarUrl()); assertEquals(0, testPerson.getRepositories().size()); }
  48. 48. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Arquillian dans la pratique ● Arquillian est un projet jeune, avec parfois des bugs ● Les tests d'intégration restent complexes – Il faut un serveur d'applications disponible en parallèle – Il faut gérer les transactions à la main (le code précédent a été simplifié à ce niveau) – Les tests sont plus lents car il faut déployer l'application sur le serveur ● Cependant le framework est très pratique – Permet de tester son application en conditions réelles – Evite d'avoir à coder des Mocks
  49. 49. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Validation des données en base● Pour les tests d'intégration nous avons besoin d'un jeu de données de test ● Dans les TPs nous utilisons Liquibase – Permet de créer le jeu de données ou de mettre à jour une base existante – Est indépendant de la base de données, on peut utiliser ● HSQLDB : base embarquée ● MySQL : plus lourd à mettre en place, mais plus simple à auditer en cas de problème ● Et nous validons les données via notre code
  50. 50. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr DBUnit ● DBUnit permet de charger les données en base – Plugin Maven pour faciliter son utilisation – Intégration Spring disponible ● DBUnit peut vérifier l'état des données en base suite au passage des tests – Automatique et plus complet que nos tests précédents – Plus lourd à exécuter – Maintenir les jeux de données en XML est fastidieux ● DBUnit contourne le cache de 2nd niveau – Ne pas oublier de l'invalider avant un test – Permet de tester les « vraies » données, et pas leur valeur en cache
  51. 51. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Pause ● Les stubs vs les mocks ● Mockito et EasyMock ● Les tests d'intégration ● Spring Test Context vs Arquillian
  52. 52. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Le TDD ● Test-Driven Development – Développement piloté par les tests ● Méthodologie de travail : – Ecrire un test avant d'écrire du code de production – N'écrire que le test nécessaire pour avoir une erreur (et les erreurs de compilation sont bien des erreurs) – N'écrire que le code de production nécessaire à corriger les erreurs
  53. 53. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Processus de développement
  54. 54. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Avantages du TDD ● Code plus simple à lire ● Code plus simple à débugger ● Meilleur design : le TDD vous pousse à mieux penser et mieux découper vos objets ● Revient en théorie moins cher : fait baisser les coûts de maintenance
  55. 55. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Problèmes liés au TDD ● C'est la même personne qui écrit les tests et le code ● Il faut maintenir les tests, ce qui peut être un travail à part entière ● Donne parfois un faux sentiment de sécurité
  56. 56. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Le BDD ● Behavior Driven Developement – Basé sur le TDD ● L'idée est de fournir des outils communs aux développeurs et aux fonctionnels, pour les faire travailler ensemble ● Permet de décrire ses tests en langage naturel, en décrivant un comportement attendu
  57. 57. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Exemple de scénario BDD Feature: Basic Arithmetic Background: A Calculator Given a calculator I just turned on Scenario: Addition When I add 4 and 5 Then the result is 9 Scenario: Another Addition When I add 4 and 7 Then the result is 11
  58. 58. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Cucumber ● Cucumber est un outil permettant de faire du BDD – http://cukes.info/ ● A la base c'est un outil Ruby, mais il existe une version Java – https://github.com/cucumber/cucumber-jvm ● C'est avec Cucumber que nous allons réaliser notre TP
  59. 59. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Comment lancer des tests ? ● Vous pouvez les lancer depuis Maven – « mvn test » – Attention, si vous distinguez certains types de tests (tests unitaires/tests d'interface graphique/tests de performance), Maven n'a pas cette finesse ● Vous devez pouvoir les lancer directement depuis votre IDE – Clic droit sur la classe → « Run as JUnit test... »
  60. 60. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP 1 « Ippon shopping » ● Bienvenue chez Ippon Shopping ! ● Nous allons réaliser trois « user stories » – Elles ont été définies par notre client – Les tests ont déjà été réalisés – A vous de coder chaque étape ● Le TP et les instructions à suivre sont disponibles dans le répertoire « 01_tdd/exercice »
  61. 61. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Correction TP 1 ● Qui a utilisé l'héritage pour gérer la TVA? Item FoodItem JudoItem
  62. 62. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Correction TP 1 ● Pourquoi utiliser des BigDecimal? (1/3+1/12+1/8+1/30) = 0.6083333332 (1/3+1/12+1/8) = 0.541666666666666 (1/3+1/12) = 0.416666666666666 Java double: 0.6083333333333333 0.5416666666666666 0.41666666666666663 Java float: 0.60833335 0.5416667 0.4166667
  63. 63. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP 2 ● Test d'intégration avec base de données embarquée ● Utilisation de AssertJ ● Utilisation de Mockito ● Utilisation conjointe de toutes ces techniques pour tester un service REST ● Le TP 2 est disponible dans « 02_mocks_vs_integration/exercice »
  64. 64. Jour 1 : Sonar, tests automatisés et couverture de tests
  65. 65. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Pourquoi faire des tests automatisés ? ● Les tests automatisés permettent de coder plus efficacement – L’automatisation permet un feedback rapide – Permet de corriger un bug juste après l’avoir causé – Facilite le débuggage ● Évite de polluer l’application et d’impacter les autres développeurs
  66. 66. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr L'intégration continue ● L’utilisation d’un serveur d’intégration continue est essentielle pour exécuter ces tests – Aujourd’hui il n’y a plus de question à se poser : utilisez Jenkins ! http://jenkins-ci.org/ ● Ce serveur vous alerte si les tests ne fonctionnent pas – Vous évite d’updater votre projet si un de vos collègues a commité des bugs
  67. 67. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Bonne pratique ● Toujours faire passer les tests unitaires avant de commiter – Renforce l’argument que ces tests doivent être rapides – Certains IDE proposent cette fonctionnalité (ils refusent de commiter s’il y a des erreurs) ● Certaines équipes vont plus loin : elles commitent dans un repository intermédiaire, et leur code n’est ensuite poussé dans le repository principal que si les tests passent
  68. 68. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr La couverture de code ● La mesure principale utilisée pour savoir si les tests permettent de bien vérifier la qualité d'un code ● Nécessite un outillage ● N'est qu'un indicateur : nous allons voir que ce n'est pas parfait...
  69. 69. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Que compte-t-on ? ● Les classes testées ● Les méthodes testées ● Les lignes testées
  70. 70. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Attention à tester les embranchements ● Un code qui contient des embranchements (if ... then … else) possède plusieurs « chemins d'exécution » qu'il faut tester – Plusieurs tests par méthode, si nécessaire – Tester les cas d'utilisation « rares » permet souvent de trouver des bugs que les testeurs humains ne voient pas ● N'oubliez pas non plus les blocs de gestion d'erreur (try … catch … finally)
  71. 71. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr L'outillage ● Il faut un outillage qui instrumente le code lors des tests, et qui est capable de générer un rapport – JaCoCo http://www.eclemma.org/jacoco/ – Cobertura : http://cobertura.sourceforge.net/ – Emma : http://emma.sourceforge.net/ – Atlassian Clover (payant) : http://www.atlassian.com/software/clover/overview
  72. 72. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Comment truquer le système ● Faites un test d'intégration qui lance une grande partie du système ● Appelez quelques méthodes qui ont beaucoup de lignes ● Appelez à la fin un assertTrue(true); La couverture de code n'est qu'un outil, rien ne vaut une vraie revue de code faite par un humain
  73. 73. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP 3 : analyse Sonar ● Installation de Sonar ● Analyse de notre projet dans Sonar ● Le TP 3 est disponible dans « 03_sonar/exercice »
  74. 74. Jour 2 : les tests de performance
  75. 75. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Pourquoi tester la performance ? ● Rassurer la DSI (POC - comparatifs) ● Prévenir les dérives du système en utilisation réelle : – Anticiper la montée en charge des utilisateurs – Anticiper l'augmentation du volume de données – Anticiper l'utilisation croissante de la bande passante – Dimensionner/valider l'infrastructure matérielle (suivi du taux d'occupation de la CPU / mémoire) ● Corriger les problèmes démontrés par les tests (on ne corrige pas « à l'aveugle ») : – Evite de monter une usine à gaz – Evite des dépenses inutiles, là où les problèmes ne sont pas importants
  76. 76. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Quand tester la performance ? ● Le plus tôt possible ● Lors de la phase de lancement, cela permet de : – Valider l'architecture – Définir la volumétrie des données ,leur répartition et leur typologie ● Lors de l'élaboration : – Mise au point des tests et élimination des risques ● En production : – Supervision / Monitoring
  77. 77. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Les types de test ● Tests standards : assurer le bon fonctionnement en condition normale ● Tests de stress et de montée en charge: valider la tenue et limites lors de pic de charge (mise en évidence des « dead locks » et fuites de mémoire) ● Tests d'endurance/robustesse : valider le fonctionnement sur la durée (dégradation des temps de réponses, fuite de mémoire ou blocage)
  78. 78. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Méthodologie ● Tester dans un environnement contrôlé (de préférence isolé) au plus proche de la production (environnement système et typologie des données). Préparation des tests Mesure des performances Identification, Analyse et priorisation Correction des problèmes Supervision
  79. 79. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Maîtrise de la mesure ● La mesure sert à l'identification d'un problème ● Et aussi à la validation de sa résolution : – Nécessite une comparaison par rapport à une baseline ● Cela implique : – Gel (peu envisageable) ou utilisation d'une branche – Enregistrement des conditions de mesure (version, état du matériel, environnement système, configuration, paramètres JVM…) – Jeux de données identique (dump), statistiques DB identiques – Maîtrise du niveau de LOG, aspects actifs (tissage léger) – Gestion de l'historique des mesures ; classification des résultats – Disponibilité / exclusivité : pas de pollution des tirs – Quels KPI : temps de réponse, nombres de requêtes, taux CPU, consommations mémoire, nombre de sessions/connections...
  80. 80. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Identification, analyse, priorisation ● L'identification des problèmes se fait suivant des SLA réalistes ● L'analyse ne doit pas être basée sur des hypothèses ou convictions mais sur des faits : les résultats. ● Les problèmes / goulets d'étranglement (bottlenecks) doivent être qualifiés en terme de: – Risques d’occurrences – Importance ( % temps consommé) – % de présence sur les différents scénarios – Corrélation avec la popularité du scénario – Coût de correction et tests ● Prioriser en agrégeant ces critères, par exemple: – Favoriser une correction à 2j/H pour 30 % de gain par rapport à une à 15j/H pour 50 % de gain – Favoriser une correction à 10j/H sur un goulet au niveau du framework représentant 10 % de gain sur 70 % des scénarios plutôt qu'une à 5j/H pour 80 % de gain sur un scénario mineur
  81. 81. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Jeux de données ● Travailler le plus tôt possible avec des données de production. Si les données sont sensibles, s'appuyer dessus en masquant / remplaçant les attributs sensibles ● Respecter la répartition réelle de la typologie des données (induit des chemins d'exécution différents ainsi que des plans d'exécutions de requêtes différents) ● Variabiliser les types d'utilisateurs injectés suivant différents profils ● Variabiliser les objets/ressources accédés afin de ne pas travailler exclusivement avec les caches
  82. 82. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Choix des scénarios ● Identifier les cas d'utilisations critiques : – Les plus fréquemment utilisés (s'aider de statistiques si déjà en production) – Les plus vitaux (la facturation, la paie...) – Les plus risqués (qui peuvent pénaliser le système dans son intégralité, ex. : les recherches) ● Choix de scénarios réalistes mais ne pas être perfectionniste (coûts inutiles) ● Attention au coût de maintien d'un nombre trop élevé de scénarios à faire évoluer en phase de développement ● Attention aux scénarios faisant appels à des services extérieurs (plus complexes) : risques de ban ou faux positifs
  83. 83. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Choix des outils ● Support de la technologie (http, https...) ● Type des licences (prix) ● Efficacité, fonctionnalités, limites ● Simplicité d'utilisation (industrialisation, langage de scripting, interface utilisateur...) ● Contraintes de sécurité (accès aux environnements - supervision)
  84. 84. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Outils de test : Loader/Injecteurs Les plus utilisés sur le marché : ● HP Load Runner (Commercial) ● JMeter (licence Apache) – Fondation Apache – Maturité – GUI facile à utiliser ● Gatling (licence Apache) – Scripts Scala, avec un DSL – Recorder réaliste, injection évoluée d'utilisateurs – Rapports détaillés
  85. 85. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Outils de profiling/monitoring Permettent de suivre l'activité des threads, consommation de la mémoire de la JVM, activité du GC etc... Outils gratuits : ● JConsole : inclus JDK5+, monitoring JMX uniquement ● JVisualVM : inclus JDK6+ : monitoring JMX + profiling basique mémoire/thread (présente des limites avec trop de threads) ● Java Mission Control : inclus JDK7+ monitoring JMX avancé, profiler (« flight recorder ») payant ● Netbeans profiler : nécessite l'IDE, profiler complet Outils payants : ● JProfiler : le plus complet (facilité de détection des deadlocks etc.) ● Yourkit : plus simple à utiliser et moins cher que JProfiler
  86. 86. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Limites physiques Suivre l'utilisation des ressources physiques : – Charge ou % d'utilisation des CPU – Mémoire physique – Usage disque I/O – Nombres de connections – Taux d'erreurs Outils : Perfmon, sysinternals, vmstats, iostat, sysstat, topas, top, nmon TraceRoute, netstat, tcpdump, wireshark...
  87. 87. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Outils de supervision ● Gratuits – Metrics + Graphite – Hyperic ● Commerciaux – Dynatrace – AppDynamics – New Relic
  88. 88. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Le monitoring avec JMX (1/2) ● Solution « standard » de monitoring en Java – Activation explicite dans la ligne de commandes en lançant votre application Java – Permet de voir de nombreuses informations ● Données du serveur d'applications : Tomcat, JBoss... ● Librairies exposant des MBeans : Hibernate, ehcache... ● Services de l'application elle-même : Beans Spring, EJBs... – Récupération des informations par le biais d'un des clients classiques ● JConsole ● VisualVM
  89. 89. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Monitorer JPA avec JMX (2/2) ● Informations à récolter avec JMX pour une application JPA – Statistiques sur l'utilisation du cache L2 ● Nombre de hits pour chaque cache ● Hits ratios pour chacun ● Nombre d’évictions du cache ● 60% de hits minimum pour justifier de l'utilisation d'un cache sur une entité JPA – Statistiques sur l'utilisation du pool de connexions ● Nombre de connexions maximal ● Nombre de connexions en attente (« idle ») ● Nombre de connexions supprimées ● Les statistiques Hibernate (3.x) – Très complètes – Sont désactivées par défaut <property name="hibernate.generate_statistics" value="true"/>
  90. 90. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr HEAPHEAP Sources potentielles de ralentissement CacheCache JDBC / Pool connexion ThreadsThreadsSessionsSessions CacheCache WebApp/EJBWebApp/EJB SessionSession PB INFRAPB INFRA GCGC ConcurrenceConcurrenceBandwidthBandwidth
  91. 91. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Suivi des métriques ● Notre application possède déjà une dépendance sur les librairies « Metrics » (http://metrics.codahale.com/) ● Afin d'effectuer un suivi sur l'ajout/suppression d'un item dans notre panier (parmi les actions les plus utilisées, donc à suivre de près), nous allons ajouter l'annotation @Timed sur l'ensemble des méthodes publiques de notre controller Rest gérant le panier. ● Lancez l'application à partir du main() de la classe fr.ippon.shopping.Application en précisant l'argument de JVM : -XX:MaxPermSize=256m ● Rendez-vous sur l'URL http://localhost:8080 et connectez-vous à l'aide du user/password : « admin/admin ». Le menu « metriques » est maintenant accessible dans « administration », le sélectionner. TP Optimiser « Ippon shopping »
  92. 92. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping »
  93. 93. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping »
  94. 94. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Suivi des métriques ● L'écran des métriques est personnalisable applicativement ; celui que nous visualisons est la vue par défaut. ● Il est possible de suivre l'état des bases et autres systèmes externes, l'état de la JVM, les statistiques sur les méthodes annotées, ainsi que les statistiques EhCache.
  95. 95. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Suivi des métriques ● Rendez-vous sur la page d'accueil, ajoutez, supprimez des produits, revenez sur les statistiques afin de visualiser le temps consommé et constater que la méthode addToCart() est consommatrice. Note : Pour ce TP, nous avons ajouté un morceau de code peu efficace, ce qui permet de visualiser aisément le problème. Cependant dans un contexte normal c'est en environnement de production après l'utilisation concurrente de l'application par de nombreux utilisateurs que l'on obtient des statistiques qui prennent du sens.
  96. 96. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Sampling avec VisualVM ● Lancez VisualVM présent dans JDK_HOME/bin/jvisualvm ● Dans la liste des VM locales, ouvrir celles correspondant à notre programme et se placer sur l'onglet « sampler », puis cliquez sur CPU. ● Dans notre exemple, on identifiera facilement le code consommateur. ● Supprimez les 4 lignes de code qui n'apportent rien et polluent le code. Relancez le serveur afin de constater la disparition du problème.
  97. 97. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Note : Ici un simple sampling permet l'analyse de notre problème, on privilégiera cette approche qui est plus légère et ne nécessite pas d'instrumentation du code, et qui est basée sur une multitude de thread dump « légers » et de stacktrace. Dans des situations moins évidentes, nous utiliserons le profiling qui lui nécessite une instrumentation, mais est beaucoup plus précis : il compte chaque invocation de méthodes. De plus, on peut démarrer et arrêter le profiling sur une période bien définie.
  98. 98. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Création d'un plan de test avec Gatling (Enregistrement – 1/2) Téléchargez Gatling sur http://gatling-tool.org/ et décompressez le. ● Afin d'appréhender plus facilement les scripts Scala, nous allons utiliser l'enregistreur (recorder) de Gatling qui se trouve dans /bin. ● Nous laissons tous les réglages par défaut de l'enregistreur, excepté le nom de classe que nous appelons AddSuppressItemsSimulation et nous le lançons à l'aide du bouton Start. Une fenêtre apparaît, elle contient la liste des URL accédées et permet d'ajouter un Tag utile pour ajouter un commentaire sur les différents scenarii (créez en un). L'enregistreur se comporte comme un proxy. ● Paramétrez donc le proxy du navigateur en spécifiant le port (8000 si vous l'avez laissé par défaut sur l'enregistreur).
  99. 99. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Création d'un plan de test avec Gatling (Enregistrement – 2/2) ● Déroulez le scénario suivant : ajoutez 2 produits dans un premier temps puis supprimez-les. Lorsque le scénario est terminé, effectuez un « stop and save » dans la fenêtre enregistreuse. ● Le script AddSuppressItemsSimulation.scalaAddSuppressItemsSimulation.scala est généré dans user- filessimulations. On remarque dans le fichier que le Tag a été ajouté sous forme de commentaire et que même les temps d'attente entre les actions ont été enregistrés (pause).
  100. 100. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Création d'un plan de test avec Gatling (Rejeux – 1/3) ● Le fichier Scala généré est directement exploitable en l'état. Lancez /bin/gatling.[bat| sh], choisissez le numéro correspondant à notre scénario et laissez le reste par défaut. ● Le fichier Scala est d'abord compilé puis l'exécution se lance. Une fois terminé, les résultats sont générés et visualisables via /results/[nomClasseScalaLowerCase] [DateExecution]/index.html
  101. 101. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Création d'un plan de test avec Gatling (Rejeux – 2/3) ● Dans notre cas nous n'avons qu'un seul utilisateur, les graphiques ne sont pas très parlants, nous allons modifier l'injecteur afin de simuler un nombre variant d'utilisateurs : setUp(scn.inject(nothingFor(1 seconds), atOnce(2 users), ramp(5 users) over (3 seconds), constantRate(7 usersPerSec) during (4 seconds), rampRate(15 usersPerSec) to(3 usersPerSec) during(2 seconds))) .protocols(httpProtocol)
  102. 102. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Création d'un plan de test avec Gatling (Rejeux – 3/3) ● Remplacez les RawFileBody() qui peuvent être simplifiés avec leurs contenus directement dans une String //.body(RawFileBody("RecordedSimulation_request_1.txt"))) .body(StringBody("7"))) ● Relancez et regardez de nouveau les résultats, observez le nombre de requêtes exécutées en fonction du nombre d'utilisateurs
  103. 103. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Création d'un plan de test avec Gatling (Paramétrage du scénario – 1/2) ● Pour tester les problèmes de locks, modifiez le script afin de stresser notre application : ● Nous allons répéter 80 fois notre scénario : modifiez le scénario scn (on donne un nom à notre scénario), en pensant à l'accolade fermante !
  104. 104. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Création d'un plan de test avec Gatling (Paramétrage du scénario – 2/2) ● Mettez en commentaire toutes les pauses (trop d'attente cacherait les problèmes inhérents aux locks) ● Remplacez l'injecteur afin d'ajouter plus d'utilisateurs (on évitera de trop en mettre, afin d'avoir un nombre de threads raisonnable au niveau du serveur, sinon VisualVM aura du mal à effectuer des dumps) :
  105. 105. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Création d'un plan de test avec Gatling (Exécution et interprétation – 1/2) ● Le but n'est pas d'obtenir des graphes mais d'observer un comportement avec un outil de profiling (ici VisualVM). ● Lancer gatling avec l'option -nr, afin de ne pas générer de rapport qui pourrait impacter nos mesures ; on précisera aussi directement la classe a exécuter : gatling.[bat|sh] -nr -s AddSuppressItemsSimulation ● Lancez VisualVM et placez-vous sur l'onglet « Thread ». Le test devrait mettre en avant de sérieux problèmes de locks (Monitor en rouge), s'ils sont assez nombreux cela garantira que la génération d'un dump de la stack trace des threads en cours d'exécution (bouton « Thread Dump »), contiendra l'état BLOCKED.
  106. 106. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Création d'un plan de test avec Gatling (Exécution et interprétation – 2/2) ● Attention si l'activité est trop grande (souvent dû à un trop grand nombre de threads au niveau du serveur), il se peut que le dump mette du temps à être généré... Copiez le contenu dans un éditeur afin de faire une recherche sur BLOCKED. ● La stacktrace devrait vous permettre d'identifier le code « synchronized » provocant le lock. Effectuez la correction et relancez le test pour voir si les problèmes sont résolus – il est probable que quelques monitors apparaissent encore mais l'erreur principale devrait être corrigée
  107. 107. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Création d'un plan de test avec Gatling (Fuites mémoire 1/4) ● L'objectif est de simuler de nombreux utilisateurs pendant une période plus longue afin de suivre l'évolution de la mémoire dans le temps. ● Nous allons voir les limites de VisualVM en tant qu'outil d'analyse. Pour cela la session utilisateur est de 30s ce qui permet de libérer les 'shopping cart' régulièrement et donc voir plus facilement s'il n'y a pas d'autres fuites mémoires sur notre application. Le problème a été exagéré afin de le constater plus aisément. ● Dans le fichier Scala, décommentez les pauses en mettant des temps de l'ordre du dixième de secondes. Redéfinir le repeat à un nombre réaliste (3). Enfin, injectez 3000 utilisateurs à raison d'une montée de 30 utilisateurs sur 3s toutes les secondes :
  108. 108. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Création d'un plan de test avec Gatling (Fuites mémoire 2/4) ● Lancez le test et laissez le tourner. Sur VisualVM, ouvrez l'onglet Monitor et observez l'activité du GC (Garbage Collector) dans la vue CPU ainsi que l'évolution de la « Heap ». ● Quand l'activité est importante, le GC n'arrive plus à libérer assez de ressources et la progression est linéaire, ce qui caractérise très souvent la fuite mémoire. ● Effectuez un profiling de la mémoire (il est conseillé de le lancer avant le démarrage du test). On constate que ce sont les chaînes de caractères qui ne cessent de croître, cependant VisualVM ne nous permet pas d'en déduire la classe qui en est à l'origine. Même si le problème portait sur un objet métier, nous aurions su quelle classe était concernée mais nous n'aurions pas deviné la source.
  109. 109. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Création d'un plan de test avec Gatling (Fuites mémoire 3/4) ● VisualVM étant insuffisant pour ce type de problème, nous nous tournerons vers des outils de profiling plus avancés. Nous vous recommandons en particulier : – JProfiler – Yourkit ● Dans le slide suivant, il nous est possible à l'aide de JProfiler et de sa vue « heap walker » de déduire que le code à l'origine du problème se trouve sur le champ static « stringList » du CartResource. Après analyse du code on voit que cette liste n'est pas utilisée (créée seulement pour l'exercice), nettoyez le code inutile et relancez le test pour constater que la fuite mémoire a disparu.
  110. 110. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Création d'un plan de test avec Gatling (Fuites mémoire 4/4)
  111. 111. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » [Optionnel] Création d'un plan de test avec JMeter (1/5) ● Téléchargez la dernière version de JMeter sur http://jmeter.apache.org/ et décompressez-la. ● Lancez /bin/jmeter.[bat|sh] en mode admin
  112. 112. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » [Optionnel] Création d'un plan de test avec JMeter (2/5) Configuration du plan de travail et de test : 1. Dans le plan de test : Ajouter->Moteurs d'utilisateurs->Groupe d'unités 2. Dans le plan de test : Ajouter->Configurations->Paramètre http par défaut 3. Dans le groupe d'unité : Ajouter->Contrôleur logique->Contrôleur enregistreur 4. Dans le groupe d'unité : Ajouter->Configurations->Gestionnaire de cookie http Ceci nous servira à nettoyer les cookies à chaque itération afin de ne pas réutiliser le même panier (penser à cocher la case) 5. Dans le plan de travail : Ajouter->Element hors test->Enregistreur script de test http(s) 1) Définir le port du proxy à 8000 2) Cocher la capture des entêtes, ajout d'assertion (facultatif), suivre les redirections 3) Ajouter le motif a exclure .*.gif 6. Dans l'enregistreur script : Ajouter->Récepteur->Arbre de résultat
  113. 113. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » [Optionnel] Création d'un plan de test avec JMeter (3/5) ● Lancez sur l'enregistreur et cliquez sur le bouton « Lancer » ; comme pour Gatling un proxy va être créé, il faudra donc activer l'utilisation d'un proxy au niveau du navigateur. ● Naviguez dans l'application. ● Dans l'arbre de résultat on voit l'ensemble des requêtes effectuées et leurs détails. ● Stoppez l'enregistreur et observez le contrôleur enregistreur, il contient automatiquement le jeu effectué (attention à bien nettoyer les actions intermédiaire parasites si vous êtes allé sur d'autres sites). ● Configurez les assertions générées sous les requêtes HTTP, cela permettra de s'assurer que les tirs de test ont bien le retour attendu et ainsi détecter un retour vide si le serveur est stoppé ou si le code a changé. Exemple d'assertion : motif « contient », motif à tester « grossPrice":80 »
  114. 114. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » [Optionnel] Création d'un plan de test avec JMeter (4/5) ● Ajoutez des récepteurs de type « Rapport consolidé » ou « Arbre de résultat » afin de suivre la bonne exécution de nos tests. ● Attention lors de la mesure, il est conseillé de désactiver les assertions ainsi que tous les récepteurs ou autres éléments qui ne servent qu'à l'interprétation des résultats ; ainsi la mesure ne sera pas parasitée et donc plus précise. ● Afin de lancer les tests il suffira d'appuyer sur le bouton « lecture » et tous les éléments non désactivés s'exécuteront. ● Si l'on veut modifier le nombre d'utilisateurs, la durée de montée en charge ou le nombre d'itérations (l'option infini peut être intéressante pour la détection de fuite mémoire), on peut l'effectuer sur le groupe d'unités. ● Maintenant on pourra regarder sur Metrics et suivre l'exécution du tir sur VisualVM, comme on l'a fait précédemment avec Gatling. ● Sur le slide suivant un exemple du plan de travail une fois créé et les tests prêts à être déroulés
  115. 115. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » [Optionnel] Création d'un plan de test avec JMeter (5/5) 
  116. 116. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Superviser à l'aide de JMX (1/5) ● Ajoutez une ressource JMX à l'aide des annotations @ManageResource et @ManageAttribute afin de lire le nom du dernier item ajouté par les utilisateurs dans un panier. ● Ouvrez JConsole et vérifiez que la ressource est bien affichée dans l'onglet « beans » et que sa valeur d'attribut évolue lorsque vous naviguez dans l'application
  117. 117. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Superviser à l'aide de JMX (2/5) ● Il est possible d'exporter des objets java sous forme de MBean, cependant attention à ne pas trop en mettre afin de ne pas dégrader les performances. ● Vous avez déjà à votre disposition des ressources fournies par la JVM, « Metrics », « hibernate » ou même votre serveur d'application ● Dans notre TP, un Decorateur dans la classe HibernateStatsConfiguration.java a été ajouté afin de palier l'absence de contrôleur JMX sur les statistiques Hibernate dans sa version 4.0 . ● Lancez le dernier scénario créé sur Gatling et constatez dans les statistiques Hibernate que le nombre d'entités chargées en base de données augmente rapidement
  118. 118. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Superviser à l'aide de JMX (3/5)
  119. 119. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Superviser à l'aide de JMX (4/5) ● Notre test insère des items dans un panier, nous allons donc regarder les statistiques au niveau de nos items ● Allez dans les opérations et utilisez getEntityStatisticsString() avec les classes fr.ippon.shopping.domain.Item et fr.ippon.shopping.domain.JudoItem – Seule la classe réellement instanciée (pas le parent) est comptabilisée – Le nombre de load() est trop important. Si l'on avait activé les logs (dans application.yml : jpa.show_sql=true), on aurait aussi pu constater de nombreux appels sur la même requête de type « select ».
  120. 120. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Superviser à l'aide de JMX (5/5) ● Ajoutez un cache en vous aidant des autres classes du domaine pour exemple. ● Relancer les tests et vérifiez maintenant que seul le cache de second niveau est sollicité ● Vérifiez l'état du cache grâce aux statistiques « Metrics »
  121. 121. Jour 2 : les tests fonctionnels avec Selenium
  122. 122. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Présentation de Selenium ● Selenium permet de réaliser des tests d'interface graphique – Selenium se charge de lancer un navigateur – D'effectuer des actions utilisateurs (clics...) – Et de contrôler le DOM suite à ces actions ● On teste ainsi l'interface « finale » proposée à l'utilisateur ● Son exécution peut être automatisée ● Il est relativement lourd à mettre en place et à utiliser
  123. 123. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Selenium vs HP Quality Center ● HP Quality Center est une suite complète, permettant en particulier de tester des interfaces Web ● Selenium est un concurrent Open Source – A l'origine, HP Quality Center = Mercury Quality Center – Le Selenium est un antidote à l'empoisonnement au Mercure... ● Les deux solutions sont excellentes, le principal élément discriminant est le prix
  124. 124. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Selenium IDE ● Pour démarrer facilement, il existe un plug-in Firefox nommé « Selenium IDE », qui enregistre les actions utilisateurs ● Il faut ensuite optimiser le code généré, et rajouter des assertions
  125. 125. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Selenium WebDriver ● WebDriver permet de directement contrôler un navigateur avec du code ● Il faut écrire les tests comme des tests unitaires normaux ● Il existe des bindings dans les principaux langages de programmation – Et en particulier en Java !
  126. 126. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Installation de WebDriver ● Le plus simple est d'ajouter les dépendances dans Maven – Utilisez le scope « test » pour ne pas polluer votre classpath <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-firefox-driver</artifactId> <version>2.39.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-support</artifactId> <version>2.39.0</version> <scope>test</scope> </dependency>
  127. 127. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Lancement des tests ● Attention lorsque vous lancez Selenium – Selenium est relativement lourd ● Il faut lancer le serveur d'applications ● Il faut lancer le navigateur – Vous ne pourrez peut-être pas le lancer sur votre serveur d'intégration continue ● Pas d'interface graphique ? Etudiez le plugin phantom.js ● Pour ces raisons, on le configure souvent dans un profil à part – Selenium n'est pas lancé par défaut quand on fait un « mvn test »
  128. 128. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Création du WebDriver ● Vous devez choisir une implémentation du WebDriver pour lancer vos tests @Before public void before() throws Throwable { FirefoxProfile profile = new FirefoxProfile(); profile.setPreference("browser.cache.disk.enable", false); profile.setPreference("browser.cache.memory.enable", false); profile.setPreference("browser.cache.offline.enable", false); profile.setPreference("network.http.use-cache", false); profile.setPreference("intl.accept_languages", "no,en-us,en"); driver = new FirefoxDriver(profile); driver.manage().deleteAllCookies(); }
  129. 129. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Sélectionner des éléments (1/2) ● Le principal travail avec Selenium est de trouver les bons éléments dans le DOM ● Vous pouvez les sélectionner par ID ou class – Le plus simple – Méthode familière aux utilisateurs de JQuery By.id("cartGrossPrice") By.cssSelector("#list-item .dropdown-menu li a")
  130. 130. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Sélectionner des éléments (2/2) ● Vous pouvez aussi utiliser une expression XPath ● Ou directement du JavaScript By.xpath("//input") ((JavascriptExecutor)driver) .executeScript("return $('.test')[0]");
  131. 131. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Attention aux IDs ! ● Le plus simple (et sûr!) reste l'utilisation des IDs ● Ce qui peut poser problème, car certains frameworks les génèrent – Ils fluctuent donc en fonction des développements, ce qui rend les tests impossibles – C'est le cas notamment avec JSF et avec GWT ● Il faut donc forcer ces IDs – Cela rajoute un coût supplémentaire aux développements – Complexe à rajouter après coup
  132. 132. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Remplir un formulaire ● Pour remplir un champ texte il faut le sélectionner et lui envoyer les caractères : ● Pour une drop-down list : ● Astuce pour les éléments codés en CSS WebElement element = driver.findElement(By.id("login-id")); element.sendKeys("jdoe"); Select select = new Select(driver.findElement(By.id("state"))); select.selectByIndex(1); element.sendKeys("and user", Keys.ARROW_DOWN);
  133. 133. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Gestion de la navigation ● Vous pouvez utiliser votre WebDriver pour aller sur une page : ● Et pour cliquer sur des éléments de cette page : driver.get("http://localhost:8080/shopping/index.html"); driver.findElement(By.id("add-product-2-btn")).click();
  134. 134. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Comment attendre ? ● L'un des problèmes principaux de Selenium est qu'il faut attendre – Attendre que le DOM se mette à jour – Attendre qu'une requête Ajax réponde ● Vous devez donc utiliser une méthode d'attente, avec un timeout (new WebDriverWait(driver, 10)) .until( ExpectedConditions .textToBePresentInElementLocated( By.id("cartGrossPrice"), "60")); (new WebDriverWait(driver, 10)) .until( ExpectedConditions.elementToBeClickable( By.id("delete-btn")));
  135. 135. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Utilisation des assertions ● Pour vérifier que les éléments de votre page sont corrects, utilisez les assertions normalement – Note : vous pouvez utiliser les librairies d'assertion, comme AssertJ assertThat(authentStatusElement.isDisplayed()) .isTrue(); assertThat(authentStatusElement.getText()) .isIn("Bienvenue", "Welcome");
  136. 136. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Copies d'écran ● Une fonctionnalité importante de Selenium est la création de copies d'écran – Le serveur d'intégration continue peut ainsi générer des copies d'écran des erreurs rencontrées – Utile en particulier si l'on teste avec plusieurs navigateurs différents File scrFile = ((TakesScreenshot)driver) .getScreenshotAs(OutputType.FILE); FileUtils.copyFile(scrFile, new File(System.getProperty("user.home") + "/selenium_screenshot.png"));
  137. 137. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr FluentLenium ● L'API officielle de Selenium n'est pas des plus simples ● FluentLenium est un projet Open Source vous proposant une API « fluente » – https://github.com/FluentLenium/FluentLenium ● Nous vous conseillons son utilisation – Plus simple à apprendre – Plus lisible – Moins de code à écrire
  138. 138. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Exemple de code FluentLenium public class BingTest extends FluentTest { @Test public void title_of_should_contain_search_query_name() { goTo("http://www.bing.com"); fill("#sb_form_q").with("FluentLenium"); submit("#sb_form_go"); assertThat(title()).contains("FluentLenium"); } }
  139. 139. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Une API plus simple ● Actions plus simples – click("#create-button") – clear("#firstName") – submit("#update") – executeScript("alert('Hello, world');") ● Enchaînements (API fluente) – fill("#firstName").with("test") ● Gestion des attentes simplifiée – Await().atMost(10, TimeUnit.SECONDS) .until("#ajaxElement").isPresent() ● API ressemblant à JQuery – $("#firstName").text("test") – $("#create-button").click()
  140. 140. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Le « Page Object Pattern » ● Une page est représentée par une classe – https://code.google.com/p/selenium/wiki/PageObjects – Avec des méthodes représentant les services de cette page – Ne fait pas d'assertions ou de vérification ● Facilite la réutilisation et la maintenance ● Facile à réaliser avec FluentLenium : public class LoginPage extends FluentPage { public String getUrl() { return "myCustomUrl"; } public void fillAndSubmitForm(String... paramsOrdered) { fill("input").with(paramsOrdered); click("#create-button"); } }
  141. 141. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP 5 : tests Selenium ● Création de deux jeux de tests Selenium ● Attention, pour ce TP, l'URL est : – http://localhost:8080/shopping ● Le TP 5 est disponible dans « 05_selenium/exercice »
  142. 142. Jour 2 : les tests d'interface avec Karma
  143. 143. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Introduction ● Karma permet de lancer des tests d'interface ● C'est un outil JavaScript, qui fonctionne avec Node.js – Cela permet de tester directement une application JavaScript – Il est particulièrement intéressant pour les nouvelles applications Web « riches », par exemple développées avec AngularJS ● Il fait partie des outils « modernes » de test, et est en particulier utilisé avec – Grunt, pour lancer les tests Karma – Jasmine, pour écrire les tests
  144. 144. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Que permet de faire Karma ? ● Karma permet de tester son code sur un ou plusieurs navigateurs – En particulier Phantom.js ● Les tests peuvent tourner de manière automatique – A chaque sauvegarde de fichier ● Karma permet de debugger les tests dans Chrome ou dans un IDE (s'il le supporte) ● Karma s'intègre dans un environnement d'intégration continue (Jenkins)
  145. 145. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Node.js ● Plateforme bâtie sur le moteur JavaScript V8 de Chrome ● Permet de développer des applications « full JavaScript » – Client & serveur codés en JavaScript ● Fournit un environnement complet et de nombreux outils utilisables pour des applications « classiques » développées en Java ● http://nodejs.org/
  146. 146. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Grunt ● Grunt permet de lancer des tâches ● Il propose ainsi d'automatiser – La minification du JavaScript et des images – La compilation de scripts SASS ou CoffeeScript – La validation du code JavaScript (JSHint) – Les tests avec Karma – Etc... ● L'écosystème proposé est énorme et facilite grandement le développement d'applications JavaScript ● http://gruntjs.com/
  147. 147. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Jasmine ● Jasmine est un framework de tests, à la manière de JUnit ● Il est écrit en JavaScript, et peut être utilisé avec Karma ● Il ne nécessite pas d'avoir accès au DOM – On teste les fonctions JavaScript – Plus adapté que Selenium (uniquement basé sur le DOM) pour des applications complexes
  148. 148. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Exemple de test Jasmine ● Une suite de tests est définie avec une fonction describe() ● Un test (« spec ») est défini par une fonction it() ● Une assertion est une fonction expect() describe("Une suite de tests est une fonction", function() { var a; it("Un test est une fonction", function() { a = true; expect(a).toBe(true); }); });
  149. 149. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Les matchers de Jasmine ● Jasmine propose également un système de matchers – Nous sommes donc dans un fonctionnement très proche de ce que nous avons vu en Java expect(a).toBe(b); expect(a).not.toBe(null); expect(a).toEqual(12); expect(message).toMatch(/bar/); expect(message).toMatch('bar'); expect(message).not.toMatch(/quux/); expect(a.foo).toBeDefined(); expect(a.bar).not.toBeDefined(); expect(a).toBeNull(); expect(foo).toBeTruthy(); // gestion des booléens expect(foo).not.toBeFalsy(); expect(a).toContain('bar'); expect(pi).toBeGreaterThan(e); expect(pi).toBeCloseTo(e, 0); // avec précision mathématique
  150. 150. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Les mocks avec Jasmine ● On peut également créer des mocks partiels (« spy ») – cf. le chapitre sur les mocks (c'est le même système qu'avec Mockito) – Permettent de simuler des appels REST describe("Un spy", function() { var foo, bar, fetchedBar; beforeEach(function() { foo = { setBar: function(value) { bar = value; }, getBar: function() { return bar; } }; spyOn(foo, 'getBar').andReturn(745); foo.setBar(123); fetchedBar = foo.getBar(); }); it("Retourne la valeur du mock", function() { expect(fetchedBar).toEqual(745); }); });
  151. 151. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Phantom.js ● Permet de lancer depuis une console, sans interface graphique, un moteur WebKit – WebKit est le moteur de rendu de Chrome et Safari ● C'est un moteur complet, pas un simulateur ● Scriptable via une API JavaScript ● Très performant – En particulier comparé à Selenium ● http://phantomjs.org/
  152. 152. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Yeoman ● Mettre en place toute la stack technique exposée ici peut être compliqué ● Yeoman propose un système de générateurs, vous permettant d'avoir un ensemble fonctionnel très rapidement ● Il existe de nombreux générateurs, en fonction de vos besoins ● http://yeoman.io/
  153. 153. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Installation ● Installez Node.js – http://nodejs.org/ – Node.js fournit NPM, un gestionnaire de package ● Vous pouvez ensuite installer Karma – Installation globale – Installation locale (dans ./node_modules/.bin) npm install -g karma npm install -g karma --save-dev
  154. 154. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Fichier de configuration de Karma● Les principales options du fichier de configuration sont – « basePath » : le chemin dans lequel Karma trouvera les fichiers – « files » : un tableau contenant tous les fichiers JavaScript à charger dans le navigateur – « autoWatch » : lance les tests automatiquement à chaque changement de fichier – « browsers » : un tableau contenant les navigateurs sur lesquels les tests doivent être exécutés
  155. 155. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Tests en continu ● Si vous mettez « autoWatch » à true, les tests seront exécutés automatiquement – Indépendant de votre IDE, fonctionne à la sauvegarde des fichiers – Très rapide et peut tourner en tâche de fond (en particulier avec Phantom.js) – C'est l'un des intérêts principaux de Karma, en particulier en comparaison à Selenium
  156. 156. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Debugging ● Vous pouvez débugger dans votre IDE (s' il le permet) ou directement dans Chrome : – Ajouter Chrome dans les navigateurs testés : – Ajouter un point d'arrêt dans le code : – Lancer Karma – Aller dans le navigateur Chrome ouvert, et rafraîchir la page browsers = ['Chrome']; it('spec', function() { debugger; });
  157. 157. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Quelques astuces ● La méthode « dump() » permet d'afficher des valeurs dans la console de Karma – « console.log() » fonctionne toujours, mais affiche dans la console du navigateur ● En cas d'échec, Karma vous donne le fichier et la ligne de l'erreur ● « autoWatchBatchDelay » permet de configurer combien de temps attendre avant de lancer les tests (pour qu'un ensemble de fichiers sauvés soient testés en batch) ● Vous pouvez configurer un proxy vers des serveurs distants, afin de faire des tests d'intégration (alternative aux Spies)
  158. 158. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Reporting avec Karma ● Karma propose un système de reporting ● Pour être utilisé avec Jenkins, il faut utiliser un reporting de type « JUnit » – Pour l'installer : – Pour l'utiliser, ajouter dans le fichier de configuration de Karma : npm install karma-junit-reporter --save-dev singleRun: true, reporters: ['dots', 'junit'], junitReporter: { OutputFile: 'test-results.xml' }
  159. 159. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP 6 : tests avec Karma ● Nous allons utiliser Karma, Jasmine, Phantom.js et Grunt pour tester notre interface graphique ● Il vous faudra pour cela installer Node.js ● Le TP 6 est disponible dans « 06_karma/exercice »
  160. 160. Conclusion

×