Download - Formation tests decembre2010
1
Formation tests
Florence CHABANOISMardi 14 décembre 2010
2
Consultante Soat
Ce que j’aimeLe partageLe fun
Ce que je n’aime pasLa répétition
Qualité Développement
3
Vous ?
Ce qui vous sort par les yeux, en général ou au quotidien
Ce que vous trouviez « bien » dans votre projet et sur vos pratiques
Votre projetL’objectif ?Ce qui l’empêche d’y arriver
4
Planning
Mardi Matin : présentation générale sur les testsAprès-midi : étude de l’existant et choix des outils
Mercredi-JeudiMélée dans les équipes pour poser des tests
VendrediMatin : atelier de mise au point (rattrapage, traitement d’un problème récurrent ou perfectionnement)Après-midi : synthèse avec les managers
5
Formation tests
Jusque 11h
6
Tester ?
Vérifier le bon fonctionnement
Révéler les défauts
7
Nous faisons
tous
des tests
8
9
10
En informatique
Un client nous remonte qu’il vient de s’inscrire sur notre site d’e-commerce et qu’il a eu un message d’erreur
11
12
13
14
15
16
Tests manuels en IT
Hypothèse invalidéeIl faut supprimer le compte et tester une autre hypothèse
17
Coûts des tests manuels
Longs Nouveaux + existants
Propices aux erreursConcentration, oublis
Laissent moins de place aux autres tests (exploratoires, de charge, expérience utilisateur, etc.)X10 x10 x10
Industrialiser les tests
18
Typologie des tests
Test fonctionnel
Test unitaire
Test de charge
Test d’exploitabilité
Test d’intégration
Test d’accessibilité
Test de conformité W3C
Test fonctionnel
Test unitaire
…
« bon fonctionnement »
19
Tests fonctionnels
Boite noire Données en entrée et observations attendues
nom
prenom
emailInscription
…
newsletter
« Vous êtes bien inscrit »
20
Selenium
http://seleniumhq.org
Mode opératoire0. Lancer le plugin firefox1. Enregistrement du scénario2. Spécifications des attentes3. Arrêt de l’enregistrement3. Ajustement pour faire passer le test
Présentation
Code
Selenium
Données
21
Exemple Selenium
Spécification : un mot recherché ne doit pas tenir compte de la casse
« electricite »
Recherche
« Electricité »
22
Selenium
23
Selenium
Les avantagesFacilité de création des cas de testsAssure la non régressionTeste la fonctionnalité comme le ferait un utilisateurTestable en continu
24
Selenium
Les inconvénientsLenteursTests non déterministesPotentiellement très nombreuxPeu évolutifs et difficiles à maintenirCrées après l’implémentationDépendants du navigateurPeu compréhensibles avant d’être exécutés
25
Fitnesse
http://fitnesse.org
Mode opératoire0. Lancer le serveur fitnesse1. Déclarer vos spécifications dans le wiki2. Câbler votre code dessus (par le biais de
fixture)
Présentation
Code
Fitnesse
Données
Fixtures
26
Fitnesse
27
Fitnesse
28
Fitnesse
Les avantagesLimite les malentendus par les exemplesConstitue une spécification exécutable (TDR)FactorisableTestable en continuCentralisé
Les inconvénientsTicket d’entréeNe teste pas l’application tout à fait comme un utilisateur
29
Autres outils de tests fonctionnels
Greenpepper avec XWiki ou Confluencehttp://www.greenpeppersoftware.com
Concordionhttp://www.concordion.org/
31
32
33
D’où vient le problème ?
Frein ?
Direction assistée?
Boite de vitesse ?
Pneus usés ?
34
Tests unitaires
Permet de vérifier isolément que les composants fonctionnent bien
Tester une partie du produit Simuler un comportement différent de la production
35
Tests unitaires
Pour pouvoir tester unitairement :Les composants doivent être séparables pour être utilisés de façon isoléeLes éléments testés doivent être simples
36
Test Driven Development
Développement dirigé par les tests
• Given… When… Then• Implémentation• Refactoring
37
38
Premier test
39
Quand… Avec … Alors …
@Test public void add_DeuxEtTrois_retourneCinq() { int resultat = new Computer().ajoute(2, 3); assertThat(resultat,is(equalTo(5))); }
40
Barre rouge
41
Implémentation et barre verte
42
Deuxième test
43
Généralisation
44
Tester une méthode qui traverse des couches
45
Utiliser les mocks pour tester en isolation
public class Utilisateur { private String login = « login »;
public boolean login(String motDePasse) {UserDao userDao = new UserDao();
String motDePasseDeLaBase = userDao.getPassword(login);
return (motDePasse==motDePasseDeLaBase); }
46
@Test public void login_utilisateurExisteEtPasswordOk_retourneTrue()
{ insereUtilisateurDansLaBase("login","mot de passe correct"); boolean estLoggue = new Utilisateur().login("mot de passe
correct"); assertThat(estLoggue, is(true)); supprimerUtilisateurDeLaBase("login"); }
47
Tester les cas limites
@Test public void login_utilisateurExisteEtPasswordOk_retourneTrue() { insereUtilisateurDansLaBase("login","mot de passe correct"); boolean estLoggue = new Utilisateur().login("mot de passe correct"); assertThat(estLoggue, is(true)); supprimerUtilisateurDeLaBase("login"); } @Test public void login_utilisateurExisteEtPasswordIncorrect_retourneFalse() { insereUtilisateurDansLaBase("login","mot de passe correct"); boolean estLoggue = new Utilisateur().login(« pas le bon mot de passe"); assertThat(estLoggue, is(false)); supprimerUtilisateurDeLaBase("login"); }
48
Factoriser
@Before public void setUp() { insereUtilisateurDansLaBase("login","mot de passe correct"); } @After public void tearDown() { supprimerUtilisateurDeLaBase("login"); } @Test public void login_utilisateurExisteEtPasswordOk_retourneTrue() { boolean estLoggue = new Utilisateur().login("mot de passe correct"); assertThat(estLoggue, is(true)); }
49
InconvénientsInterdépendance avec la base
Tests non parallélisablesEtat instable (si données non supprimées)Potentiellement non déterministe
Couplage fortNombreux tests à modifier
SolutionRefactorer pour permettre un branchement
50
Création d’une veine pour le DAO
public class Utilisateur { String login = « login »; UserDao userDao = new UserDao();
Utilisateur(UserDao userDao) { this.userDao = userDao; }
public boolean login(String motDePasse) { String motDePasseDeLaBase =
userDao.getPassword(login); return (motDePasse.equals(motDePasseDeLaBase)); }
51
Utilisation de mock pour simuler d’autres comportements
@Test public void login_utilisateurExisteEtPasswordOk_retourneTrue() { UserDao dao = Mockito.mock(UserDao.class); when(dao.getPassword("login")).thenReturn("mot de passe correct"); boolean estLoggue = new Utilisateur(dao).login("mot de passe
correct"); assertThat(estLoggue, is(true)); }
52
Autre cas limite
@Test public void login_utilisateurExisteEtException_retourneFalse() { UserDao dao = Mockito.mock(UserDao.class); when(dao.getPassword("login")).thenThrow(new RuntimeException());
boolean estLoggue = new Utilisateur(dao).login("mot de passe correct");
verify(dao).getPassword("login"); assertThat(estLoggue, is(false)); }
53
Vérification du comportement
@Test public void login_utilisateurExisteEtPasswordOk_retourneTrue() { UserDao dao = mock(UserDao.class); when(dao.getPassword("login")).thenReturn("mot de passe correct"); boolean estLoggue = new Utilisateur(dao).login("mot de passe
correct"); verify(dao).getPassword("login"); assertThat(estLoggue, is(true)); }
54
Autres frameworks de tests
ClassiquesJMock, Easymock
Pour le code legacyPowermock, JMockit
55
Tests unitaires
AvantagesPermet de sécuriser son application … incrémentalementAugmente la confianceAide à construire le logiciel
InconvénientsApprentissageRalentit le développement dans un premier temps
56
Ressources complémentaires
TestsTest Driven Development, K.BeckxUnit Test Patterns, G.MeszarosGrowing Object Oriented Software, S.Freeman, N.PryceWorking Effectively With Legacy Code, M.Feathers
DesignCoder Proprement, R.MartinRefactoring, M.Fowler
57
A retenir
Test non automatisé = (pas de test)Un bug corrigé une fois est corrigé pour toujoursFaites toujours passer un test au rouge avant de le passer au vertSoignez le comme du code de productionSoignez votre code de production (boy scout rule, DRY, KISS)
58
Questions ?
Votre expérience ?Vos besoins ? Votre ressenti ?