Je vous propose aujourd'hui un petit challenge, suite à ma rencontre aujourd'hui avec le code qui suit.
Les règles sont simples :
- Le test doit être écrit dans un pseudo-code similaire à celui de Atoum ou PHPUnit.
- Il doit être écrit sur pastebin avec une durée de vie infinie.
- Le lien correspondant doit être soumis ici en commentaire, avec éventuellement les explications correspondantes.
- Le remaniement du code est autorisé.
- La version de PHP est au minimum 5.3.
Petite précision qui a son importance en cas de remaniement, l'appel à foo::getPrevious()
effectue une requête de type restriction éventuellement gourmande en ressource sur une base de données.
<?php
class foo
{
...
public function doSomethingOnPreviousIfExists()
{
$previous = $this->getPrevious();
if ($previous !== null)
{
$previous->doSomething();
}
return $this;
}
...
}
?>
À vos marques ? Prêt ? Partez !
10 réactions
1 De Laurentj - 18/01/2011, 12:14
Perso, je ne vois pas l'intérêt de tester une méthode aussi simpliste que ça (si l'hypothèse de départ est que cette méthode est un cas réèl et ne ferais que ce qui est écrit ici). je ne ferais des tests unitaires que sur le getPrevious et doSomething... C'est une perte de temps sinon, selon moi (enfin, tout dépend aussi de l'importance de cette méthode par rapport au projet, au composant, ce que tu ne dis pas). Et je n'ajouterai des tests sur cette méthode que si elle évolue et devient plus complexe / plus critique.
Et sinon, pour en revenir au challenge, je modifierai la méthode pour retourner un boolean par exemple pour savoir si le previous existe et a été processé -> test sur la valeur de retour, en fonction du contexte qui a été initialisé pour le test (si un previous a été défini pour le test ou pas) (ou en fonction d'un test unitaire réalisé sur getPrevious())
Ensuite, j'imagine que doSomething modifie quelque chose quelque part, et donc deuxième test pour savoir si cette chose a été modifiée ou non.
il me semble qu'il y a trop peu d'information pour ton challenge, par exemple, quoi tester pour doSomething. Du coup, je ne vois pas comment traduire ça en pseudo code.
2 De usul - 18/01/2011, 12:19
Comme ça vite fait en phpunit : http://pastebin.com/JEwrbttt
Je le fais avec atoum pour voir :D
3 De mageekguy - 18/01/2011, 12:29
@Laurentj : Ce n'est pas parce que la méthode semble simple qu'il ne faut pas la tester.
D'ailleurs, dans mon cas, la plupart de mes bugs proviennent de méthodes de ce style, car justement parce qu'elles sont simples, j'y fais moins attention.
Quand au
foo::getPrevious()
etfoo::doSomething()
, ils sont testés unitairement par ailleurs, et tu peux leur faire .Et dans tous les cas, la méthode est
, si tant est qu'une méthode de classe peut avoir une plus ou moins grande par rapport à d'autres.4 De mageekguy - 18/01/2011, 12:47
@usul : Je suis d'accord avec ta solution, mais elle met justement le doigt sur le nœud du problème : comment tester que si
foo::getPrevious()
retournenull
, il n'y a aucun traitement d'effectué ?Car ton test valide le fonctionnement de la méthode lorsque
foo::getPrevious()
retourne quelque chose, pas lorsqu'elle retournenull
Bref, comment tester une non-exécution ?
Et je précise que dans mon cas,
foo::getPrevious()
retourne une instance de la classefoo
, mais ce n'est pas bien important.5 De Bruno Michel - 18/01/2011, 12:51
@usul : dans ton deuxième test, tu devrais également tester que la méthode doSomething n'est pas appelée. Enfin, c'est ce que j'aurais fait si je savais écrire des tests avec PHP.
6 De mageekguy - 18/01/2011, 12:54
@Bruno Michel : Bingo ! Là réside le challenge !
7 De usul - 18/01/2011, 12:54
Je suis tout a fait d'accord avec toi, c'est là le pb si on laisse le code comme ça.
On peut trouver un début de solution avec atoum :
http://pastebin.com/1TLeMrHy
8 De usul - 18/01/2011, 13:02
@Bruno Michel : effectivement, j'aurais pu mocker encore une fois l'autre classe pour faire un expects a 0 mais vu que ce mock n'aurait jamais été fournit, ben le test est pas judicieux je pense.
Et avec phpunit ... (sans vouloir faire la promo d'atoum bien entendu)
9 De mageekguy - 18/01/2011, 13:09
@usul : bien vu, la solution avec Atoum, je n'y avais pas pensé.
Le plus marrant est que l'idée n'est nullement de mettre Atoum et PHPUnit en compétition, c'est d'ailleurs pour cela que j'ai demandé du pseudo-code...
10 De usul - 18/01/2011, 13:49
@mageekguy Yep je me doutais bien que tu voulais pas challenger les deux, c'était juste pour montrer des approches différentes et la facilité d'utiliser les mocks dans atoum