163
Formation « Total Tests »

Formation Gratuite Total Tests par les experts Java Ippon

Embed Size (px)

DESCRIPTION

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.

Citation preview

Page 1: Formation Gratuite Total Tests par les experts Java Ippon

Formation « Total Tests »

Page 2: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 3: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 4: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 5: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 6: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 7: Formation Gratuite Total Tests par les experts Java Ippon

Jour 1 : garantir la qualité de son code

Page 8: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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 !

Page 9: Formation Gratuite Total Tests par les experts Java Ippon
Page 10: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 11: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 12: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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é

Page 13: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

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

Page 14: Formation Gratuite Total Tests par les experts Java Ippon
Page 15: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 16: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

Quelques exemples d'assertions● Ces assertions sont fournies par JUnit

– assertEquals

– assertSame

– assertTrue

– assertNotNull

– fail

assertEquals(expected, printedCart);

Page 17: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 18: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 19: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 20: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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(john);

assertThat(userRepository.findAll()) .hasSize(2) .contains(john);

assertThat(userRepository.findAll()).hasSize(2);

Page 21: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 22: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

Exemple de fixture

@Beforepublic void setup() { User user = new User(); user.setLogin("user"); user.setFirstName("John"); user.setLastName("Testeur"); user.setPassword("test"); userRepository.saveAndFlush(user);}

Page 23: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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}

Page 24: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 25: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

Exemple● Exemple d'un test en erreur dans IntelliJ

IDEA :

Page 26: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 27: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 28: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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 :

@Injectprivate TodoListsService todoListsService

Page 29: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 30: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 31: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 32: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 33: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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()»

Page 34: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

Exemple de Mock avec EasyMock

@Testpublic 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");

....

Page 35: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 36: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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 »

Page 37: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

Exemple de Mock avec Mockito

@Testpublic 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");

}

Page 38: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

Les mocks partiels avec Mockito

● Vous pouvez créer un mock partiel (appelé « spy »), permettant de simuler uniquement une méthode d'un objet existantList list = new LinkedList();List spy = spy(list);

//optionally, you can stub out some methods:when(spy.size()).thenReturn(100);

//using the spy calls real methodsspy.add("one");spy.add("two");

//prints "one" - the first element of a listSystem.out.println(spy.get(0));

//size() method was stubbed - 100 is printedSystem.out.println(spy.size());

Page 39: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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/

Page 40: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 41: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 42: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 43: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 44: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 45: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 46: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 47: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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@Transactionalpublic void createUser() { // Même code que précédemment}

Page 48: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 49: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 50: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 51: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 52: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 53: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

Pause● Les stubs vs les mocks● Mockito et EasyMock● Les tests d'intégration● Spring Test Context vs Arquillian

Page 54: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 55: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

Processus de développement

Page 56: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 57: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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é

Page 58: Formation Gratuite Total Tests par les experts Java Ippon
Page 59: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 60: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 61: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 62: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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... »

Page 63: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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 »

Page 64: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

Correction TP 1● Qui a utilisé l'héritage pour gérer la TVA?

Item

FoodItem JudoItem

Page 65: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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.60833333333333330.54166666666666660.41666666666666663

Java float:

0.608333350.54166670.4166667

Page 66: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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 »

Page 67: Formation Gratuite Total Tests par les experts Java Ippon

Jour 1 : Sonar, tests automatisés et couverture de tests

Page 68: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 69: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 70: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 71: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 72: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

Que compte-t-on ?● Les classes testées● Les méthodes testées● Les lignes testées

Page 73: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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)

Page 74: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 75: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 76: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

TP 3 : analyse Sonar● Installation de Sonar● Analyse de notre projet dans Sonar● Le TP 3 est disponible dans

« 03_sonar/exercice »

Page 77: Formation Gratuite Total Tests par les experts Java Ippon

Jour 2 : les tests de performance

Page 78: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 79: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 80: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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)

Page 81: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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 desproblèmes

Supervision

Page 82: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 83: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 84: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 85: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 86: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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)

Page 87: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

Outils de test : Loader/InjecteursLes 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

Page 88: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

Outils de profiling/monitoringPermettent 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

Page 89: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

Limites physiquesSuivre 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...

Page 90: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

Outils de supervision● Gratuits

– Metrics + Graphite

– Hyperic● Commerciaux

– Dynatrace

– AppDynamics

– New Relic

Page 91: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 92: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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"/>

Page 93: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

HEAPHEAP

Sources potentielles de ralentissement

CacheCache

JDBC / Pool connexion

ThreadsThreadsSessionsSessions

CacheCache

WebApp/EJBWebApp/EJB

SessionSession

PB INFRAPB INFRA

GCGC

ConcurrenceConcurrenceBandwidthBandwidth

Page 94: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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 »

Page 95: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

TP Optimiser « Ippon shopping »

Page 96: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

TP Optimiser « Ippon shopping »

Page 97: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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.

Page 98: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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.

Page 99: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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.

Page 100: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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.

Page 101: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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).

Page 102: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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-files\simulations.

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).

Page 103: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 104: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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)

Page 105: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 106: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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 !

Page 107: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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) :

Page 108: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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.

Page 109: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 110: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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 :

Page 111: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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.

Page 112: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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.

Page 113: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

TP Optimiser « Ippon shopping »Création d'un plan de test avec Gatling (Fuites mémoire 4/4)

Page 114: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 115: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 116: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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 »

Page 117: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 118: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

TP Optimiser « Ippon shopping »[Optionnel] Création d'un plan de test avec JMeter (5/5) 

Page 119: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 120: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 121: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

TP Optimiser « Ippon shopping »Superviser à l'aide de JMX (3/5)

Page 122: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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 ».

Page 123: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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 »

Page 124: Formation Gratuite Total Tests par les experts Java Ippon

Jour 2 : les tests fonctionnels avec Selenium

Page 125: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 126: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 127: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 128: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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 !

Page 129: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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>

Page 130: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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 »

Page 131: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

Création du WebDriver● Vous devez choisir une implémentation du

WebDriver pour lancer vos tests

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

Page 132: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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")

Page 133: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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]");

Page 134: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 135: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 136: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 137: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 138: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 139: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 140: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 141: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 142: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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()

Page 143: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 144: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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 »

Page 145: Formation Gratuite Total Tests par les experts Java Ippon

Jour 2 : les tests d'interface avec Karma

Page 146: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 147: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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)

Page 148: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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/

Page 149: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

Grunt● Grunt permet de lancer des tâches

● Il propose ainsi d'automatiser

– La minification du JavaScript et desimages

– 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/

Page 150: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 151: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 152: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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éensexpect(foo).not.toBeFalsy();expect(a).toContain('bar');expect(pi).toBeGreaterThan(e);expect(pi).toBeCloseTo(e, 0); // avec précision mathématique

Page 153: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 154: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

Phantom.js● Permet de lancer depuis une console,

sans interface graphique, un moteurWebKit– 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/

Page 155: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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'avoirun ensemble fonctionnel très rapidement

● Il existe de nombreux générateurs, en fonction de vos besoins

● http://yeoman.io/

Page 156: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 157: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 158: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 159: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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

Page 160: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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)

Page 161: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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'}

Page 162: Formation Gratuite Total Tests par les experts Java Ippon

@ippontech www.ippon.fr blog.ippon.fr www.atomes.com [email protected]

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 »

Page 163: Formation Gratuite Total Tests par les experts Java Ippon

Conclusion