Formation tests Florence CHABANOIS Mardi 14 décembre 2010
Consultante Soat Ce que j’aime Le partage Le fun Ce que je n’aime pas La répétition Qualité Développement
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 projet L’objectif ? Ce qui l’empêche d’y arriver
Planning Mardi  Matin : présentation générale sur les tests Après-midi : étude de l’existant et choix des outils Mercredi-Jeudi Mélée dans les équipes pour poser des tests Vendredi Matin : atelier de mise au point (rattrapage, traitement d’un problème récurrent ou perfectionnement) Après-midi : synthèse avec les managers
Formation tests Jusque 11h
Tester ? Vérifier le bon fonctionnement Révéler les défauts
Nous faisons  tous  des tests
 
 
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
 
 
 
 
 
Tests manuels en IT Hypothèse invalidée Il faut supprimer le compte et tester une autre hypothèse
Coûts des tests manuels Longs  Nouveaux + existants Propices aux erreurs Concentration, oublis Laissent moins de place aux autres tests (exploratoires, de charge, expérience utilisateur, etc.) X10 x10 x10      Industrialiser les tests
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 »
Tests fonctionnels Boite noire  Données en entrée et observations attendues nom prenom email Inscription … newsletter « Vous êtes bien inscrit »
Selenium http://seleniumhq.org   Mode opératoire 0. Lancer le plugin firefox 1. Enregistrement du scénario 2. Spécifications des attentes 3. Arrêt de l’enregistrement 3. Ajustement pour faire passer le test Présentation Code Selenium Données
Exemple Selenium Spécification : un mot recherché ne doit pas tenir compte de la casse « electricite » Recherche « Electricité »
Selenium
Selenium Les avantages Facilité de création des cas de tests Assure la non régression Teste la fonctionnalité comme le ferait un utilisateur Testable en continu
Selenium Les inconvénients Lenteurs Tests non déterministes Potentiellement très nombreux Peu évolutifs et difficiles à maintenir Crées après l’implémentation Dépendants du navigateur Peu compréhensibles avant d’être exécutés
Fitnesse http://fitnesse.org   Mode opératoire 0. Lancer le serveur fitnesse 1. Déclarer vos spécifications dans le wiki 2. Câbler votre code dessus (par le biais de fixture) Présentation Code Fitnesse Données Fixtures
Fitnesse
Fitnesse
Fitnesse Les avantages Limite les malentendus par les exemples Constitue une  spécification exécutable  (TDR) Factorisable Testable en continu Centralisé Les inconvénients Ticket d’entrée Ne teste pas l’application tout à fait comme un utilisateur
Autres outils de tests fonctionnels Greenpepper avec XWiki ou Confluence http://www.greenpeppersoftware.com   Concordion http://www.concordion.org/
Limites des tests fonctionnels Dépendant de l’état de l’application Longs à écrire, à exécuter et à maintenir Boucle de feedback Ne donne aucun indice sur la cause
 
 
D’où vient le problème ? Frein ? Direction assistée? Boite de vitesse ? Pneus usés ?
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
Tests unitaires Pour pouvoir tester  unitairement : Les composants doivent être séparables pour être utilisés de façon isolée Les éléments testés doivent être simples
Test Driven Development Développement dirigé par les tests Given… When… Then Implémentation Refactoring
 
Premier test
Quand… Avec … Alors … @Test public   void  add_DeuxEtTrois_retourneCinq() { int  resultat =  new  Computer().ajoute(2, 3); assertThat (resultat, is ( equalTo (5))); }
Barre rouge
Implémentation et barre verte
Deuxième test
Généralisation
Tester une méthode qui traverse des couches
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); }
@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"); }
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"); }
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 )); }
Inconvénients Interdépendance avec la base  Tests non parallélisables Etat instable (si données non supprimées) Potentiellement non déterministe Couplage fort Nombreux tests à modifier Solution Refactorer pour permettre un branchement
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)); }
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 )); }
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 )); }
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 )); }
Autres frameworks de tests Classiques JMock, Easymock Pour le code legacy Powermock, JMockit
Tests unitaires Avantages Permet de sécuriser son application  …  incrémentalement Augmente la confiance Aide à construire le logiciel Inconvénients Apprentissage Ralentit le développement dans un premier temps
Ressources complémentaires Tests Test Driven Development, K.Beck xUnit Test Patterns, G.Meszaros Growing Object Oriented Software, S.Freeman, N.Pryce Working Effectively With Legacy Code, M.Feathers Design Coder Proprement, R.Martin Refactoring, M.Fowler
A retenir Test non automatisé = (pas de test) Un bug corrigé une fois est corrigé pour toujours Faites toujours passer un test au rouge avant de le passer au vert Soignez le comme du code de production Soignez votre code de production (boy scout rule, DRY, KISS)
Questions ? Votre expérience ? Vos besoins ?  Votre ressenti ?

Formation tests decembre2010

  • 1.
    Formation tests FlorenceCHABANOIS Mardi 14 décembre 2010
  • 2.
    Consultante Soat Ceque j’aime Le partage Le fun Ce que je n’aime pas La répétition Qualité Développement
  • 3.
    Vous ? Cequi 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 projet L’objectif ? Ce qui l’empêche d’y arriver
  • 4.
    Planning Mardi Matin : présentation générale sur les tests Après-midi : étude de l’existant et choix des outils Mercredi-Jeudi Mélée dans les équipes pour poser des tests Vendredi Matin : atelier de mise au point (rattrapage, traitement d’un problème récurrent ou perfectionnement) Après-midi : synthèse avec les managers
  • 5.
  • 6.
    Tester ? Vérifierle bon fonctionnement Révéler les défauts
  • 7.
    Nous faisons tous des tests
  • 8.
  • 9.
  • 10.
    En informatique Unclient 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 enIT Hypothèse invalidée Il faut supprimer le compte et tester une autre hypothèse
  • 17.
    Coûts des testsmanuels Longs Nouveaux + existants Propices aux erreurs Concentration, oublis Laissent moins de place aux autres tests (exploratoires, de charge, expérience utilisateur, etc.) X10 x10 x10  Industrialiser les tests
  • 18.
    Typologie des testsTest 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 Boitenoire Données en entrée et observations attendues nom prenom email Inscription … newsletter « Vous êtes bien inscrit »
  • 20.
    Selenium http://seleniumhq.org Mode opératoire 0. Lancer le plugin firefox 1. Enregistrement du scénario 2. Spécifications des attentes 3. Arrêt de l’enregistrement 3. 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.
  • 23.
    Selenium Les avantagesFacilité de création des cas de tests Assure la non régression Teste la fonctionnalité comme le ferait un utilisateur Testable en continu
  • 24.
    Selenium Les inconvénientsLenteurs Tests non déterministes Potentiellement très nombreux Peu évolutifs et difficiles à maintenir Crées après l’implémentation Dépendants du navigateur Peu compréhensibles avant d’être exécutés
  • 25.
    Fitnesse http://fitnesse.org Mode opératoire 0. Lancer le serveur fitnesse 1. Déclarer vos spécifications dans le wiki 2. Câbler votre code dessus (par le biais de fixture) Présentation Code Fitnesse Données Fixtures
  • 26.
  • 27.
  • 28.
    Fitnesse Les avantagesLimite les malentendus par les exemples Constitue une spécification exécutable (TDR) Factorisable Testable en continu Centralisé Les inconvénients Ticket d’entrée Ne teste pas l’application tout à fait comme un utilisateur
  • 29.
    Autres outils detests fonctionnels Greenpepper avec XWiki ou Confluence http://www.greenpeppersoftware.com Concordion http://www.concordion.org/
  • 30.
    Limites des testsfonctionnels Dépendant de l’état de l’application Longs à écrire, à exécuter et à maintenir Boucle de feedback Ne donne aucun indice sur la cause
  • 31.
  • 32.
  • 33.
    D’où vient leproblème ? Frein ? Direction assistée? Boite de vitesse ? Pneus usés ?
  • 34.
    Tests unitaires Permetde 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 Pourpouvoir tester unitairement : Les composants doivent être séparables pour être utilisés de façon isolée Les éléments testés doivent être simples
  • 36.
    Test Driven DevelopmentDéveloppement dirigé par les tests Given… When… Then Implémentation Refactoring
  • 37.
  • 38.
  • 39.
    Quand… Avec …Alors … @Test public void add_DeuxEtTrois_retourneCinq() { int resultat = new Computer().ajoute(2, 3); assertThat (resultat, is ( equalTo (5))); }
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
    Tester une méthodequi traverse des couches
  • 45.
    Utiliser les mockspour 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 caslimites @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énients Interdépendance avecla base Tests non parallélisables Etat instable (si données non supprimées) Potentiellement non déterministe Couplage fort Nombreux tests à modifier Solution Refactorer pour permettre un branchement
  • 50.
    Création d’une veinepour 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 mockpour 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 detests Classiques JMock, Easymock Pour le code legacy Powermock, JMockit
  • 55.
    Tests unitaires AvantagesPermet de sécuriser son application … incrémentalement Augmente la confiance Aide à construire le logiciel Inconvénients Apprentissage Ralentit le développement dans un premier temps
  • 56.
    Ressources complémentaires TestsTest Driven Development, K.Beck xUnit Test Patterns, G.Meszaros Growing Object Oriented Software, S.Freeman, N.Pryce Working Effectively With Legacy Code, M.Feathers Design Coder Proprement, R.Martin Refactoring, M.Fowler
  • 57.
    A retenir Testnon automatisé = (pas de test) Un bug corrigé une fois est corrigé pour toujours Faites toujours passer un test au rouge avant de le passer au vert Soignez le comme du code de production Soignez votre code de production (boy scout rule, DRY, KISS)
  • 58.
    Questions ? Votreexpérience ? Vos besoins ? Votre ressenti ?

Notes de l'éditeur

  • #3 Activités
  • #7 Il y a une arnaque
  • #10 Si tout le monde en fait dejà, qu’est ce que j’apporte ?
  • #15 Je ressaisis mon mot de passe
  • #18 Cout de MEP et multiplication des causes possibles
  • #32 Revenons sur la voiture d’occasion que nous voulions acheté
  • #33 Le défaut est révélé
  • #35 Qu’est ce qu’on y gagne? Satisfaction : on sait que ça marche Qd pb, on peut innocenter le code Specs Rassure, confiance pour remanier le code Il faut des branchements
  • #36 Qu’est ce qu’on y gagne? Satisfaction : on sait que ça marche Qd pb, on peut innocenter le code Specs Rassure, confiance pour remanier le code Il faut des branchements
  • #37 Given : carburant + huile moteur + batterie ok When : tourne la clef Then : démarrage du moteur
  • #46 ajoute
  • #51 ajoute
  • #57 Pour les méthodes et classes longues
  • #58 Ils devront etre maintenus