web-dev-qa-db-fra.com

PHPUNIT - Les tests sont douloureusement lents

Je plongeai plus profondément et plus profond dans le monde des tests unitaires.

Une question que j'ai rencontrée, et c'est là que je voudrais des commentaires, c'est quand on dirige plusieurs suites de tests, peut-être que c'est juste moi, mais je dois utiliser le paramètre -Process-isolement pour mes tests. Je peux courir l'une de mes suites individuellement sans problème, mais que les 6-7 suites que je dispose jusqu'à présent avec 180 affirmations étalées entre eux échouent si je cours sans isolement. Le problème est que l'utilisation de ce paramètre facilite le test de test pendant 35 minutes, par rapport aux 2,5 minutes habituelles. C'est une attente loooong.

Le problème est associé à l'utilisation de conteneurs diabots moqués pour des tests et des conteneurs spécifiques ne sont pas correctement réinitialisés lorsque des tests suites sont en chaînées. Les propriétés statiques définies sur un conteneur di-pour tester les défaillances attendus rendent les tests dans la suite suivante. Le conteneur a un paramètre pouvant contenir l'objet contenu dans un VaR statique, pour renvoyer la même instance à chaque appel. Un singleton déguisé. Et cela fonctionne bien au niveau de l'application, c'est juste une nuisance pour les tests.

Je pourrais éviter ce paramètre de conteneur et code l'application pour ne pas utiliser de propriétés statiques, mais éviter une construction de langues utile pour des raisons d'une méthodologie semble être une overkill.

Peut-être que je vais faire quelque chose de mal (j'espère bien sûr alors!) Mais j'ai l'impression que si on veut exécuter des tests avec la SUPT dans un état propre pour chaque test, il n'ya pas de déplacement à l'aide de l'isolement. Cela rend le test très chronométré et en prend une joie un peu. J'ai effectivement contourné le problème par des suites et des tests sur les suites et les tests individuellement lorsque je suis codé et en exécutant la suite en arrière-plan avant les engagements majeurs.

Est-ce que je suis normal et y a-t-il un moyen de contrer cela? Comment les testeurs vous assurent-vous que le temps de test est raisonnable? Comment les statiques sont-elles traitées pour ne pas influencer les tests?

Toute perspicacité appréciée/commentaire appréciée.

44
stefgosselin

Vous avez plusieurs problèmes.

Le premier est l'isolement du processus. Normalement, il ne devrait pas être nécessaire et vous voulez seulement l'utiliser pour déterminer quel test spécifique est celui qui brise fatalement vos tests. Comme vous vous êtes noté, c'est terriblement lent, ce qui est quelque chose que vous ne pouvez pas résoudre. Vous voudrez peut-être vouloir Désactiver la sauvegarde des vars globaux qui enregistre cependant des millisecondes par test.

Le deuxième problème, qui conduit à votre premier problème, est que votre code n'est pas testable car les VAR statiques sont conservés lors des tests - mon problème de singleton le plus détesté. Vous pouvez résoudre ce problème en fournissant une méthode "nettoyage" ou "réinitialiser" dans vos conteneurs de dépendance. Celles-ci seront appelées à partir de la méthode setUp() dans votre classe de cas d'essai principal et réinitialisez tout à un état propre.

La vitesse

Concernant le temps d'exécution des tests - j'ai récemment écrit une Entrée de blog sur la découverte de quels tests étaient trop lents. Généralement, les tests sont trop lents si vous ne pouvez pas les exécuter après avoir enregistré le fichier ou chaque commit sur votre propre boîte. 10 secondes est à peine acceptable pour moi. Plus vous avez des tests, le plus lent les exécutera être.

Si vous avez vraiment 35 minutes, puis divisez vos tests en groupes sensibles afin que vous puissiez exécuter les éléments nécessaires sur votre propre ordinateur - uniquement les tests qui testent le code que vous avez modifié. Pyrus, le programme d'installation suivant-gen PEAR a la fonctionnalité NIFTY pour détecter automatiquement et exécuter les tests qui doivent être exécutés , en fonction des fichiers que vous avez modifiés. PHPUNIT n'a pas cela, mais vous pouvez imiter cela à la main et phpunit --group .. :)

Prenez toujours soin de la moqueur de services Web et de bases de données, ou du moins à exécuter la base de données avec uniquement les données nécessaires pour chaque test unique. En attente de 3 secondes pour une réponse de services Web dans un test qui vérifie si vous pouvez enregistrer l'utilisateur à la base de données est quelque chose que vous ne voulez jamais.

34
cweiske

L'une des choses que je fais habituellement lorsque je teste avec MySQL au lieu de SQLite's :memory: Est que j'ajouterai Hash::setRounds(5); à l'intérieur tests/CreatesApplication.php Traitez-la. J'ai vécu cela fera les tests surtout avec MySQL tant plus rapidement:

public function createApplication()
{
    $app = require __DIR__ . '/../bootstrap/app.php';

    $app->make(Kernel::class)->bootstrap();

    // TODO: DON'T FORGET TO IMPORT HASH OBJECT ON TOP
    Hash::setRounds(5);

    return $app;
}
4
Hassan Azimi