Comme tout les programmeurs vous faites des tests unitaires. En php, On utilise souvent PHPUnit.
quand je lance mes tests je vois cela.
C’est un peu triste. Et encore j’ai activé la couleur !.
il existe des variantes avec --testdox
12345678
$ bin/phpunit --testdox
PHPUnit 4.8-ge1cc585 by Sebastian Bergmann and contributors.
Spark\Spark
[x] It creates a string from data
[x] It dont care if input is string
[x] It works with float number
[x] It s not divide by 0
C’est un peu mieux.
Il existe aussi --debug
1234567891011121314
PHPUnit 4.8-ge1cc585 by Sebastian Bergmann and contributors.
Starting test'Spark\SparkTest::testItCreatesAStringFromData'.
.
Starting test'Spark\SparkTest::testItDontCareIfInputIsString'.
.
Starting test'Spark\SparkTest::testItWorksWithFloatNumber'.
.
Starting test'Spark\SparkTest::testItSNotDivideBy0'.
.
Time: 69 ms, Memory: 4.50Mb
OK (4 tests, 4 assertions)
Mais on a un peu fait le tour
Les Listeners de PHPUnit
On peux surcharger l’affichage de PHPunit et cela grâce au listener.
Comment enregistrer un listener
Il suffit d’éditer phpunit.xml et de rajouter les lignes suivantes
Mais pour aujourd’hui, Je vais faire plus simple je vais hériter de la classe PHPUnit_TextUI_ResultPrinter si je n’ai pas envie de réécrire toutes les méthodes.
Plein d’utilisation de Listener
Des statistiques sur les tests
Quel est le test qui prend le plus de temps ? Facile avec le Listener suivant.
12345678910111213141516171819202122232425262728
<?phpclassMaxListenerextendsPHPUnit_TextUI_ResultPrinter{public$maxTime=0;private$suites=0;private$endedSuites=0;publicfunctionstartTestSuite(PHPUnit_Framework_TestSuite$suite){$this->suites++;}publicfunctionendTestSuite(PHPUnit_Framework_TestSuite$suite){$this->endedSuites++;if($this->suites>$this->endedSuites){return;}echoPHP_EOL;echo"le test le plus long prend $this->maxTime seconde(s)";}publicfunctionendTest(PHPUnit_Framework_Test$test,$time){$this->maxTime=max($time,$this->maxTime);}}
Avec ma librairie que j’ai développé dans les posts précédents.
On peux libérer de la mémoire en mettant à null les mocks à la fin du test. (exemple trouvé sur github mybuilder/phpunit-accelerator)
123456789101112131415
classFreeListenerimplementsPHPUnit_Framework_TestListener{// .. // les autres methodes vides.publicfunctionendTest(PHPUnit_Framework_Test$test,$time){$refl=newReflectionObject($test);foreach($refl->getProperties()as$prop){if(!$prop->isStatic()&&0!==strpos($prop->getDeclaringClass()->getName(),'PHPUnit_')){$prop->setAccessible(true);$prop->setValue($this,null);}}}}
On pourrait faire cela sur un tearDown()
Jouer des fixtures
Normalement il n’y a pas de fixture dans PHPUnit. Mais en pratique pour tester certaines méthodes dans les repository, ben il n’y pas beaucoup le choix. On peux refaire la base, dropper le schéma, un truncate à chaque test ou memory::sqlite. Mais sur certaines bases de données, c’est un peu compliqué. Une solution est de vider la base entre chaque suites de tests. Une proposition
1234567891011121314151617181920212223242526272829
classDBListenerimplementsPHPUnit_Framework_TestListener{// .. // les autres methodes vides.publicfunctionstartTestSuite(PHPUnit_Framework_TestSuite$suite){$this->truncateDb();}publicfunctiontruncateDb(){// vide la table..}publicfunctionfixtureDb(){// joue les fixtures}publicfunctionstartTest(PHPUnit_Framework_Test$test){// si le nom du test contient truncateif(strpos($test->getName(),'truncate')){$this->truncateDB();}//if(strpos($test->getName(),'fixture')){$this->truncateDB();$this->fixtureDB();}}}
Si le nom du test contient truncate et fixture alors on force le truncate et/ou fixture. Une autre possibilité est d’implémenter la méthode setUpBeforeClass dans le test. Cette méthode est jouée juste avant l’instantiation de la classe. C’est du statique, donc pas forcement la joie..
<?phpclassFailureListenerextendsPHPUnit_TextUI_ResultPrinter{private$suites=0;private$endedSuites=0;public$failTest=array();publicfunctionstartTestSuite(PHPUnit_Framework_TestSuite$suite){$this->suites++;}publicfunctionaddFailure(PHPUnit_Framework_Test$test,PHPUnit_Framework_AssertionFailedError$e,$time){$this->failTest[]=$test->getName();}publicfunctionstartTest(PHPUnit_Framework_Test$test){}publicfunctionendTestSuite(PHPUnit_Framework_TestSuite$suite){$this->endedSuites++;if($this->suites>$this->endedSuites){return;}$cli=implode('|',$this->failTest);echoPHP_EOL."Pour relancer seulement les tests qui ne passent pas ajoutez".PHP_EOL;echo"--filter '($cli)'";}}
Le script en action.
12345678910
bin/phpunit -c build/phpunit.xml
PHPUnit 4.5.1 by Sebastian Bergmann and contributors.
Configuration read from /home/marc/prog/un-projet-pro/build/phpunit.xml
............................................................................................F.F...........
Pour relancer seulement les tests qui ne passent pas ajoutez
--filter '(testObjectNeedUpdate|testUpdateObject)'Time: 958 ms, Memory: 17.25Mb
La seconde fois avec la commande qui va bien.
12345678
bin/phpunit -c build/phpunit.xml --filter '(testObjectNeedUpdate|testUpdateObject)'PHPUnit 4.5.1 by Sebastian Bergmann and contributors.
Configuration read from /home/marc/prog/un-projet-pro/build/phpunit.xml
FF
Time: 116 ms, Memory: 9.25Mb
Conclusion
Il y a encore pas mal d’utilisation je pense au nyan-cat ! Ou l’utilisation avec des notifications sur le bureau par exemple ici.
La librairie mcamuzat/spark a été initialement fait pour ce post. J’ai passé finalement plus de temps sur la création de la librairie.