Août 01

[Formation NOOB] Tester sans se faire détester

Vous avez lu notre article  “Débugger sans peine” et maintenant vous souhaitez passer à votre phase de test ?

Dans cette vidéo vous apprendrez pourquoi et quand tester votre application, vous découvrirez également ce qu’est un test unitaire et ce qu’il implique. 

 

POURQUOI TESTER ?

Tout projet web est découpé en différentes étapes :

  1. Phase de développement
  2. Phase de test
  3. Phase de livraison

Lors de la phase de développement, vous pouvez être amené à opérer des changements majeurs : mise à jour de plugins, injections SQL, ajout de nouveaux champs à un formulaire, etc.

En théorie, 50% de votre temps devrait être alloué à re-tester la totalité de votre application et vérifier que tout fonctionne. Pourtant, en qualité de chef de projet junior, vous avez tendance à vous reposer sur votre lead développeur pour tester l’application, et en phase de recette vous vous dites que c’est le client qui doit tester la totalité de l’application.

N’oubliez pas qu’une recette avec des centaines de bugs – qui auraient pu être détectés au développement – est une recette longue et fastidieuse, pouvant mettre votre projet en péril !

TEST UNITAIRE : S’EVITER UNE RECETTE FASTIDIEUSE

Lire et comprendre une merge request n’est pas chose évidente…  C’est là que le test unitaire va vous aider. Il va vous permettre :

  • De tester la totalité de votre application pendant que vous développez et ce à n’importe quel moment,
  • D’assurer tous les comportements attendus depuis le début de l’application,
  • De réduire le cycle de test, particulièrement la phase de recette
  • De tester les cas qui n’arrivent jamais

Il permet aussi de réaliser un test manuel sur un comportement en particulier, toutefois vous devez connaitre à l’avance le comportement de l’objet, et non son fonctionnement !

L’injection de dépendance va fortement nous aider car il nous permet de mettre facilement en œuvre les tests unitaires.Vous devez donc éviter les factories et les singletons qui vont vous compliquer la tâche.

En effet, l’idéal est de tester un seul et unique comportement : chaque test unitaire doit pouvoir être exécuté seul.

ORIENTER SON DEVELOPPEMENT

Le « Test Driven Development » ou développement orienté par le comportement attendu, ne suit plus une logique algorithmique mais une logique de comportement.

Par exemple, si vous avez des objets à ordonner comme des contrats avec plusieurs gestionnaires et que vous avez réalisé un arbre de conditions, l’idéal est de coder tous vos tests à l’avance avant de développer pas à pas votre application.

En travaillant dans ce sens, vous aurez peu de chance d’avoir des erreurs ! En effet, si vous vous trompez dans votre code et inversez deux conditions, alors votre test ne passera plus.

L’EXEMPLE DE PHP UNIT

De nombreux outils existent pour vous aider, c’est le cas de PHPUnit qui est un framework qui vous permet d’implémenter des tests de régression, en vérifiant que les exécutions correspondent aux assertions prédéfinies.

Pour l’installer, vous pouvez utiliser le gestionnaire de paquets « Composer », il vous suffit de taper la commande « composer require phpunit/phpunit –dev ».

L’avantage, c’est que vous pouvez installer PHPUnit dans votre intégration continue comme Gitlab : quand vous envoyez votre code, celui-ci lancera automatiquement sa validation.

Exemple de test :

 

PhpUnit, comme la majorité des frameworks de test, utilise les assertions pour contrôler un résultat.

PHP unit assertion

Il est important de toujours utiliser l’assertion du même type que le résultat attendu, afin d’avoir un une erreur cohérente et compréhensible si celle-ci se produit.

 

Jeu de données

Si vous avez plusieurs jeux de données à tester pour une même fonction, il est possible d’utiliser des providers qui permettent d’écrire simplement un test avec un jeu de données multiples :

 

Vous ne devez pas tester plusieurs comportements dans un seul test, car vous devez garder une visibilité la plus unitaire possible, néanmoins vous pouvez lier vos tests :

Avec la règle @depends vous pouvez créer une fonction qui dépend d’une autre, toutefois cela complexifie votre test et reste à éviter au maximum !

 

 

Vous pouvez également faire des Mocks, qui vont vous permettre de simuler une base de donner derrière votre test.

 

Exemple Mocks

Par exemple avec prophesize, celui-ci permet de donner une valeur de retour à une fonction.

Dans l’exemple nous allons donner une valeur à la fonction getCode.

Nous pourrons donc totalement faire abstraction de la base de données.

 

 

 

 

Pour conclure, les tests unitaires sont plus qu’utiles pour contrôler la pérennité de votre projet et éviter au maximum les régressions de code. Il n’est pas demandé d’avoir un test unitaire sur chaque petite fonction du code (sauf dans le cas d’un paquet open source ou public), mais sur les zones compliquées.

Les tests vous sécuriseront aussi s’il y a d’autres intervenants que vous, car vous pourrez identifier plus rapidement les erreurs et cela avant votre client.

Tout le monde est gagnant, vous car vous sécurisez votre code et votre client qui a une application plus stable.