Tester c'est douter - Linkvalue tech

Post on 09-Jan-2017

200 views 0 download

Transcript of Tester c'est douter - Linkvalue tech

#LinkValue #TheGreatPlaceToGeek

Tester c’est douter !

meetup 5 octobre 2016

Test: définition et utilisation

LinkValue #TheGreatPlaceToGeek

Tester, c’est douter ?● Evidemment !

● Tout le monde teste son code

● Test de faisabilité (poc)

● Vérification pendant le développement

● Recette

LinkValue #TheGreatPlaceToGeek

Test automatisé● C’est un code qui vérifie la validité d’un autre

● C’est un code qui surveille les régressions

● C’est un code dont l'exécution ne nécessite pas l'intervention d'un humain

LinkValue #TheGreatPlaceToGeek

Pourquoi écrire des tests ?Plus-value à court terme:

● Les tests rassurent

● Ils aident au développement

● Ils permettent certaines vérifications impossibles en manuel

LinkValue #TheGreatPlaceToGeek

Pourquoi écrire des tests ?Plus-value à moyen terme:

● VSR et VABF plus court

● Facilite l’implémentation de nouvelles fonctionnalités

● Limite voir supprime les régressions

● Facilite la migration et la refactorisation

LinkValue #TheGreatPlaceToGeek

Pourquoi écrire des tests ?Plus-value à long terme:

● Limite la dette technique

● Accélère la vitesse de développement

● Surveille/ évite le retour des bugs corrigés ● Coût des bugs amoindri

LinkValue #TheGreatPlaceToGeek

Coût des bugs

Unitaire, Intégration, Fonctionnel

LinkValue #TheGreatPlaceToGeek

Le test unitaire● Teste unitairement une portion de code

● Assure le bon fonctionnement d’une méthode

● Mock de toutes les dépendances

● Test à granularité fine

● Test de type white box

LinkValue #TheGreatPlaceToGeek

Le test d’intégration● Teste l’assemblage de plusieurs composants logiciels indépendants

● Ne vérifie pas la conformité des composants

● Assure la cohésion d’un système

● Test à granularité moyenne

● Test de type white box

LinkValue #TheGreatPlaceToGeek

Le test fonctionnel● Simule l’action d’un utilisateur

● Ne tient pas compte des différentes couches applicatives

● Vérifie le résultat général

● Test à grosse granularité

● Test de type black box

LinkValue #TheGreatPlaceToGeek

Vue globale

Les tests doubles

LinkValue #TheGreatPlaceToGeek

Fonctionnement d’un test

● Un test appelle un SUT

● SUT : System Under Test

● Si le SUT possède des dépendances, on les Mocks

● … ou on les Stubs

LinkValue #TheGreatPlaceToGeek

Définition d’un Stub● Un Stub est centré sur le SUT

● Il lui fournit une indépendance

● Il lui fournit des données utilisées pendant les tests

● Il ne fait jamais échouer le test

● “State-based testing”

LinkValue #TheGreatPlaceToGeek

Définition d’un Stub● Un Stub est centré sur le SUT

● Il lui fournit une indépendance

● Il lui fournit des données utilisées pendant les tests

● Il ne fait jamais échouer le test

● “State-based testing”

LinkValue #TheGreatPlaceToGeek

Définition d’un Mock● Un Mock est centré sur le test

● Il décide si le test échoue ou réussit

● Une assertion se fait contre le Mock

● On ne teste pas le résultat mais la manière de l’obtenir

● “Interaction testing”

LinkValue #TheGreatPlaceToGeek

Définition d’un Mock

LinkValue #TheGreatPlaceToGeek

Les autres tests doubles

● Dummy : passer en paramètre à l’objet mais n’est jamais appelé

● Fake : l’objet possède une implémentation simple qui retourne toujours le même résultat

● Spy : objet qui surveille le comportement d’un code ne pouvant être relevé

LinkValue #TheGreatPlaceToGeek

On s’en mock

● Dummy, spies, fake sont des cas spécifiques de mocks ou de stubs

● Comprendre et maitriser l’utilisation des mocks et des stubs induit l’utilisation des autres sans en avoir pleinement conscience

● De toute facon, par abus de language, on appelle tout un “mock”

Bonnes Pratiques

LinkValue #TheGreatPlaceToGeek

Avant-propos :Tests smellsTest smells définit tout type de test qui ne valide pas la qualité du code

et/ou gène le travail du développeur.

● Test difficile à comprendre et à maintenir.

● Test trop long.

● Test un faux positif ou faux négatif.

● Test avec effet de bord.

● Test multiple comportement en une fois.

LinkValue #TheGreatPlaceToGeek

● Mock toutes les dépendances

● Seule la classe testée doit être instanciée

● Tester une classe, une méthode et un comportement à la fois

● Si plusieurs comportements par méthode, faire un test pour chacun

Un test unitaire doit être unitaire

LinkValue #TheGreatPlaceToGeek

Un test unitaire doit être rapide

● Il teste la vitesse d’éxécution du script

● Ne dialogue avec personne (bdd, classe tiers, webservice …)

● Confort pour le développeur (lancer tous les tests avant chaque commit)

LinkValue #TheGreatPlaceToGeek

Un code doit toujours être testable

● Indicateur de fiabilité

● Indicateur de refactoring

LinkValue #TheGreatPlaceToGeek

CODEZ PROPRE !!!● Les tests sont le reflet de l’application

● Ils doivent être compréhensibles et maintenables

● Evite le risque de “test smell”

● Non, ce n’est pas qu’un test

● Oui, c’est grave

LinkValue #TheGreatPlaceToGeek

Testez vos cas d’erreurs

● Faites un test pour chaque cas d’erreur

● Vérifiez la nature de la réponse (boolean, exception … )

● Vérifiez le comportement de vos catch dans le cas d’un try/catch

LinkValue #TheGreatPlaceToGeek

Une seule méthode par test

● Plus simple à maintenir

● Granularité plus fine en cas de débbugage

LinkValue #TheGreatPlaceToGeek

Code: Tests:

LinkValue #TheGreatPlaceToGeek

Nommer proprement vos tests

● Indiquez la méthode testée dans le nom du test : “testMyCustomMethod”

● Indiquez le use case dan le nom du test: “testMyCustomMethodWithSecondParametersMissing”

● Le nom du test doit indiquer son comportement

LinkValue #TheGreatPlaceToGeek

Identifiez précisement les étapes

● SetUp: équivalent à un construct

● Exercise: déroulement logique du texte

● Verify: contrôle le résultat

● TearDown: équivalent à destruct

LinkValue #TheGreatPlaceToGeek

Ne laissez pas de traces

● Ajoutez et supprimez les données de test durant les phases de SetUp et TearDown

● Ne vous appuyez pas sur les fixtures

● Toujours remettre votre base de donnée à l’état initiale à la fin de chaque test

LinkValue #TheGreatPlaceToGeek

Gérez vos données

● Les intéractions avec la base de données doivent être testées lors de tests fonctionnels

● Recréez votre database et vos fixtures avant de lancer vos tests

LinkValue #TheGreatPlaceToGeek

Vos tests sont des classes comme les autres

● Stockez vos paramètres et dépendances dans des attributs

● Découplez vos méthodes réutilisables (DRY)

● Utilisez les principes SOLID

LinkValue #TheGreatPlaceToGeek

LinkValue #TheGreatPlaceToGeek

Ne vous focalisez pas sur le code coverage, mais gardez un ratio de 100% mininum

● 100% ne couvre pas tous les cas de figure

● Moins, c’est la certitude de ne pas couvrir “du tout” une partie du code

● Si moins de 100, alors combien et pourquoi ?

● C’est mettre en péril la valeur qualitative des tests

LinkValue #TheGreatPlaceToGeek

Aucun test n’est futile● Tester vos Models

● Tester vos getters et setters

● Oui ca sert (principalement en TDD)

● Ca prend cinq minutes à écrire

* attention : aucun test n’est futile! Mais il est inutile de tester le code qui ne vous appartient pas (librairie tierce/framework …)

LinkValue #TheGreatPlaceToGeek

N’écrivez pas les tests à la fin

● Ecrivez vos tests durant le développement

● Un test est plus simple à écrire quand le code est récent

● Il illustre la mise en pratique du code

● Il complète la doc

● Il limite les “tests smells”

LinkValue #TheGreatPlaceToGeek

Evitez les valeurs fixes

● Sauf si c’est dans les specs

● Les tests ne doivent pas bloquer l’évolution du code

● Cela provoque un couplage avec le code

LinkValue #TheGreatPlaceToGeek

Evitez la logique

● Pas de boucle ou de conditions dans un test

● Utilisez les dataProviders pour jouer le test avec plusieurs valeurs

● Simplifiez la compréhension de vos tests

LinkValue #TheGreatPlaceToGeek

Mauvaises idées

● Modifier les paramètres d’environnement pour faire passer certains tests

● Certains tests ne fonctionnent pas partout

● Mon test unitaire est long car …

● Certains tests sont aléatoirement en échec

Cas pratique

LinkValue #TheGreatPlaceToGeek

Mise en situationContexte:

1. On récupère depuis un api externe des données utilisateurs

2. On enregistre les données en base via un orm

3. On retourne une réponse

LinkValue #TheGreatPlaceToGeek

Les différents tests

Rouge : Les tests unitaires

Orange : les tests d’intégrations

Vert : les tests fonctionnels

LinkValue #TheGreatPlaceToGeek

Ecrire un Test unitaire● Déclarez les mocks

des dépendances de la classe testée en attribut de la classe de test.

● Idem pour la config

LinkValue #TheGreatPlaceToGeek

Ecrire un Test unitaire● Dans l’exercise,

définissez le comportement de votre test

● Dans le verify assurez vous de la réponse attendue. Un test doit contenir au moins une assertion

LinkValue #TheGreatPlaceToGeek

Ecrire un Test unitaire● Testez les appels des

méthodes de vos mocks ainsi que le nombre d’appels

● Testez également les paramètres passés en argument

● Surveillez toutes les étapes d’avancement de votre code

LinkValue #TheGreatPlaceToGeek

Ecrire un Test unitaire● Ne tester que des comportements attendus: inutile de s’assurer qu’une

méthode non utilisée n’est pas appelée

● N’utilisez pas les dataProviders pour tester plusieurs fois le même cas de figure.

● Faites toujours attention de tester le comportement attendu de votre code et non le code écrit

LinkValue #TheGreatPlaceToGeek

Ecrire un Test d’intégration● On ne teste pas le bon

fonctionnement des différentes couches, on teste leurs intéractions

● On mock les dépendances externes (webservice, BDD …) qui pourrait faire échouer les tests alors que le code est bon

● On ne vérifie pas le résultat des dépendances, on vérifie la réponse de la méthode testée

LinkValue #TheGreatPlaceToGeek

Ecrire un Test d’intégration

● Utilisez intelligemment les mocks, mais pas trop

● Dans cet exemple l’objet User ne devrait pas être mocké

● Ne mockez que les classes qui comportent des dépendances externes

LinkValue #TheGreatPlaceToGeek

Ecrire un Test d’intégration

● Un test d’intégration intervient dès lors qu’on teste plusieurs classes

● Il ne remplace pas un test unitaire, il le complète

● Les tests d’intégrations sont souvent plus lents et plus fragiles que les tests unitaires

LinkValue #TheGreatPlaceToGeek

Ecrire un test fonctionnel● Ne vous appuyez pas sur les

données de fixtures

● Utilisez des transactions pour vos appels en bdd

● Configurer le lancement de la transaction dans le setUp et son rollback dans le tearDown

LinkValue #TheGreatPlaceToGeek

Ecrire un test fonctionnel● Ne vous occupez pas du code

● Testez uniquement le résultat

● Testez une valeur fixe seulement si elle est unique

● Ne testez qu’un seul comportement par test

LinkValue #TheGreatPlaceToGeek

Ecrire un test fonctionnelLes tests fonctionnels doivent être lancés sur un serveur applicatif dédié et iso prod.

Pour les dépendances externes (API) : ● Si une version de test existe, configurez et appelez l’api de test● Si vous appelez une api de prod, connaissez les données retournées

Pour la base de données: ● Appelez une base de données de test● Utilisez des fixtures pour remplir la base de donnée

Test Driven Developement

LinkValue #TheGreatPlaceToGeek

Késako ?

● TDD : Acronyme de Test Driven Development

● Développement piloté par les tests

● Ecrire le test avant le code

LinkValue #TheGreatPlaceToGeek

Process TDD1. On écrit le test

2. On vérifie que le test échoue

3. On écrit le code le plus vite possible

4. On vérifie que tous les tests soient verts

5. On refactorise le code proprement

LinkValue #TheGreatPlaceToGeek

Pourquoi travailler en TDD

● Structure le code avant écriture

● Participe intégralement au process de développement

● Evite l’écriture de tests qui valident le code existant

LinkValue #TheGreatPlaceToGeek

Difficultés● Simple à comprendre, moins à utiliser

● Nécessite de la pratique

● Force à réapprendre une logique de développement

● Chercher le rouge, ne jamais le commiter

La Team DD

LinkValue #TheGreatPlaceToGeek

Problèmatique TDD

● Ca sert à quoi d’écrire les tests en premiers ?

● Je dois tout tester ou seulement certaines choses ?

● Que dois-je tester en premier ?

LinkValue #TheGreatPlaceToGeek

BDD à la rescousse

● TDD : Incite le développeur à se poser les bonnes questions

● BDD : Behaviour Driven Development.Aide les différents corps de métiers à se poser les bonnes questions ensemble

LinkValue #TheGreatPlaceToGeek

Scénariser les tests● Les tests ne sont plus écrits par les développeurs à partir du cahier

des charges

● Client et développeurs décident ensemble des tests à écrire

● Ecriture de scénario décrivant le comportement de l’application et donc le comportement à tester

● Utilisation d’un langage commun entre le client et le développeur : le gherkin

LinkValue #TheGreatPlaceToGeek

Comment tu me causes ?

● Utilisation d’un “ubiquitous language” gherkin

● Compréhensible par l’ensemble des métiers

● Utilise la matrice Given/When/Then pour écriture de scénario

LinkValue #TheGreatPlaceToGeek

Ecrire un scénario● Votre scénario décrit le

comportement attendu

● Given pose le contexte

● When indique le déroulement de l’action

● Then le résultat attendu

LinkValue #TheGreatPlaceToGeek

Coder un scénario● Le code reprend les étapes

setUp / exercise / Verify

● BDD permet de coder des tests fonctionnels

● Ces tests fonctionnels serviront alors de scénario pour les tests unitaires

LinkValue #TheGreatPlaceToGeek

BDD + TDD1. (story) Pour chaque scénario décrivant la fonctionnalité

2. (RED) Lancer le scénario qui va échouer

3. (RED) Définir la première étape

4. (GREEN) Ecrire le code de l’étape pour la faire passer

5. (REFACTOR) Refactorer le code et répéter les étapes 4&5 pour chaque étape jusqu’à ...

6. (GREEN) Le scénario passe

7. (REFACTOR) Refactorer le code de l’application

LinkValue #TheGreatPlaceToGeek

BDD + TDD

● L’écriture des tests est dirigée par les scénarios

● BDD n’est pas un remplacant de TDD

● Concept de développement Agile

LinkValue #TheGreatPlaceToGeek

BDD + TDD + DDD

LinkValue #TheGreatPlaceToGeek

Pour Conclure● Tester c’est inutile : Seuls les mauvais développeurs ne doutent pas

de leur code

● C’est trop difficile : Non, mais cela demande de l’investissement. Les bonnes pratiques et les patterns de tests aident pour démarrer

● C’est irréaliste : Regardez autour de vous ! Sur github tout type de projet et de toute taille les utilisent et fonctionnent. C’est plus régulier de trouver un projet couvert par les tests

● C’est pas mon job : As tu déjà réfléchis à une reconversion ? Les tests c’est du code

LinkValue #TheGreatPlaceToGeek

Questions ?

LinkValue #TheGreatPlaceToGeek

Sources:

● http://www.thedarksideofthewebblog.com/les-mocks-sont-ils-nos-amis/

● http://blog.viseo-bt.com/tests-unitaires-dintegration-fonctionnel-metier-comment-les-definir/

● http://blog.xebia.fr/2008/04/11/les-10-commandements-des-tests-unitaires/

● http://blog.soat.fr/2013/09/10-trucs-infaillibles-pour-rater-ses-tests-unitaires-en-toutes-circonstances-12/

● http://agilitateur.azeau.com/post/2010/09/05/Stub-et-Mock-montent-sur-sc%C3%A8ne

● http://agilitateur.azeau.com/post/2011/04/12/Pour-en-finir-avec-les-Stubs-et-les-Mocks

● http://xunitpatterns.com/

● http://xunitpatterns.com/Test%20Stub.html

● http://fr.slideshare.net/ohoareau/intro-sur-les-tests-unitaires