juillet
2008
Sans vouloir recréer PHPUnit, j’ai crée – dans le cadre d’une formation PHP Best Practices que j’ai donnée – un lanceur de tests.
Il s’agit d’une classe statique, regardez, c’est très simple :
class ProduitsTest
{
public static function testVendreProduits()
{
echo __FUNCTION__, ' OK';
}
public static function testVendreTropDeProduitsFails()
{
echo __FUNCTION__, ' OK';
}
}
Bon elle ne sert à rien, ses méthodes ne font qu’afficher leur nom puis ‘OK’, en fait ce qu’il y a à l’interieur importe peu pour ce billet blog.
Ce qui importe, c’est comment les appeler.. ? Très simple me direz-vous, un simple appel static :
ProduitsTest::testVendreProduits();
ProduitsTest::testVendreTropDeProduitsFails();
Super, mais comment faire si j’ai 50 méthodes de tests ? Et si j’ai 50 classes qui définissent 50 méthodes de tests chacune ? Je ne vais pas les lancer à la main tout de même : la conception d’un lanceur autommatique s’impose.
Mon idée : Faire implémenter une interface à toutes mes classes de tests, Lancable par exemple. Utiliser ensuite la reflection et la SPL pour créer un itérateur capable de lancer toutes les méthodes statiques de toutes les classes « Lancables » définies dans PHP.
class MethodIterator extends FilterIterator
{
public function __construct(ReflectionClass $a)
{
parent::__construct(new ArrayIterator($a->getMethods()));
}
public function accept()
{
return $this->current()->isStatic() && strpos($this->current()->getName(),'test') == 0;
}
}
class ClassIterator extends FilterIterator
{
public function __construct()
{
parent::__construct(new ArrayIterator(get_declared_classes()));
}
public function accept()
{
return $this->current()->implementsInterface('Lancable');
}
public function current()
{
return new ReflectionClass(parent::current());
}
}
Ca s’utilise très simplement :
foreach( new classIterator() as $class) {
foreach (new MethodIterator($class) as $method) {
$method->invoke($class->getName());
}
}
Au lancement, la classe ClassIterator analyse toutes les classes déclarées (y compris les classes internes de PHP). L’itérateur est un filtre, il ne renverra que les classes qui implémentent l’interface « Lancable« , et celle-ci n’a en réalité besoin de définir aucune méthode, mais juste d’exister au sein du code PHP.
Chaque classe issue de l’itérateur est donc lançable. Il faut alors l’analyser, chercher toutes ses méthodes statiques, vérifier qu’elles commencent par le mot ‘test’, et les invoquer.
C’est ce que fait la classe MethodIterator
2 foreach l’un dans l’autre, c’est pas joli; Qui a une idée pour rendre ceci récursif ?
1 Commentaire + Ajouter un commentaire
Commentaires récents
Archives
- novembre 2010
- août 2010
- juillet 2010
- juin 2010
- mai 2010
- avril 2010
- mars 2010
- février 2010
- janvier 2010
- décembre 2009
- novembre 2009
- octobre 2009
- septembre 2009
- août 2009
- juillet 2009
- juin 2009
- mai 2009
- avril 2009
- mars 2009
- février 2009
- janvier 2009
- décembre 2008
- novembre 2008
- octobre 2008
- septembre 2008
- août 2008
- juillet 2008
- juin 2008
- mai 2008
- avril 2008
- mars 2008
- février 2008
- janvier 2008
- décembre 2007
- novembre 2007
- octobre 2007
- septembre 2007
- août 2007
- juillet 2007
- juin 2007
- mai 2007
- avril 2007
- mars 2007
- février 2007
Tu n’as pas besoin de le rendre récursif puisqu’il n’y a aucune raison qu’un troisième niveau apparaisse un jour