Prev Next

Chapitre 11. Pratiques de test

 

Vous pouvez toujours écrire davantage de tests. Cependant, vous vous rendrez rapidement compte que seule une fraction des tests auxquels vous pensez est réellement utile. Ce que vous voulez, c'est écrire des tests qui échouent même si vous pensez qu'ils devraient fonctionner, ou des tests qui réussissent même si vous pensez qu'ils devraient échouer. Une autre façon d'envisager cela consiste à le faire en terme de coûts/bénéfices. Vous voulez écrire des tests qui vous paient en retour avec des informations.

 
  --Erich Gamma

Pendant le développement

Lorsque vous avez besoin de modifier la structure interne d'un logiciel sur lequel vous êtes en train de travailler pour la rendre plus facile à comprendre et moins chère à modifier sans modifier son comportement visible, une suite de tests est inestimable pour appliquer de façon sure ces refactorings comme on les appelle. Sans cela, vous ne pourrez pas vous détecter que vous avez cassé le système en réalisant la restructuration.

Les conditions suivantes vous aideront à améliorer le code et la conception de votre projet, tant que vous utiliserez des tests unitaires pour vérifier que les étapes de transformation dues au refactoring préservent bien le comportement et n'introduisent pas d'erreurs :

  1. Tous les tests unitaires fonctionnent correctement.

  2. Le code transmet des principes de conception.

  3. Le code ne contient pas de redondances.

  4. Le code contient le nombre minimal de classes et de méthodes.

Quand vous avez besoin d'ajouter de nouvelles fonctionnalités au système, écrivez d'abord les tests. Puis, vous aurez terminé quand les tests s'exécuteront. Cette pratique sera discutée en détail dans le prochain chapitre.

Pendant le débogage

Quand vous recevez un rapport de bug, vous pourriez être tenté de le corriger aussi vite que possible. L'expérience prouve que cette impulsion ne vous rendra pas service : il est probable que ce défaut en provoque un autre.

Vous pouvez maîtriser cette impulsion en suivant ce qui suit :

  1. Vérifiez que vous pouvez reproduire le défaut.

  2. Trouvez la démonstration la plus ciblée possible du défaut dans le code. Par exemple, si un nombre s'affiche incorrectement dans une sortie écran, trouvez l'objet qui calcule ce nombre.

  3. Ecrivez un test automatisé qui échoue maintenant mais qui réussira quand le défaut sera corrigé.

  4. Corrigez le défaut.

Trouver le moyen fiable le plus ciblé pour reproduire le défaut vous offre l'opportunité de vraiment en examiner la cause. Le test que vous écrivez va améliorer les chances que lorsque vous corrigerez le défaut, vous le fassiez vraiment du fait que le nouveau test réduit la probabilité de défaire cette correction lors de futures modifications du code. Tous les tests écrits avant réduisent la probabilité de causer par inadvertance un problème différent.

 

Le test unitaire offre de nombreux avantages :

  • Tester conforte les auteurs de code et les relecteurs dans le fait que les correctifs produisent des résultats corrects..

  • Créer des cas de tests est un bon moyen de conduire les développeurs à découvrir des cas limites.

  • Tester fournit un bon moyen de capturer les régressions rapidement et de s'assurer qu'elles ne seront pas répétées deux fois.

  • Les tests unitaires fournissent des exemples fonctionnels de la façon d'utiliser une API et peuvent aider significativement à l'effort de documentation.

Globalement, le test unitaire intégré minimise les coûts et les risques de toute modification individuelle. Il permettra au projet de mener [...] des améliorations majeures d'architecture [...] rapidement et avec confiance.

 
  --Benjamin Smedberg
Prev Next
1. Automatiser les tests
2. Objectifs de PHPUnit
3. Installer PHPUnit
4. Ecrire des tests pour PHPUnit
Dépendances des tests
Fournisseur de données
Tester des exceptions
Tester les erreurs PHP
Tester la sortie écran
Assertions
assertArrayHasKey()
assertClassHasAttribute()
assertClassHasStaticAttribute()
assertContains()
assertContainsOnly()
assertCount()
assertEmpty()
assertEqualXMLStructure()
assertEquals()
assertFalse()
assertFileEquals()
assertFileExists()
assertGreaterThan()
assertGreaterThanOrEqual()
assertInstanceOf()
assertInternalType()
assertJsonFileEqualsJsonFile()
assertJsonStringEqualsJsonFile()
assertJsonStringEqualsJsonString()
assertLessThan()
assertLessThanOrEqual()
assertNull()
assertObjectHasAttribute()
assertRegExp()
assertStringMatchesFormat()
assertStringMatchesFormatFile()
assertSame()
assertSelectCount()
assertSelectEquals()
assertSelectRegExp()
assertStringEndsWith()
assertStringEqualsFile()
assertStringStartsWith()
assertTag()
assertThat()
assertTrue()
assertXmlFileEqualsXmlFile()
assertXmlStringEqualsXmlFile()
assertXmlStringEqualsXmlString()
5. Le lanceur de tests en ligne de commandes
Options de la ligne de commandes
6. Fixtures
Plus de setUp() que de tearDown()
Variantes
Partager les Fixtures
Etat global
7. Organiser les tests
Composer une suite de tests en utilisant le système de fichiers
Composer une suite de tests en utilisant la configuration XML
8. Tester des bases de données
Systèmes gérés pour tester des bases de données
Difficultés pour tester les bases de données
Les quatre phases d'un test de base de données
1. Nettoyer la base de données
2. Configurer les fixtures
3–5. Exécuter les tests, vérifier les résultats et nettoyer
Configuration d'un cas de test de base de données PHPUnit
Implémenter getConnection()
Implémenter getDataSet()
Qu'en est-il du schéma de base de données (DDL)?
Astuce: utilisez votre propre cas de tests abstrait de base de données
Comprendre DataSets et DataTables
Implémentations disponibles
Attention aux clefs étrangères
Implementer vos propres DataSets/DataTables
L'API de connexion
API d'assertion de base de données
Faire une assertion sur le nombre de lignes d'une table
Faire une assertion sur l'état d'une table
Faire une assertion sur le résultat d'une requête
Faire une assertion sur l'état de plusieurs tables
Foire aux questions
PHPUnit va-t'il (re-)créer le schéma de base de données pour chaque test ?
Suis-je obligé d'utiliser PDO dans mon application pour que l'extension de base de données fonctionne ?
Que puis-je faire quand j'obtiens une erreur « Too much Connections (Trop de connexions) » ?
Comment gérer les valeurs NULL avec les DataSets au format XML à plat / CSV ?
9. Tests incomplets et sautés
Tests incomplets
Sauter des tests
Sauter des tests en utilisant @requires
10. Doublure de test
Bouchons
Objets simulacres (Mock Objects)
Bouchon et simulacre pour Web Services
Simuler le système de fichiers
11. Pratiques de test
Pendant le développement
Pendant le débogage
12. Développement dirigé par les tests
Exemple du compte bancaire
13. Développement dirigé par le comportement
Exemple du jeu de Bowling
14. Analyse de couverture de code
Spécifier les méthodes couvertes
Ignorer des blocs de code
Inclure et exclure des fichiers
Cas limites
15. Autres utilisations des tests
Documentation agile
Tests transverses à l'équipe
16. Générateur de squelette
Générer un squelettre de classe de cas de test
Générer un squelette de classe à partir d'une classe de cas de test
17. PHPUnit et Selenium
Selenium Server
Installation
PHPUnit_Extensions_Selenium2TestCase
PHPUnit_Extensions_SeleniumTestCase
18. Journalisation
Résultats de test (XML)
Résultats de test (TAP)
Résultats de test (JSON)
Couverture de code (XML)
Couverture de code (TEXTE)
19. Etendre PHPUnit
Sous-classe PHPUnit_Framework_TestCase
Ecrire des assertions personnalisées
Implémenter PHPUnit_Framework_TestListener
Sous classer PHPUnit_Extensions_TestDecorator
Implémenter PHPUnit_Framework_Test
A. Assertions
B. Annotations
@author
@backupGlobals
@backupStaticAttributes
@codeCoverageIgnore*
@covers
@coversNothing
@dataProvider
@depends
@expectedException
@expectedExceptionCode
@expectedExceptionMessage
@group
@outputBuffering
@requires
@runTestsInSeparateProcesses
@runInSeparateProcess
@test
@testdox
@ticket
C. Le fichier de configuration Configuration
PHPUnit
Série de tests
Groupes
Inclure et exclure des fichiers de la couverture de code
Journalisation
Moniteurs de tests
Configurer les réglages de PHP INI, les constantes et les variables globales
Configurer les navigateurs pour Selenium RC
D. Index
Index
E. Bibliographie
F. Copyright