SlideShare une entreprise Scribd logo
1  sur  163
Télécharger pour lire hors ligne
Formation « Total Tests »
@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
@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
@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
@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
@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
Jour 1 : garantir la qualité de son
code
@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 !
@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
@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
@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é
@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);
}
@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
@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);
@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()));
@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);
@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);
@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)
;
@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
@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);
}
@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
}
@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
@ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr
Exemple
● Exemple d'un test en erreur dans IntelliJ
IDEA :
@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
@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
@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
@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);
@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
@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");
@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
@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()»
@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");
....
@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);
}
@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 »
@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");
}
@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());
@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/
@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
@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
@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
@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
@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());
}
}
@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() {
...
}
}
@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
@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
}
@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
@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());
}
@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
@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
@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
@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
@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
@ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr
Processus de développement
@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
@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é
@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
@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
@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
@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... »
@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 »
@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
@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
@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 »
Jour 1 : Sonar, tests automatisés et
couverture de tests
@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
@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
@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
@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...
@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
@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)
@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
@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
@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 »
Jour 2 : les tests de performance
@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
@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
@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)
@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
@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...
@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
@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
@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
@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)
@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
@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
@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...
@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
@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
@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"/>
@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
@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 »
@ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr
TP Optimiser « Ippon shopping »
@ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr
TP Optimiser « Ippon shopping »
@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.
@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.
@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.
@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.
@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).
@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).
@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
@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)
@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
@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 !
@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) :
@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.
@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
@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 :
@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.
@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.
@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)
@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
@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
@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 »
@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
@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) 
@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
@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
@ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr
TP Optimiser « Ippon shopping »
Superviser à l'aide de JMX (3/5)
@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 ».
@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 »
Jour 2 : les tests fonctionnels avec
Selenium
@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
@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
@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
@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 !
@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>
@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 »
@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();
}
@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")
@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]");
@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
@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);
@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();
@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")));
@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");
@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"));
@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
@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");
}
}
@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()
@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");
}
}
@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 »
Jour 2 : les tests d'interface avec
Karma
@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
@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)
@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/
@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/
@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
@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);
});
});
@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
@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);
});
});
@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/
@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/
@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
@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
@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
@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;
});
@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)
@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'
}
@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 »
Conclusion

Contenu connexe

Tendances

Workshop spring session 2 - La persistance au sein des applications Java
Workshop spring   session 2 - La persistance au sein des applications JavaWorkshop spring   session 2 - La persistance au sein des applications Java
Workshop spring session 2 - La persistance au sein des applications JavaAntoine Rey
 
Les Streams de Java 8
Les Streams de Java 8Les Streams de Java 8
Les Streams de Java 8Antoine Rey
 
Tester unitairement une application java
Tester unitairement une application javaTester unitairement une application java
Tester unitairement une application javaAntoine Rey
 
Gitlab CI : Integration et Déploiement Continue
Gitlab CI : Integration et Déploiement ContinueGitlab CI : Integration et Déploiement Continue
Gitlab CI : Integration et Déploiement ContinueVincent Composieux
 
Formation GIT gratuite par ippon 2014
Formation GIT gratuite par ippon 2014Formation GIT gratuite par ippon 2014
Formation GIT gratuite par ippon 2014Ippon
 
Spring boot
Spring bootSpring boot
Spring bootsdeeg
 
DevOps avec Ansible et Docker
DevOps avec Ansible et DockerDevOps avec Ansible et Docker
DevOps avec Ansible et DockerStephane Manciot
 
Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...ENSET, Université Hassan II Casablanca
 
softCours design pattern m youssfi partie 9 creation des objets abstract fact...
softCours design pattern m youssfi partie 9 creation des objets abstract fact...softCours design pattern m youssfi partie 9 creation des objets abstract fact...
softCours design pattern m youssfi partie 9 creation des objets abstract fact...ENSET, Université Hassan II Casablanca
 
Appalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSPAppalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSPYouness Boukouchi
 

Tendances (20)

Workshop spring session 2 - La persistance au sein des applications Java
Workshop spring   session 2 - La persistance au sein des applications JavaWorkshop spring   session 2 - La persistance au sein des applications Java
Workshop spring session 2 - La persistance au sein des applications Java
 
Nouveautés de java 8
Nouveautés de java 8Nouveautés de java 8
Nouveautés de java 8
 
Polymorphisme, interface et classe abstraite
Polymorphisme, interface et classe abstraitePolymorphisme, interface et classe abstraite
Polymorphisme, interface et classe abstraite
 
Les Streams de Java 8
Les Streams de Java 8Les Streams de Java 8
Les Streams de Java 8
 
Tester unitairement une application java
Tester unitairement une application javaTester unitairement une application java
Tester unitairement une application java
 
Gitlab CI : Integration et Déploiement Continue
Gitlab CI : Integration et Déploiement ContinueGitlab CI : Integration et Déploiement Continue
Gitlab CI : Integration et Déploiement Continue
 
Formation GIT gratuite par ippon 2014
Formation GIT gratuite par ippon 2014Formation GIT gratuite par ippon 2014
Formation GIT gratuite par ippon 2014
 
Spring boot
Spring bootSpring boot
Spring boot
 
DevOps avec Ansible et Docker
DevOps avec Ansible et DockerDevOps avec Ansible et Docker
DevOps avec Ansible et Docker
 
Support programmation orientée aspect mohamed youssfi (aop)
Support programmation orientée aspect mohamed youssfi (aop)Support programmation orientée aspect mohamed youssfi (aop)
Support programmation orientée aspect mohamed youssfi (aop)
 
Test unitaires
Test unitairesTest unitaires
Test unitaires
 
Spring ioc
Spring iocSpring ioc
Spring ioc
 
Les collections en Java
Les collections en JavaLes collections en Java
Les collections en Java
 
Introduction to spring boot
Introduction to spring bootIntroduction to spring boot
Introduction to spring boot
 
Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...
 
JUnit Presentation
JUnit PresentationJUnit Presentation
JUnit Presentation
 
softCours design pattern m youssfi partie 9 creation des objets abstract fact...
softCours design pattern m youssfi partie 9 creation des objets abstract fact...softCours design pattern m youssfi partie 9 creation des objets abstract fact...
softCours design pattern m youssfi partie 9 creation des objets abstract fact...
 
Appalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSPAppalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSP
 
Rest Assured
Rest AssuredRest Assured
Rest Assured
 
Spring Boot RestApi.pptx
Spring Boot RestApi.pptxSpring Boot RestApi.pptx
Spring Boot RestApi.pptx
 

Similaire à Formation Gratuite Total Tests par les experts Java Ippon

testUnitaire (1).pptx
testUnitaire (1).pptxtestUnitaire (1).pptx
testUnitaire (1).pptxManalAg
 
Automatisation des tests - objectifs et concepts - partie 2
Automatisation des tests  - objectifs et concepts - partie 2Automatisation des tests  - objectifs et concepts - partie 2
Automatisation des tests - objectifs et concepts - partie 2Christophe Rochefolle
 
Intro sur les tests unitaires
Intro sur les tests unitairesIntro sur les tests unitaires
Intro sur les tests unitairesPHPPRO
 
Les cinq bonnes pratiques des Tests Unitaires dans un projet Agile
Les cinq bonnes pratiques des Tests Unitaires dans un projet AgileLes cinq bonnes pratiques des Tests Unitaires dans un projet Agile
Les cinq bonnes pratiques des Tests Unitaires dans un projet AgileDenis Voituron
 
Traits : de la théorie à la pratique
Traits : de la théorie à la pratiqueTraits : de la théorie à la pratique
Traits : de la théorie à la pratiqueFrederic Hardy
 
Automatisation des tests - objectifs et concepts - partie 1
Automatisation des tests  - objectifs et concepts - partie 1Automatisation des tests  - objectifs et concepts - partie 1
Automatisation des tests - objectifs et concepts - partie 1Christophe Rochefolle
 
PyConFR - testons en python
PyConFR - testons en pythonPyConFR - testons en python
PyConFR - testons en pythongburet
 
PHPTour Lyon 2014 - Conférence - Tests unitaires Je veux mes 80% de couvertur...
PHPTour Lyon 2014 - Conférence - Tests unitaires Je veux mes 80% de couvertur...PHPTour Lyon 2014 - Conférence - Tests unitaires Je veux mes 80% de couvertur...
PHPTour Lyon 2014 - Conférence - Tests unitaires Je veux mes 80% de couvertur...Cyrille Grandval
 
Meetup Python Nantes - les tests en python
Meetup Python Nantes - les tests en pythonMeetup Python Nantes - les tests en python
Meetup Python Nantes - les tests en pythonArthur Lutz
 
Cocoaheads Paris Nombembre Test unitaires
Cocoaheads Paris Nombembre Test unitairesCocoaheads Paris Nombembre Test unitaires
Cocoaheads Paris Nombembre Test unitairesCocoaHeads France
 
Formation Extreme Programming, Tests unitaires, travail collaboratif
Formation Extreme Programming, Tests unitaires, travail collaboratifFormation Extreme Programming, Tests unitaires, travail collaboratif
Formation Extreme Programming, Tests unitaires, travail collaboratifkemenaran
 
Performance ug#1
Performance ug#1Performance ug#1
Performance ug#1Marc Bojoly
 
Tests Dinterface SWT
Tests Dinterface SWTTests Dinterface SWT
Tests Dinterface SWTEric Le Merdy
 
Tester avant de déployer ; comment tester ses déploiements ARM.
Tester avant de déployer ; comment tester ses déploiements ARM.Tester avant de déployer ; comment tester ses déploiements ARM.
Tester avant de déployer ; comment tester ses déploiements ARM.AZUG FR
 

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

testUnitaire (1).pptx
testUnitaire (1).pptxtestUnitaire (1).pptx
testUnitaire (1).pptx
 
Automatisation des tests - objectifs et concepts - partie 2
Automatisation des tests  - objectifs et concepts - partie 2Automatisation des tests  - objectifs et concepts - partie 2
Automatisation des tests - objectifs et concepts - partie 2
 
Intro sur les tests unitaires
Intro sur les tests unitairesIntro sur les tests unitaires
Intro sur les tests unitaires
 
Test unitaire
Test unitaireTest unitaire
Test unitaire
 
Les tests en PHP
Les tests en PHPLes tests en PHP
Les tests en PHP
 
Flex Unit Testing
Flex Unit TestingFlex Unit Testing
Flex Unit Testing
 
Les cinq bonnes pratiques des Tests Unitaires dans un projet Agile
Les cinq bonnes pratiques des Tests Unitaires dans un projet AgileLes cinq bonnes pratiques des Tests Unitaires dans un projet Agile
Les cinq bonnes pratiques des Tests Unitaires dans un projet Agile
 
Bbl sur les tests
Bbl sur les testsBbl sur les tests
Bbl sur les tests
 
Traits : de la théorie à la pratique
Traits : de la théorie à la pratiqueTraits : de la théorie à la pratique
Traits : de la théorie à la pratique
 
Automatisation des tests - objectifs et concepts - partie 1
Automatisation des tests  - objectifs et concepts - partie 1Automatisation des tests  - objectifs et concepts - partie 1
Automatisation des tests - objectifs et concepts - partie 1
 
PyConFR - testons en python
PyConFR - testons en pythonPyConFR - testons en python
PyConFR - testons en python
 
J Unit
J UnitJ Unit
J Unit
 
PHPTour Lyon 2014 - Conférence - Tests unitaires Je veux mes 80% de couvertur...
PHPTour Lyon 2014 - Conférence - Tests unitaires Je veux mes 80% de couvertur...PHPTour Lyon 2014 - Conférence - Tests unitaires Je veux mes 80% de couvertur...
PHPTour Lyon 2014 - Conférence - Tests unitaires Je veux mes 80% de couvertur...
 
Test unitaire
Test unitaireTest unitaire
Test unitaire
 
Meetup Python Nantes - les tests en python
Meetup Python Nantes - les tests en pythonMeetup Python Nantes - les tests en python
Meetup Python Nantes - les tests en python
 
Cocoaheads Paris Nombembre Test unitaires
Cocoaheads Paris Nombembre Test unitairesCocoaheads Paris Nombembre Test unitaires
Cocoaheads Paris Nombembre Test unitaires
 
Formation Extreme Programming, Tests unitaires, travail collaboratif
Formation Extreme Programming, Tests unitaires, travail collaboratifFormation Extreme Programming, Tests unitaires, travail collaboratif
Formation Extreme Programming, Tests unitaires, travail collaboratif
 
Performance ug#1
Performance ug#1Performance ug#1
Performance ug#1
 
Tests Dinterface SWT
Tests Dinterface SWTTests Dinterface SWT
Tests Dinterface SWT
 
Tester avant de déployer ; comment tester ses déploiements ARM.
Tester avant de déployer ; comment tester ses déploiements ARM.Tester avant de déployer ; comment tester ses déploiements ARM.
Tester avant de déployer ; comment tester ses déploiements ARM.
 

Plus de Ippon

Quoi de neuf pour JHipster en 2016
Quoi de neuf pour JHipster en 2016Quoi de neuf pour JHipster en 2016
Quoi de neuf pour JHipster en 2016Ippon
 
Démystifions le machine learning avec spark par David Martin pour le Salon B...
Démystifions le machine learning avec spark par David Martin pour le Salon B...Démystifions le machine learning avec spark par David Martin pour le Salon B...
Démystifions le machine learning avec spark par David Martin pour le Salon B...Ippon
 
Système d’Information à l’Apec : un nouveau coeur de métier mis en place avec...
Système d’Information à l’Apec : un nouveau coeur de métier mis en place avec...Système d’Information à l’Apec : un nouveau coeur de métier mis en place avec...
Système d’Information à l’Apec : un nouveau coeur de métier mis en place avec...Ippon
 
Multi criteria queries on a cassandra application
Multi criteria queries on a cassandra applicationMulti criteria queries on a cassandra application
Multi criteria queries on a cassandra applicationIppon
 
Agilité, n’oublions pas les valeurs
Agilité, n’oublions pas les valeursAgilité, n’oublions pas les valeurs
Agilité, n’oublions pas les valeursIppon
 
Formation Usine Logicielle gratuite par Ippon 2014
Formation Usine Logicielle gratuite par Ippon 2014Formation Usine Logicielle gratuite par Ippon 2014
Formation Usine Logicielle gratuite par Ippon 2014Ippon
 
Formation html5 CSS3 offerte par ippon 2014
Formation html5 CSS3 offerte par ippon 2014Formation html5 CSS3 offerte par ippon 2014
Formation html5 CSS3 offerte par ippon 2014Ippon
 
One Web (API?) – Alexandre Bertails - Ippevent 10 juin 2014
One Web (API?) – Alexandre Bertails - Ippevent 10 juin 2014One Web (API?) – Alexandre Bertails - Ippevent 10 juin 2014
One Web (API?) – Alexandre Bertails - Ippevent 10 juin 2014Ippon
 
Web API & Cache, the HTTP way - Ippevent 10 Juin 2014
Web API & Cache, the HTTP way - Ippevent 10 Juin 2014Web API & Cache, the HTTP way - Ippevent 10 Juin 2014
Web API & Cache, the HTTP way - Ippevent 10 Juin 2014Ippon
 
Realtime Web avec Akka, Kafka, Spark et Mesos - Devoxx Paris 2014
Realtime Web avec Akka, Kafka, Spark et Mesos - Devoxx Paris 2014Realtime Web avec Akka, Kafka, Spark et Mesos - Devoxx Paris 2014
Realtime Web avec Akka, Kafka, Spark et Mesos - Devoxx Paris 2014Ippon
 
Cassandra Java Driver : vers Cassandra 1.2 et au-delà
Cassandra Java Driver : vers Cassandra 1.2 et au-delàCassandra Java Driver : vers Cassandra 1.2 et au-delà
Cassandra Java Driver : vers Cassandra 1.2 et au-delàIppon
 
JPA avec Cassandra, grâce à Achilles
JPA avec Cassandra, grâce à AchillesJPA avec Cassandra, grâce à Achilles
JPA avec Cassandra, grâce à AchillesIppon
 
Offre 2015 numeriq_ippon
Offre 2015 numeriq_ipponOffre 2015 numeriq_ippon
Offre 2015 numeriq_ipponIppon
 
Atelier TDD (Test Driven Development)
Atelier TDD (Test Driven Development)Atelier TDD (Test Driven Development)
Atelier TDD (Test Driven Development)Ippon
 
CDI par la pratique
CDI par la pratiqueCDI par la pratique
CDI par la pratiqueIppon
 
Nouveau look pour une nouvelle vie : HTML5, Spring, NoSQL et Mobile
Nouveau look pour une nouvelle vie : HTML5, Spring, NoSQL et MobileNouveau look pour une nouvelle vie : HTML5, Spring, NoSQL et Mobile
Nouveau look pour une nouvelle vie : HTML5, Spring, NoSQL et MobileIppon
 
Hibernate vs le_cloud_computing
Hibernate vs le_cloud_computingHibernate vs le_cloud_computing
Hibernate vs le_cloud_computingIppon
 
Stateful is beautiful
Stateful is beautifulStateful is beautiful
Stateful is beautifulIppon
 
Présentation Ippon DGA Liferay Symposium 2011
Présentation Ippon DGA Liferay Symposium 2011Présentation Ippon DGA Liferay Symposium 2011
Présentation Ippon DGA Liferay Symposium 2011Ippon
 
Scrum et forfait
Scrum et forfaitScrum et forfait
Scrum et forfaitIppon
 

Plus de Ippon (20)

Quoi de neuf pour JHipster en 2016
Quoi de neuf pour JHipster en 2016Quoi de neuf pour JHipster en 2016
Quoi de neuf pour JHipster en 2016
 
Démystifions le machine learning avec spark par David Martin pour le Salon B...
Démystifions le machine learning avec spark par David Martin pour le Salon B...Démystifions le machine learning avec spark par David Martin pour le Salon B...
Démystifions le machine learning avec spark par David Martin pour le Salon B...
 
Système d’Information à l’Apec : un nouveau coeur de métier mis en place avec...
Système d’Information à l’Apec : un nouveau coeur de métier mis en place avec...Système d’Information à l’Apec : un nouveau coeur de métier mis en place avec...
Système d’Information à l’Apec : un nouveau coeur de métier mis en place avec...
 
Multi criteria queries on a cassandra application
Multi criteria queries on a cassandra applicationMulti criteria queries on a cassandra application
Multi criteria queries on a cassandra application
 
Agilité, n’oublions pas les valeurs
Agilité, n’oublions pas les valeursAgilité, n’oublions pas les valeurs
Agilité, n’oublions pas les valeurs
 
Formation Usine Logicielle gratuite par Ippon 2014
Formation Usine Logicielle gratuite par Ippon 2014Formation Usine Logicielle gratuite par Ippon 2014
Formation Usine Logicielle gratuite par Ippon 2014
 
Formation html5 CSS3 offerte par ippon 2014
Formation html5 CSS3 offerte par ippon 2014Formation html5 CSS3 offerte par ippon 2014
Formation html5 CSS3 offerte par ippon 2014
 
One Web (API?) – Alexandre Bertails - Ippevent 10 juin 2014
One Web (API?) – Alexandre Bertails - Ippevent 10 juin 2014One Web (API?) – Alexandre Bertails - Ippevent 10 juin 2014
One Web (API?) – Alexandre Bertails - Ippevent 10 juin 2014
 
Web API & Cache, the HTTP way - Ippevent 10 Juin 2014
Web API & Cache, the HTTP way - Ippevent 10 Juin 2014Web API & Cache, the HTTP way - Ippevent 10 Juin 2014
Web API & Cache, the HTTP way - Ippevent 10 Juin 2014
 
Realtime Web avec Akka, Kafka, Spark et Mesos - Devoxx Paris 2014
Realtime Web avec Akka, Kafka, Spark et Mesos - Devoxx Paris 2014Realtime Web avec Akka, Kafka, Spark et Mesos - Devoxx Paris 2014
Realtime Web avec Akka, Kafka, Spark et Mesos - Devoxx Paris 2014
 
Cassandra Java Driver : vers Cassandra 1.2 et au-delà
Cassandra Java Driver : vers Cassandra 1.2 et au-delàCassandra Java Driver : vers Cassandra 1.2 et au-delà
Cassandra Java Driver : vers Cassandra 1.2 et au-delà
 
JPA avec Cassandra, grâce à Achilles
JPA avec Cassandra, grâce à AchillesJPA avec Cassandra, grâce à Achilles
JPA avec Cassandra, grâce à Achilles
 
Offre 2015 numeriq_ippon
Offre 2015 numeriq_ipponOffre 2015 numeriq_ippon
Offre 2015 numeriq_ippon
 
Atelier TDD (Test Driven Development)
Atelier TDD (Test Driven Development)Atelier TDD (Test Driven Development)
Atelier TDD (Test Driven Development)
 
CDI par la pratique
CDI par la pratiqueCDI par la pratique
CDI par la pratique
 
Nouveau look pour une nouvelle vie : HTML5, Spring, NoSQL et Mobile
Nouveau look pour une nouvelle vie : HTML5, Spring, NoSQL et MobileNouveau look pour une nouvelle vie : HTML5, Spring, NoSQL et Mobile
Nouveau look pour une nouvelle vie : HTML5, Spring, NoSQL et Mobile
 
Hibernate vs le_cloud_computing
Hibernate vs le_cloud_computingHibernate vs le_cloud_computing
Hibernate vs le_cloud_computing
 
Stateful is beautiful
Stateful is beautifulStateful is beautiful
Stateful is beautiful
 
Présentation Ippon DGA Liferay Symposium 2011
Présentation Ippon DGA Liferay Symposium 2011Présentation Ippon DGA Liferay Symposium 2011
Présentation Ippon DGA Liferay Symposium 2011
 
Scrum et forfait
Scrum et forfaitScrum et forfait
Scrum et forfait
 

Formation Gratuite Total Tests par les experts Java Ippon

  • 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. @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. @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. @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. @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. Jour 1 : garantir la qualité de son code
  • 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.
  • 10. @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
  • 11. @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
  • 12. @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é
  • 13. @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); }
  • 14.
  • 15. @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
  • 16. @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);
  • 17. @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()));
  • 18. @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);
  • 19. @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);
  • 20. @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) ;
  • 21. @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
  • 22. @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); }
  • 23. @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 }
  • 24. @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
  • 25. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Exemple ● Exemple d'un test en erreur dans IntelliJ IDEA :
  • 26. @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
  • 27. @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
  • 28. @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
  • 29. @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);
  • 30. @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
  • 31. @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");
  • 32. @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
  • 33. @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()»
  • 34. @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"); ....
  • 35. @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); }
  • 36. @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 »
  • 37. @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"); }
  • 38. @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());
  • 39. @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/
  • 40. @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
  • 41. @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
  • 42. @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
  • 43. @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
  • 44. @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()); } }
  • 45. @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() { ... } }
  • 46. @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
  • 47. @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 }
  • 48. @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
  • 49. @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()); }
  • 50. @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
  • 51. @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
  • 52. @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
  • 53. @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
  • 54. @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
  • 55. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr Processus de développement
  • 56. @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
  • 57. @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é
  • 58.
  • 59. @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
  • 60. @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
  • 61. @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
  • 62. @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... »
  • 63. @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 »
  • 64. @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
  • 65. @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
  • 66. @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 »
  • 67. Jour 1 : Sonar, tests automatisés et couverture de tests
  • 68. @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
  • 69. @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
  • 70. @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
  • 71. @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...
  • 72. @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
  • 73. @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)
  • 74. @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
  • 75. @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
  • 76. @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 »
  • 77. Jour 2 : les tests de performance
  • 78. @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
  • 79. @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
  • 80. @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)
  • 81. @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
  • 82. @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...
  • 83. @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
  • 84. @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
  • 85. @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
  • 86. @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)
  • 87. @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
  • 88. @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
  • 89. @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...
  • 90. @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
  • 91. @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
  • 92. @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"/>
  • 93. @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
  • 94. @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 »
  • 95. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping »
  • 96. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping »
  • 97. @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.
  • 98. @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.
  • 99. @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.
  • 100. @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.
  • 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 (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).
  • 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 (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).
  • 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 (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
  • 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 (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)
  • 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 (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
  • 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 (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 !
  • 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 (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) :
  • 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 (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.
  • 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 (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
  • 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 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 :
  • 111. @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.
  • 112. @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.
  • 113. @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)
  • 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 (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
  • 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 (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
  • 116. @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 »
  • 117. @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
  • 118. @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) 
  • 119. @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
  • 120. @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
  • 121. @ippontech www.ippon.fr blog.ippon.fr www.atomes.com contact@ippon.fr TP Optimiser « Ippon shopping » Superviser à l'aide de JMX (3/5)
  • 122. @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 ».
  • 123. @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 »
  • 124. Jour 2 : les tests fonctionnels avec Selenium
  • 125. @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
  • 126. @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
  • 127. @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
  • 128. @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 !
  • 129. @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>
  • 130. @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 »
  • 131. @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(); }
  • 132. @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")
  • 133. @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]");
  • 134. @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
  • 135. @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);
  • 136. @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();
  • 137. @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")));
  • 138. @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");
  • 139. @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"));
  • 140. @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
  • 141. @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"); } }
  • 142. @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()
  • 143. @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"); } }
  • 144. @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 »
  • 145. Jour 2 : les tests d'interface avec Karma
  • 146. @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
  • 147. @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)
  • 148. @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/
  • 149. @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/
  • 150. @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
  • 151. @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); }); });
  • 152. @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
  • 153. @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); }); });
  • 154. @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/
  • 155. @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/
  • 156. @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
  • 157. @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
  • 158. @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
  • 159. @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; });
  • 160. @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)
  • 161. @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' }
  • 162. @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 »