RSpec et Cucumber en valent-ils vraiment la peine?

12

Je sais que la plupart des programmeurs RoR testent des toxicomanes et je comprends les avantages d'une grande suite de tests, mais quand je commence à tester, je n'ai jamais une si grande suite et je me demande toujours "Suis-je en train de tester correctement? Y a-t-il vraiment une efficacité?". J'ai souvent affaire à des tests d'intégration testant uniquement le comportement de l'application.

Premièrement, les tests en valent-ils vraiment la peine? Je veux dire, le temps passé à écrire des tests en vaut-il vraiment la peine?

Ensuite, j'utilise RSpec, j'ai récemment découvert Cucumber, l'utilise depuis un moment mais je ne sais pas si l'écriture de toutes ces étapes en vaut vraiment la peine? Je sais que je peux réutiliser des étapes mais je ne sais jamais si ces étapes sont trop complètes ou non: par exemple, j'ai utilisé un Given I am logged in as (.+)mais je ne sais pas si je dois le dire dans sa définition Given there's a user called $1car il peut dupliquer l'utilisateur s'il est créé mais cela ne vaut pas la peine d'avoir toujours une étape avant Given I am logged in as (.+). C'est beaucoup de code qui sera peut-être rarement utile. Je suppose qu'il n'y a pas de nouveaux bugs sur les pièces testées tous les jours ... Donc, Cucumber vaut-il vraiment la peine par rapport à RSpec?

Cydonia7
la source

Réponses:

13

Mon 'ah-ha!' des moments sur les tests dans Ruby and Rails sont venus quand je me suis vraiment assis et j'ai lu les ressources définitives sur le sujet, les livres Rspec et Cucumber . J'ai partagé votre dédain initial pour le concombre, mais j'ai réalisé que je regardais l'image sous un mauvais angle.

Fondamentalement, Cucumber concerne le BDD (développement axé sur le comportement) - vous utilisez Cucumber pour planifier vos fonctionnalités, sur quoi vous allez travailler ensuite. Hmm, ensuite, vous voulez que les utilisateurs puissent promouvoir des messages sur un forum ou quelque chose (pour voler un exemple;)) Donc, vous écrivez quelque chose de simple.

Given I am logged in
And I can see the post "BDD is awesome"
When I vote the post up
Then the post should have one more vote
And the page should show a message thanking me for my vote.

Notez qu'il n'y a à peu près aucune référence à quelque chose de code. Cela vient dans vos pas. Lorsque vous refactorisez votre code, vous devrez peut-être modifier vos définitions d'étape, mais le comportement (votre fonctionnalité) n'aura jamais besoin de changer.

Maintenant, chaque fois que vous exécutez votre fonctionnalité Cucumber, vous serez à peu près guidé à travers la façon de tester la fonctionnalité à l'aide de TDD (développement piloté par les tests). Cela se fait à un niveau inférieur à l'aide de RSpec.

Première exécution - ma première définition d'étape n'est pas définie. Copiez le bloc pour le définir dans par exemple user_steps.rb ou même session_steps.rb car il concerne les utilisateurs et leurs sessions. Maintenant, comment définissez-vous qu'un utilisateur est connecté? Vous pouvez les suivre via le processus de connexion.

Given /^I am logged in$/ do
  visit login_path
  fill_in :name, :with => 'Joe'
  fill_in :password, :with => 'Password'
  click_button 'submit'
end

Devrait être tout heureux. Deuxième étape.

Given /^I can see the post "(.+)"$/ do |name|
  visit post_path(Post.find_by_name(name))
end

Encore une fois assez facile. Notez que si nous refaisons totalement notre processus de connexion, ou comment nos messages sont définis et affichés, nous n'avons pas à changer le comportement. Troisième étape.

When /^I vote the post up$/ do
  pending 
end 

Voici où vous commencez à parler de nouvelles fonctionnalités, mais vous ne savez pas encore comment cela va fonctionner. Comment votez-vous pour un article? Vous pouvez cliquer sur une image d'un +1 ou quelque chose, qui envoie un message ajax à un contrôleur, qui renvoie JSON, ou quelque chose du genre. Alors maintenant, vous pouvez passer à des tests Rspec purs.

  • Testez votre vue pour vous assurer que l'image +1 est affichée,
  • Testez votre contrôleur qu'il se comporte correctement lorsqu'il reçoit une demande ajax donnée du bon format (les chemins heureux et malheureux - que se passe-t-il si un ID de message non valide est reçu? Que se passe-t-il si l'utilisateur a utilisé ses 25 votes positifs en une journée? Augmente-t-il correctement le nombre de votes?)
  • Testez votre javascript pour qu'il réponde correctement lorsqu'il reçoit un blob de JSON au bon format (met-il à jour l'image +1 pour montrer qu'il a été utilisé? (En pensant à Google+ ici ...) Est-ce qu'il affiche le message de remerciement? Etc. )

Tout cela n'affecte pas le comportement - mais lorsque vous avez terminé de traiter les tests de niveau inférieur, il sera trivial de remplir la définition d'étape pour savoir comment voter un message. Cela pourrait être aussi simple que click_link '+1'. Et le reste des étapes consiste à tester les résultats, ce qui devrait encore être simple à faire. Et lorsque vous avez terminé, vous savez que votre fonctionnalité est terminée et terminée. Si le comportement nécessaire change, vous pouvez modifier votre fonctionnalité, sinon vous pouvez modifier votre code d'implémentation en toute sécurité.

J'espère que cela a du sens. Tout cela m'a échappé, mais je pense que cela démontre la différence entre BDD et TDD, et pourquoi le concombre et RSpec répondent à des besoins différents.

sevenseacat
la source
Cela m'a vraiment aidé. Mais j'ai une autre question: j'ai commencé un projet en utilisant RSpec pour tester à la fois les contrôleurs et les vues, le code est couvert à 90% par des tests. Pensez-vous que j'ai vraiment besoin de concombre et que je passe du temps à écrire des étapes et des scénarios maintenant? Je veux dire, je peux faire tout ça avec RSpec de toute façon.
Cydonia7
@Skydreamer: Probablement pas nécessaire, mais cela pourrait être une bonne pratique. Tant que vous faites des tests, vous êtes sur la bonne voie :)
sevenseacat
10

Les tests, à mon avis, sont un art. Faire TDD (en utilisant RSpec ou tout autre framework) donne au départ l'impression de "perdre votre temps". Ceci est compréhensible car vous n'écrivez aucun code de production.

Cependant, vous commencez à voir les avantages de TDD lorsque vous devez améliorer votre base de code tout en vous assurant que tout le reste fonctionne. TDD vous aide à détecter les erreurs de régression le plus tôt possible. Cela m'a sauvé des jours de travail car j'avais des tests ciblés qui ont mis en évidence mes erreurs.

De plus, les tests peuvent être bénéfiques pour les révisions de code, car votre réviseur peut voir quels scénarios vous testez et comment votre code est destiné à être utilisé.

Une fois que vous entrez dans le swing de TDD, faire autre chose semble mal.

David Weiser
la source
2
+1 bien que parlant d'expérience, "entrer dans le swing de TDD" est un effort herculéen en soi et très difficile à faire pour la majorité des développeurs.
Wayne Molina
@Wayne M: D'accord. Entrer dans le groove TDD est difficile, mais les avantages sont énormes. :)
David Weiser
C'est difficile de le dire à la légère ... j'essaie depuis des années de me mettre dans la tête :)
Wayne Molina
Oh oui, ça vaut bien l'effort.
sevenseacat
2

Mon point de vue est que vous avez raison sur le front du concombre. Écrire toutes ces étapes représente beaucoup de problèmes et les avantages ne justifient pas la douleur. J'ai beaucoup écrit sur les six inconvénients de l'utilisation de Cucumber ici: Pourquoi s'embêter avec les tests de concombre?

Les tests unitaires et les tests d'intégration réguliers, effectués soit avec Rspec ou Test :: Unit ont beaucoup de sens, mais heureusement, ils sont beaucoup plus rapides à écrire que les tests Cucumber. D'une part, vous pouvez utiliser du Ruby pur au lieu d'avoir à combattre la syntaxe verbeuse et maladroite de Gherkin.

Jack Kinsella
la source
2
Je peux dire en toute sécurité que je suis en désaccord avec chacun de vos points sur les tests de concombre. * Il ne casse pas les bons éditeurs de texte (mon gedit le mettra en surbrillance et le complètera très bien), * vous ne devez copier aucune configuration de test de votre configuration Rspec existante vers votre configuration Cucumber (les deux ensembles de tests s'exécutent à des niveaux très différents de granularité), * si vous ne pouvez pas être cohérent à propos de nommer vos pages qui ne sont pas la faute de Cucumber (Rails ne vous permettra pas d'appeler des routes différentes choses à différents jours, alors pourquoi Cucumber devrait-il?) (à suivre)
sevenseacat
1
* Vous dites quelle est la convention sur les fichiers de pas mais dites ensuite que vous ne savez pas où chercher pour suivre la convention? Pourquoi la promotion d'une publication se ferait-elle dans autre chose que post_steps.rb? * Vos fonctionnalités ne sont pas censées être du code, donc la verbosité n'est pas pertinente - vos fonctionnalités sont de la documentation sur le comportement de votre application; * Et enfin, je ne peux que critiquer la «réutilisation du code décourageant» si vous le faites mal .
sevenseacat
2

Ce que je crois personnellement, c'est cela RSpec testing is a definite must. Imaginons par exemple que vous souhaitiez écrire une nouvelle fonctionnalité, et qui fasse également référence à une autre fonctionnalité, et cette fonctionnalité peut être référencée avec un autre module ou une autre méthode. Alors, comment pouvez-vous vous assurer que ce que vous écrivez ne casse aucune autre partie de l'application?

Supposons que vous avez une grande application et que vous avez codé quelque chose de trivial par rapport à l'application globale, allez-vous retester l'application entière en cliquant sur chaque lien de l'application pour vous assurer qu'elle fonctionne à chaque fois que vous modifiez une seule ligne de code?

Cependant, je crois que le test du concombre n'est pas un must. Je pense que les tests d'intégration utilisant RSpec lui-même ont plus de sens jusqu'à ce que et à moins que vous ne deviez faire vérifier les tests par votre client. D'après mon expérience, c'est RARE. Si votre équipe est entièrement composée de développeurs, je pense que vous devriez plutôt remplacer les étapes Cucumber pour les tests de fonctionnalités RSpec. Et je pense qu'après la RSpec 3 DSL, les tests sont à peu près lisibles.

Ex:

Définition de l'étape de concombre:

Given /^I am logged in$/ do
  visit login_path
  fill_in :name, :with => 'Joe'
  fill_in :password, :with => 'Password'
  click_button 'submit'
end

Test de fonctionnalité RSpec:

feature 'Given the user is logged in' do
      visit login_path
      fill_in :name, :with => 'Joe'
      fill_in :password, :with => 'Password'
      click_link_or_button 'submit'
end

Je pense que plutôt que d'avoir des fonctionnalités Cucumber, les fonctionnalités RSpec font la même chose sans le mal de tête supplémentaire d'écrire une autre définition d'étape.

En dehors de cela, c'est aussi purement votre propre préférence.

J'espère que cela pourrait vous aider à comprendre un peu.

Sankalp Singha
la source
0

À mon avis, la première chose est de faire la différence entre les pratiques et les cadres concrets. Le concombre n'est pas BDD, RSpec n'est pas TDD.

Si vous voulez tester votre système RSpec, c'est un bon outil, vous pouvez faire TDD ou BDD avec RSpec, en fait TDD et BDD sont la même chose. Quelqu'un dit "BDD, son TDD est bien fait" et je suis totalement d'accord avec cela, BDD essaie avant tout de tester des fonctionnalités / comportements au lieu de tester des méthodes / classes. En fait, le TDD que Kent Beck décrit ses caractéristiques, mais BDD aide beaucoup de gens à comprendre cette différence clé et sa grande contribution de Dan North à la communauté du développement.

Utilisez Cucumber si vous sentez que vous avez besoin d'un meilleur outil pour communiquer avec les gens d'affaires, par exemple si le concombre permet à vos gens d'affaires ou au propriétaire du produit d'aider l'équipe à rédiger ou à réviser des scénarios. D'autres personnes aiment le concombre parce que ces scénarios sont une très bonne documentation en direct d'un système, si vous sentez que vous avez besoin de ce type de documentation, essayez le concombre.

En résumé:

  • Si vous voulez faire du TDD / BDD vous-même ou votre équipe -> essayez RSpec
  • Si vous voulez une meilleure façon de communiquer avec l'entreprise avec les histoires et les scénarios utilisateur -> essayez le concombre
  • Si vous voulez une documentation en direct de vos fonctionnalités système -> essayez le concombre.

Bien sûr, les deux derniers ont un coût élevé, vous devez évaluer si vous en avez vraiment besoin et en vaut la chandelle, cette décision dépend entièrement de votre projet et de votre environnement et de la décision qui vous appartient.

Mais rappelez-vous toujours que RSpec et Cucumber ne sont que des outils et que les outils résolvent des problèmes concrets, quel problème vous voulez résoudre?, Posez-vous cette question et vous êtes probablement mieux placé pour sélectionner le bon outil. Être un meilleur programmeur est de prendre ces décisions et non d'utiliser le framework / outil / bibliothèque / technologie X ou Y.

AlfredoCasado
la source