fwiw J'utilise SimpleTest 1.1alpha. P>
J'ai une classe singleton et je tiens à écrire un test unitaire qui garantit que la classe est un singleton en essayant d'instancier la classe (il dispose d'un constructeur privé). P>
Ceci provoque évidemment une erreur fatale: p>
Erreur fatale: appel à FrontController privé :: __ construire () p> blockQuote>
Y a-t-il un moyen de "attraper" cette erreur fatale et de signaler un test réussi? p>
3 Réponses :
Non. L'erreur fatale empêche l'exécution du script.
Et il n'est pas vraiment nécessaire de tester un singleton de cette façon. Si vous insistez sur la vérification si le constructeur est privé, vous pouvez utiliser réflexionClass: getconstructor () < / a> p> Une autre chose à considérer est que les classes / objets singletons sont un obstacle à TTD car ils sont difficiles à moquer. P> P>
Vous pouvez utiliser un concept comme l'isolement du processus de phpunit.
Ceci signifie que le code de test sera exécuté dans un sous-processus de PHP. Cet exemple montre comment cela pourrait fonctionner. P>
<?php // get the test code as string $testcode = '<?php new '; // will cause a syntax error // put it in a temporary file $testfile = tmpfile(); file_put_contents($testfile, $testcode); exec("php $tempfile", $output, $return_value); // now you can process the scripts return value and output // in case of an syntax error the return value is 255 switch($return_value) { case 0 : echo 'PASSED'; break; default : echo 'FAILED ' . $output; } // clean up unlink($testfile);
En pratique, ce seulement B> fonctionne pour détecter les erreurs de syntaxe, car (1) un script ne survivra généralement pas isolé, (2) il est irréalisable de bootstrap une application entière comme celle-ci, (3) elle ne crée pas Un contexte de test / répétible, (4) de ne pas avoir que tout le contexte mis en place pourrait provoquer de fausses erreurs mortelles comme fonction non définie i>. Ainsi, au lieu d'exécuter PHP $ TEMPFILE CODE> Il est préférable d'exécuter
PHP -NO-php-ini --Syntax-check $ tempfile code>. PHP.net/manual/fr/Feats.commandline.option.php
Pouvez-vous prouver que? Je ne pense pas si
Eh bien, il "fonctionne" dans la console parce que je vois l'erreur fatale. Le retour $ est toujours 255 pour les six erreurs non incroyables et toujours 0 sinon. Je pense avoir besoin d'un gestionnaire d'arrêt pour accéder au code d'erreur. - Quant à PHPUnit, même si je @RuninSeparateProcessez un seul test causant une erreur fatale, il apparaît toujours comme un «E». - Votre idée est intéressante et je vous ai déjà plongé. Mais pour le faire fonctionner, je pense que je dois creuser en phpunit et écrire un patch ou un plugin. Je me demande pourquoi personne ne l'a fait auparavant. Est-il déraisonnable de s'attendre à ce que un script échoue?
Maintenant, j'ai eu vos préoccupations. Va jouer avec PHPUnit un peu, écrivez probablement du code et vous donnera un retour ..
J'ai trouvé qu'il y a une isolation personnalisable Modèle . Nous avons besoin de register_shutdown_function ('__ phpunit_shutdown', $ test, $ résultat) code>.
__ phpunit_shutdown ($ test, $ résultat) code> (en cas d'erreur) imprime uniquement une matrice sérialisée comme d'habitude, mais avec une touche code> ajoutée Code> ERROR_GET_LAST () code>. Ensuite, nous pouvons ajouter une prise en charge d'un
@ExpecectedhutDownError
code> à partir de
phpunit_util_php :: runtestjob code>, qui appellerait
processchildresult code> avec des arguments docompu (principalement stardr = '').
Belle recherche! Malheureusement, le nom de fichier du modèle est codé dur dans le code source. De plus, le @ExpectedhutDownError code> devrait être implémenté. Nous aurions besoin de Fork PHPUnit afin de produire le changement (ou je manque quelque chose?)
Le modèle d'isolation est personnalisable Par défaut A >. - Le reste est difficile à faire de Userland. Nous mettrions une classe au milieu de phpunit_util_php code> et ses descendants (
..._ par défaut code> et
..._ windows code>) pour remplacer
runtestjob code> comme indiqué ci-dessus. Ensuite, à partir de la classe de cas d'essai, nous remplacerions
exécuter code> de sorte que ici , nous pouvons instancier notre classe moyenne.
Si vous le souhaitez, créons une fourchette! (... et discutez des détails là). Pensant que l'idée est bonne et que cela ne nécessitera pas trop de changements (et de travailler).
Laissez-nous Continuez cette discussion en chat .
Voici un extrait de code complet de la réponse de MCLL afin que les gens ne doivent pas avoir à traverser les docs ...
Il n'y a pas d'unité dans un test simple;)
@Gordon I Voir I> Le jeu de mots, mais je ne comprends pas.
Peut-être Cette réponse peut l'expliquer
Les cadres de test unitaires d'Oldschool sont impropres à cela. Écrivez un PHPT pour ce test et mélangez-le dans un cas PHPUNIT / SimpleTest utilisant une regex sur la sortie.