Tests unitaires

Description

Bonjour à tous,

Je présente aujourd'hui une version plus aboutie de ce code en ligne depuis peu. Il se compose de trois classes une interfaces et un index.php

Pourquoi ne pas utiliser PHPUnit ou SimpleTest ? Par goût de la simplicité.

La classe TestManager connait les deux autres classes.
Les classes de tests (que vous devez écrire !) héritant de TestUnitaire sont chargées via la méthode addClasse et lancées ensuite dans la méthode launch.
L'affichage comprend aujourd'hui une interface et une classe HtmlOutput.

Le tout étant soumis à vos appréciations. J'ai développé des choses en vitesse, pour savoir si je ne faisais pas fausse route.

A vous de jouer !

PS : La source ne présente que la classe TestManager. Ca vous donnera l'idée générale.

Source / Exemple :


<?php
final class TestManager {
	const METHOD_PREFIX = 'test_';
	const METHOD_INDENT = "\t";
	private $tests = array();
	/**

  • Pile de logs
  • /
private $logs = array(); /**
  • public function __construct()
  • /
public function __construct(){ assert_options(ASSERT_ACTIVE,1); assert_options(ASSERT_WARNING,0); assert_options(ASSERT_BAIL,0); assert_options(ASSERT_QUIET_EVAL,1); assert_options(ASSERT_CALLBACK,array($this,'hasFail')); } public function hasFail($file,$line,$code){ // Au dernier log (le [0] du tableau), j'ajoute le contexte de l'échec. $this->logs[0]['fail'] = TRUE; //array('file' => $file, 'line' => $line, 'code' => $code); } public function log($m,$args){ $log = array( 'method' => $m, 'args' => $args, 'fail' => FALSE, ); // travail anté-historique (du plus récent au plus ancien) // comme ça, les derniers tests (ceux qui nous préoccupent) occupent le haut du tableau array_unshift($this->logs,$log); } /**
  • vide les logs un par un en les affichant
  • /
public function drainLogs(TestOutput $obj){ while ($log = array_shift($this->logs)) { $obj->show($log['method'],$log['args'],$log['fail']); } } function addClasse($name){ $this->tests[] = $name; } function launch($out_class){ // instancier la sortie $out = new $out_class(); // travail anté-historique while ($current = array_shift($this->tests)) { if (is_subclass_of($current,'TestUnitaire')) { $obj = new $current($this); $l = strlen(self::METHOD_PREFIX); // annoncer la classe $out->classBegin($current); foreach (get_class_methods($obj) as $m) { if (substr($m, 0, $l) == self::METHOD_PREFIX) { // annoncer la methode $out->methodBegin($m); // ... je les appelle dans un environnement clean $obj->setUp(); $obj->$m(); $obj->tearDown(); // Pour ne pas surcharger la mémoire, à chaque fin de méthode, je dépile la pile des logs. $this->drainLogs($out); $out->methodEnd($m); }} $out->classEnd($current); } } } function generateClassTest($name, $output = 'php://output'){ $hdle = fopen($output, 'w'); fwrite($hdle, '<?php'. PHP_EOL . 'class ' . $name . 'Test extends TestUnitaire {' . PHP_EOL); // self::write_method('setUp',$hdle); self::write_method('tearDown',$hdle); foreach(get_class_methods($name) as $m) { self::write_method($m,$hdle); } fwrite($hdle, '}' . PHP_EOL); fclose($hdle); } function write_method($method_name, $handle){ fwrite($handle, self::METHOD_INDENT . 'function ' . $method_name . '(){'. PHP_EOL . self::METHOD_INDENT . '}' . PHP_EOL); } }

Conclusion :


J'attends vos regards externes pour faire avancer ce code.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.