J'ai une application Rails avec plus de 2000 exemples dans mes tests RSpec. Inutile de dire que c'est une application volumineuse et qu'il y a beaucoup à tester. Exécuter ces tests à ce stade est très inefficace et parce que cela prend tellement de temps, nous sommes presque sur le point d'être découragés de les écrire avant de pousser une nouvelle version. J'ai ajouté --profile à mes spécifications.opts pour trouver les exemples les plus longs et il y en a au moins 10 qui prennent en moyenne 10 secondes à s'exécuter. Est-ce normal parmi vous les experts RSpec? Est-ce que 10 secondes sont trop longues pour un exemple? Je me rends compte qu'avec 2000 exemples, il faudra un temps non négligeable pour tout tester à fond - mais à ce stade, 4 heures, c'est un peu ridicule.
Quel genre de temps voyez-vous pour vos exemples les plus anciens? Que puis-je faire pour dépanner mes spécifications existantes afin de déterminer les goulots d'étranglement et d'accélérer les choses. Chaque minute aiderait vraiment à ce stade.
la source
perftools.rb
avec votre framework de test pour comprendre ce qui vous consomme le plus de temps. Prenez les 10 meilleurs appels et essayez de les éliminer / les parcourir. Puis répétez, jusqu'à ce que vous soyez heureux.Réponses:
10 secondes, c'est un temps très long pour un seul test à exécuter. Mon instinct est que votre cible de spécifications exécute simultanément des tests unitaires et d'intégration. C'est une chose typique dans laquelle les projets tombent et à un certain stade, vous devrez surmonter cette dette technique si vous voulez produire plus, plus rapidement. Il existe un certain nombre de stratégies qui peuvent vous aider à le faire ... et je vais en recommander quelques-unes que j'ai utilisées dans le passé.
1. Séparer l'unité des tests d'intégration
La première chose que je ferais est de séparer l'unité des tests d'intégration. Vous pouvez le faire soit en:
La philosophie est que vous voulez que vos builds réguliers soient rapides - sinon les gens ne seront pas trop heureux de les exécuter souvent. Revenez donc sur ce territoire. Exécutez rapidement vos tests réguliers et utilisez un serveur d'intégration continue pour exécuter la version la plus complète.
Un test d'intégration est un test qui implique des dépendances externes (par exemple, base de données, WebService, file d'attente et certains diraient FileSystem). Un test unitaire teste simplement l'élément de code spécifique que vous souhaitez vérifier. Il devrait fonctionner rapidement (9000 en 45 secondes est possible), c'est-à-dire que la plupart devrait fonctionner en mémoire.
2. Convertir les tests d'intégration en tests unitaires
Si la majeure partie de vos tests unitaires est inférieure à votre suite de tests d'intégration, vous avez un problème. Cela signifie que les incohérences commenceront à apparaître plus facilement. À partir de là, commencez à créer plus de tests unitaires pour remplacer les tests d'intégration. Les choses que vous pouvez faire pour aider dans ce processus sont:
Une fois que vous avez un ou plusieurs tests unitaires appropriés pour remplacer un test d'intégration, supprimez le test d'intégration. Les tests en double ne font qu'empirer la maintenance.
3. N'utilisez pas d'appareils
Les luminaires sont mauvais. Utilisez plutôt une usine (machiniste ou factorybot). Ces systèmes peuvent créer des graphiques de données plus adaptables et, plus important encore, ils peuvent créer des objets en mémoire que vous pouvez utiliser, plutôt que de charger des éléments à partir d'une source de données externe.
4. Ajouter des vérifications pour empêcher les tests unitaires de devenir des tests d'intégration
Maintenant que vous avez mis en place des tests plus rapides, il est temps de vérifier pour empêcher que cela ne se reproduise.
Il existe des bibliothèques dont l'enregistrement actif de monkey patch génère une erreur lors de la tentative d'accès à la base de données (UnitRecord).
Vous pouvez également essayer le couplage et le TDD, ce qui peut aider votre équipe à écrire des tests plus rapides car:
5. Utilisez d'autres bibliothèques pour résoudre le problème
Quelqu'un a mentionné spork (accélère les temps de chargement de la suite de tests sous rails3), hydra / parallel_tests - pour exécuter des tests unitaires en parallèle (sur plusieurs cœurs).
Cela devrait probablement être utilisé en dernier. Votre véritable problème se situe tout au long des étapes 1, 2 et 3. Résolvez-le et vous serez mieux placé pour attribuer une infrastructure supplémentaire.
la source
Pour un excellent livre de recettes sur l'amélioration des performances de votre suite de tests, consultez la présentation Grease Your Suite .
Il documente une accélération de 45x dans le temps d'exécution de la suite de tests en utilisant des techniques telles que:
la source
Vous pouvez utiliser Spork. Il prend en charge 2.3.x,
https://github.com/sporkrb/spork
ou ./script/spec_server qui peut fonctionner pour 2.x
Vous pouvez également modifier la configuration de la base de données (ce qui accélère essentiellement les requêtes de base de données, etc.), ce qui augmentera également les performances des tests.
la source
10 secondes par exemple semblent très longues. Je n'ai jamais vu une spécification qui prenait plus d'une seconde, et la plupart en prennent beaucoup moins. Testez-vous les connexions réseau? La base de données écrit? Le système de fichiers écrit?
Utilisez autant que possible des simulations et des stubs - ils sont beaucoup plus rapides que l'écriture de code qui atteint la base de données. Malheureusement, les moqueries et les stubbing prennent également plus de temps à écrire (et sont plus difficiles à faire correctement). Vous devez équilibrer le temps passé à écrire les tests par rapport au temps passé à exécuter les tests.
J'appuie le commentaire d' Andrew Grimm sur la recherche d'un système CI qui pourrait vous permettre de paralléliser votre suite de tests. Pour quelque chose de cette taille, cela pourrait être la seule solution viable.
la source
Plusieurs personnes ont mentionné Hydra ci-dessus. Nous l'avons utilisé avec beaucoup de succès dans le passé. J'ai récemment documenté le processus de mise en service de l'hydra: http://logicalfriday.com/2011/05/18/faster-rails-tests-with-hydra/
Je suis d'accord avec le sentiment que ce type de technique ne devrait pas être utilisé comme un substitut à l'écriture de tests bien structurés et rapides par défaut.
la source
Si vous utilisez des modèles ActiveRecord, vous devez également prendre en compte le coût du cryptage BCrypt.
Vous pouvez en savoir plus à ce sujet sur ce billet de blog: http://blog.syncopelabs.co.uk/2012/12/speed-up-rspec-test.html
la source
plus rapide_require gem pourrait vous aider. De plus, votre seul moyen est (comme vous l'avez fait) de profiler et d'optimiser, ou d'utiliser spork ou quelque chose qui exécute vos spécifications en parallèle pour vous. http://ruby-toolbox.com/categories/distributed_testing.html
la source
Vous pouvez suivre quelques conseils simples pour déterminer d'abord où est passé la plupart du temps si vous ne les avez pas déjà essayés. Regardez l'article ci-dessous:
https://blog.mavenhive.in/7-tips-to-speed-up-your-webdriver-tests-4f4d043ad581
Je suppose que la plupart de ces étapes sont génériques qui s'appliqueraient également quel que soit l'outil utilisé pour les tests.
la source
Supprimez la suite de tests existante. Sera incroyablement efficace.
la source