Formation tests Florence CHABANOIS Mardi 14 décembre 2010
Consultante Soat <ul><li>Ce que j’aime </li></ul><ul><ul><li>Le partage </li></ul></ul><ul><ul><li>Le fun </li></ul></ul><...
Vous ? <ul><li>Ce qui vous sort par les yeux, en général ou au quotidien </li></ul><ul><li>Ce que vous trouviez « bien » d...
Planning <ul><li>Mardi  </li></ul><ul><ul><li>Matin : présentation générale sur les tests </li></ul></ul><ul><ul><li>Après...
Formation tests Jusque 11h
Tester ? <ul><li>Vérifier le bon fonctionnement </li></ul><ul><li>Révéler les défauts </li></ul>
<ul><li>Nous faisons  </li></ul><ul><li>tous  </li></ul><ul><li>des tests </li></ul>
 
 
En informatique <ul><li>Un client nous remonte qu’il vient de s’inscrire sur notre site d’e-commerce et qu’il a eu un mess...
 
 
 
 
 
Tests manuels en IT <ul><li>Hypothèse invalidée </li></ul><ul><li>Il faut supprimer le compte et tester une autre hypothès...
Coûts des tests manuels <ul><li>Longs  </li></ul><ul><ul><li>Nouveaux + existants </li></ul></ul><ul><li>Propices aux erre...
Typologie des tests Test  fonctionnel Test  unitaire Test  de charge Test  d’exploitabilité Test  d’intégration Test  d’ac...
Tests fonctionnels <ul><li>Boite noire  </li></ul><ul><ul><li>Données en entrée et observations attendues </li></ul></ul>n...
Selenium <ul><li>http://seleniumhq.org   </li></ul><ul><li>Mode opératoire </li></ul><ul><ul><li>0. Lancer le plugin firef...
Exemple Selenium <ul><li>Spécification : un mot recherché ne doit pas tenir compte de la casse </li></ul>« electricite » R...
Selenium
Selenium <ul><li>Les avantages </li></ul><ul><ul><li>Facilité de création des cas de tests </li></ul></ul><ul><ul><li>Assu...
Selenium <ul><li>Les inconvénients </li></ul><ul><ul><li>Lenteurs </li></ul></ul><ul><ul><li>Tests non déterministes </li>...
Fitnesse <ul><li>http://fitnesse.org   </li></ul><ul><li>Mode opératoire </li></ul><ul><ul><li>0. Lancer le serveur fitnes...
Fitnesse
Fitnesse
Fitnesse <ul><li>Les avantages </li></ul><ul><ul><li>Limite les malentendus par les exemples </li></ul></ul><ul><ul><li>Co...
Autres outils de tests fonctionnels <ul><li>Greenpepper avec XWiki ou Confluence </li></ul><ul><ul><li>http://www.greenpep...
Limites des tests fonctionnels <ul><li>Dépendant de l’état de l’application </li></ul><ul><li>Longs à écrire, à exécuter e...
 
 
D’où vient le problème ? Frein ? Direction assistée? Boite de vitesse ? Pneus usés ?
Tests unitaires <ul><li>Permet de vérifier isolément que les composants fonctionnent bien </li></ul><ul><li>Tester une  pa...
Tests unitaires <ul><li>Pour pouvoir tester  unitairement : </li></ul><ul><ul><li>Les composants doivent être séparables p...
Test Driven Development <ul><li>Développement dirigé par les tests </li></ul><ul><ul><ul><ul><li>Given… When… Then </li></...
 
<ul><li>Premier test </li></ul>
Quand… Avec … Alors … <ul><li>@Test </li></ul><ul><li>public   void  add_DeuxEtTrois_retourneCinq() { </li></ul><ul><li>in...
Barre rouge
Implémentation et barre verte
Deuxième test
Généralisation
<ul><li>Tester une méthode qui traverse des couches </li></ul>
Utiliser les mocks pour tester en isolation <ul><li>public   class  Utilisateur { </li></ul><ul><li>private String login =...
<ul><li>@Test </li></ul><ul><li>public   void  login_utilisateurExisteEtPasswordOk_retourneTrue() { </li></ul><ul><li>inse...
Tester les cas limites <ul><li>@Test </li></ul><ul><li>public   void  login_utilisateurExisteEtPasswordOk_retourneTrue() {...
Factoriser <ul><li>@Before </li></ul><ul><li>public   void  setUp() { </li></ul><ul><li>insereUtilisateurDansLaBase(&quot;...
<ul><li>Inconvénients </li></ul><ul><ul><li>Interdépendance avec la base  </li></ul></ul><ul><ul><ul><li>Tests non parallé...
Création d’une veine pour le DAO <ul><li>public   class  Utilisateur { </li></ul><ul><li>String login = « login »; </li></...
Utilisation de mock pour simuler d’autres comportements <ul><li>@Test </li></ul><ul><li>public   void  login_utilisateurEx...
Autre cas limite <ul><li>@Test </li></ul><ul><li>public   void  login_utilisateurExisteEtException_retourneFalse() { </li>...
Vérification du comportement <ul><li>@Test </li></ul><ul><li>public   void  login_utilisateurExisteEtPasswordOk_retourneTr...
Autres frameworks de tests <ul><li>Classiques </li></ul><ul><ul><li>JMock, Easymock </li></ul></ul><ul><li>Pour le code le...
Tests unitaires <ul><li>Avantages </li></ul><ul><ul><li>Permet de sécuriser son application  </li></ul></ul><ul><ul><li>… ...
Ressources complémentaires <ul><li>Tests </li></ul><ul><ul><li>Test Driven Development, K.Beck </li></ul></ul><ul><ul><li>...
A retenir <ul><li>Test non automatisé = (pas de test) </li></ul><ul><li>Un bug corrigé une fois est corrigé pour toujours ...
Questions ? <ul><li>Votre expérience ? </li></ul><ul><li>Vos besoins ?  </li></ul><ul><li>Votre ressenti ?  </li></ul>
Prochain SlideShare
Chargement dans…5
×

Formation tests decembre2010

1 248 vues

Publié le

  • Soyez le premier à commenter

Formation tests decembre2010

  1. 1. Formation tests Florence CHABANOIS Mardi 14 décembre 2010
  2. 2. Consultante Soat <ul><li>Ce que j’aime </li></ul><ul><ul><li>Le partage </li></ul></ul><ul><ul><li>Le fun </li></ul></ul><ul><li>Ce que je n’aime pas </li></ul><ul><ul><li>La répétition </li></ul></ul>Qualité Développement
  3. 3. Vous ? <ul><li>Ce qui vous sort par les yeux, en général ou au quotidien </li></ul><ul><li>Ce que vous trouviez « bien » dans votre projet et sur vos pratiques </li></ul><ul><li>Votre projet </li></ul><ul><ul><ul><li>L’objectif ? </li></ul></ul></ul><ul><ul><ul><li>Ce qui l’empêche d’y arriver </li></ul></ul></ul>
  4. 4. Planning <ul><li>Mardi </li></ul><ul><ul><li>Matin : présentation générale sur les tests </li></ul></ul><ul><ul><li>Après-midi : étude de l’existant et choix des outils </li></ul></ul><ul><li>Mercredi-Jeudi </li></ul><ul><ul><li>Mélée dans les équipes pour poser des tests </li></ul></ul><ul><li>Vendredi </li></ul><ul><ul><li>Matin : atelier de mise au point (rattrapage, traitement d’un problème récurrent ou perfectionnement) </li></ul></ul><ul><ul><li>Après-midi : synthèse avec les managers </li></ul></ul>
  5. 5. Formation tests Jusque 11h
  6. 6. Tester ? <ul><li>Vérifier le bon fonctionnement </li></ul><ul><li>Révéler les défauts </li></ul>
  7. 7. <ul><li>Nous faisons </li></ul><ul><li>tous </li></ul><ul><li>des tests </li></ul>
  8. 10. En informatique <ul><li>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 </li></ul>
  9. 16. Tests manuels en IT <ul><li>Hypothèse invalidée </li></ul><ul><li>Il faut supprimer le compte et tester une autre hypothèse </li></ul>
  10. 17. Coûts des tests manuels <ul><li>Longs </li></ul><ul><ul><li>Nouveaux + existants </li></ul></ul><ul><li>Propices aux erreurs </li></ul><ul><ul><li>Concentration, oublis </li></ul></ul><ul><li>Laissent moins de place aux autres tests (exploratoires, de charge, expérience utilisateur, etc.) </li></ul><ul><li>X10 x10 x10 </li></ul><ul><li>  Industrialiser les tests </li></ul>
  11. 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 »
  12. 19. Tests fonctionnels <ul><li>Boite noire </li></ul><ul><ul><li>Données en entrée et observations attendues </li></ul></ul>nom prenom email Inscription … newsletter « Vous êtes bien inscrit »
  13. 20. Selenium <ul><li>http://seleniumhq.org </li></ul><ul><li>Mode opératoire </li></ul><ul><ul><li>0. Lancer le plugin firefox </li></ul></ul><ul><ul><li>1. Enregistrement du scénario </li></ul></ul><ul><ul><li>2. Spécifications des attentes </li></ul></ul><ul><ul><li>3. Arrêt de l’enregistrement </li></ul></ul><ul><ul><li>3. Ajustement pour faire passer le test </li></ul></ul>Présentation Code Selenium Données
  14. 21. Exemple Selenium <ul><li>Spécification : un mot recherché ne doit pas tenir compte de la casse </li></ul>« electricite » Recherche « Electricité »
  15. 22. Selenium
  16. 23. Selenium <ul><li>Les avantages </li></ul><ul><ul><li>Facilité de création des cas de tests </li></ul></ul><ul><ul><li>Assure la non régression </li></ul></ul><ul><ul><li>Teste la fonctionnalité comme le ferait un utilisateur </li></ul></ul><ul><ul><li>Testable en continu </li></ul></ul>
  17. 24. Selenium <ul><li>Les inconvénients </li></ul><ul><ul><li>Lenteurs </li></ul></ul><ul><ul><li>Tests non déterministes </li></ul></ul><ul><ul><li>Potentiellement très nombreux </li></ul></ul><ul><ul><li>Peu évolutifs et difficiles à maintenir </li></ul></ul><ul><ul><li>Crées après l’implémentation </li></ul></ul><ul><ul><li>Dépendants du navigateur </li></ul></ul><ul><ul><li>Peu compréhensibles avant d’être exécutés </li></ul></ul>
  18. 25. Fitnesse <ul><li>http://fitnesse.org </li></ul><ul><li>Mode opératoire </li></ul><ul><ul><li>0. Lancer le serveur fitnesse </li></ul></ul><ul><ul><li>1. Déclarer vos spécifications dans le wiki </li></ul></ul><ul><ul><li>2. Câbler votre code dessus (par le biais de fixture) </li></ul></ul>Présentation Code Fitnesse Données Fixtures
  19. 26. Fitnesse
  20. 27. Fitnesse
  21. 28. Fitnesse <ul><li>Les avantages </li></ul><ul><ul><li>Limite les malentendus par les exemples </li></ul></ul><ul><ul><li>Constitue une spécification exécutable (TDR) </li></ul></ul><ul><ul><li>Factorisable </li></ul></ul><ul><ul><li>Testable en continu </li></ul></ul><ul><ul><li>Centralisé </li></ul></ul><ul><li>Les inconvénients </li></ul><ul><ul><li>Ticket d’entrée </li></ul></ul><ul><ul><li>Ne teste pas l’application tout à fait comme un utilisateur </li></ul></ul>
  22. 29. Autres outils de tests fonctionnels <ul><li>Greenpepper avec XWiki ou Confluence </li></ul><ul><ul><li>http://www.greenpeppersoftware.com </li></ul></ul><ul><li>Concordion </li></ul><ul><ul><li>http://www.concordion.org/ </li></ul></ul>
  23. 30. Limites des tests fonctionnels <ul><li>Dépendant de l’état de l’application </li></ul><ul><li>Longs à écrire, à exécuter et à maintenir </li></ul><ul><li>Boucle de feedback </li></ul><ul><li>Ne donne aucun indice sur la cause </li></ul>
  24. 33. D’où vient le problème ? Frein ? Direction assistée? Boite de vitesse ? Pneus usés ?
  25. 34. Tests unitaires <ul><li>Permet de vérifier isolément que les composants fonctionnent bien </li></ul><ul><li>Tester une partie du produit </li></ul><ul><li>Simuler un comportement différent de la production </li></ul>
  26. 35. Tests unitaires <ul><li>Pour pouvoir tester unitairement : </li></ul><ul><ul><li>Les composants doivent être séparables pour être utilisés de façon isolée </li></ul></ul><ul><ul><li>Les éléments testés doivent être simples </li></ul></ul>
  27. 36. Test Driven Development <ul><li>Développement dirigé par les tests </li></ul><ul><ul><ul><ul><li>Given… When… Then </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Implémentation </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Refactoring </li></ul></ul></ul></ul>
  28. 38. <ul><li>Premier test </li></ul>
  29. 39. Quand… Avec … Alors … <ul><li>@Test </li></ul><ul><li>public void add_DeuxEtTrois_retourneCinq() { </li></ul><ul><li>int resultat = new Computer().ajoute(2, 3); </li></ul><ul><li>assertThat (resultat, is ( equalTo (5))); </li></ul><ul><li>} </li></ul>
  30. 40. Barre rouge
  31. 41. Implémentation et barre verte
  32. 42. Deuxième test
  33. 43. Généralisation
  34. 44. <ul><li>Tester une méthode qui traverse des couches </li></ul>
  35. 45. Utiliser les mocks pour tester en isolation <ul><li>public class Utilisateur { </li></ul><ul><li>private String login = « login »; </li></ul><ul><li>public boolean login(String motDePasse) { </li></ul><ul><li>UserDao userDao = new UserDao(); </li></ul><ul><li>String motDePasseDeLaBase = userDao.getPassword(login); </li></ul><ul><li>return (motDePasse==motDePasseDeLaBase); </li></ul><ul><li>} </li></ul>
  36. 46. <ul><li>@Test </li></ul><ul><li>public void login_utilisateurExisteEtPasswordOk_retourneTrue() { </li></ul><ul><li>insereUtilisateurDansLaBase (&quot;login&quot;,&quot;mot de passe correct&quot;); </li></ul><ul><li>boolean estLoggue = new Utilisateur().login(&quot;mot de passe correct&quot;); </li></ul><ul><li>assertThat (estLoggue, is ( true )); </li></ul><ul><li>supprimerUtilisateurDeLaBase (&quot;login&quot;); </li></ul><ul><li>} </li></ul>
  37. 47. Tester les cas limites <ul><li>@Test </li></ul><ul><li>public void login_utilisateurExisteEtPasswordOk_retourneTrue() { </li></ul><ul><li>insereUtilisateurDansLaBase (&quot;login&quot;,&quot;mot de passe correct&quot;); </li></ul><ul><li>boolean estLoggue = new Utilisateur().login(&quot;mot de passe correct&quot;); </li></ul><ul><li>assertThat (estLoggue, is ( true )); </li></ul><ul><li>supprimerUtilisateurDeLaBase (&quot;login&quot;); </li></ul><ul><li>} </li></ul><ul><li>@Test </li></ul><ul><li>public void login_utilisateurExisteEtPasswordIncorrect_retourneFalse() { </li></ul><ul><li>insereUtilisateurDansLaBase (&quot;login&quot;,&quot;mot de passe correct&quot;); </li></ul><ul><li>boolean estLoggue = new Utilisateur().login(« pas le bon mot de passe&quot;); </li></ul><ul><li>assertThat (estLoggue, is ( false )); </li></ul><ul><li>supprimerUtilisateurDeLaBase (&quot;login&quot;); </li></ul><ul><li>} </li></ul>
  38. 48. Factoriser <ul><li>@Before </li></ul><ul><li>public void setUp() { </li></ul><ul><li>insereUtilisateurDansLaBase(&quot;login&quot;,&quot;mot de passe correct&quot;); </li></ul><ul><li>} </li></ul><ul><li>@After </li></ul><ul><li>public void tearDown() { </li></ul><ul><li>supprimerUtilisateurDeLaBase(&quot;login&quot;); </li></ul><ul><li>} </li></ul><ul><li>@Test </li></ul><ul><li>public void login_utilisateurExisteEtPasswordOk_retourneTrue() { </li></ul><ul><li>boolean estLoggue = new Utilisateur().login(&quot;mot de passe correct&quot;); </li></ul><ul><li>assertThat (estLoggue, is ( true )); </li></ul><ul><li>} </li></ul>
  39. 49. <ul><li>Inconvénients </li></ul><ul><ul><li>Interdépendance avec la base </li></ul></ul><ul><ul><ul><li>Tests non parallélisables </li></ul></ul></ul><ul><ul><ul><li>Etat instable (si données non supprimées) </li></ul></ul></ul><ul><ul><ul><li>Potentiellement non déterministe </li></ul></ul></ul><ul><ul><li>Couplage fort </li></ul></ul><ul><ul><ul><li>Nombreux tests à modifier </li></ul></ul></ul><ul><li>Solution </li></ul><ul><ul><li>Refactorer pour permettre un branchement </li></ul></ul>
  40. 50. Création d’une veine pour le DAO <ul><li>public class Utilisateur { </li></ul><ul><li>String login = « login »; </li></ul><ul><li>UserDao userDao = new UserDao(); </li></ul><ul><li>Utilisateur(UserDao userDao) { </li></ul><ul><li>this .userDao = userDao; </li></ul><ul><li>} </li></ul><ul><li>public boolean login(String motDePasse) { </li></ul><ul><li>String motDePasseDeLaBase = userDao.getPassword(login); </li></ul><ul><li>return (motDePasse.equals(motDePasseDeLaBase)); </li></ul><ul><li>} </li></ul>
  41. 51. Utilisation de mock pour simuler d’autres comportements <ul><li>@Test </li></ul><ul><li>public void login_utilisateurExisteEtPasswordOk_retourneTrue() { </li></ul><ul><li>UserDao dao = Mockito. mock (UserDao. class ); </li></ul><ul><li>when (dao.getPassword(&quot;login&quot;)).thenReturn(&quot;mot de passe correct&quot;); </li></ul><ul><li>boolean estLoggue = new Utilisateur(dao).login(&quot;mot de passe correct&quot;); </li></ul><ul><li>assertThat (estLoggue, is ( true )); </li></ul><ul><li>} </li></ul>
  42. 52. Autre cas limite <ul><li>@Test </li></ul><ul><li>public void login_utilisateurExisteEtException_retourneFalse() { </li></ul><ul><li>UserDao dao = Mockito. mock (UserDao. class ); </li></ul><ul><li>when (dao.getPassword(&quot;login&quot;)).thenThrow( new RuntimeException()); </li></ul><ul><li>boolean estLoggue = new Utilisateur(dao).login(&quot;mot de passe correct&quot;); </li></ul><ul><li>verify (dao).getPassword(&quot;login&quot;); </li></ul><ul><li>assertThat (estLoggue, is ( false )); </li></ul><ul><li>} </li></ul>
  43. 53. Vérification du comportement <ul><li>@Test </li></ul><ul><li>public void login_utilisateurExisteEtPasswordOk_retourneTrue() { </li></ul><ul><li>UserDao dao = mock (UserDao. class ); </li></ul><ul><li>when (dao.getPassword(&quot;login&quot;)).thenReturn(&quot;mot de passe correct&quot;); </li></ul><ul><li>boolean estLoggue = new Utilisateur(dao).login(&quot;mot de passe correct&quot;); </li></ul><ul><li>verify (dao).getPassword(&quot;login&quot;); </li></ul><ul><li>assertThat (estLoggue, is ( true )); </li></ul><ul><li>} </li></ul>
  44. 54. Autres frameworks de tests <ul><li>Classiques </li></ul><ul><ul><li>JMock, Easymock </li></ul></ul><ul><li>Pour le code legacy </li></ul><ul><ul><li>Powermock, JMockit </li></ul></ul>
  45. 55. Tests unitaires <ul><li>Avantages </li></ul><ul><ul><li>Permet de sécuriser son application </li></ul></ul><ul><ul><li>… incrémentalement </li></ul></ul><ul><ul><li>Augmente la confiance </li></ul></ul><ul><ul><li>Aide à construire le logiciel </li></ul></ul><ul><li>Inconvénients </li></ul><ul><ul><li>Apprentissage </li></ul></ul><ul><ul><li>Ralentit le développement dans un premier temps </li></ul></ul>
  46. 56. Ressources complémentaires <ul><li>Tests </li></ul><ul><ul><li>Test Driven Development, K.Beck </li></ul></ul><ul><ul><li>xUnit Test Patterns, G.Meszaros </li></ul></ul><ul><ul><li>Growing Object Oriented Software, S.Freeman, N.Pryce </li></ul></ul><ul><ul><li>Working Effectively With Legacy Code, M.Feathers </li></ul></ul><ul><li>Design </li></ul><ul><ul><li>Coder Proprement, R.Martin </li></ul></ul><ul><ul><li>Refactoring, M.Fowler </li></ul></ul>
  47. 57. A retenir <ul><li>Test non automatisé = (pas de test) </li></ul><ul><li>Un bug corrigé une fois est corrigé pour toujours </li></ul><ul><li>Faites toujours passer un test au rouge avant de le passer au vert </li></ul><ul><li>Soignez le comme du code de production </li></ul><ul><li>Soignez votre code de production (boy scout rule, DRY, KISS) </li></ul>
  48. 58. Questions ? <ul><li>Votre expérience ? </li></ul><ul><li>Vos besoins ? </li></ul><ul><li>Votre ressenti ? </li></ul>

×