Comment écrire un test qui passe en boucle à travers une gamme de valeurs à l'aide de RSpec?
J'ai une question très simple Ruby mise en œuvre d'un jeu appelé "FizzBuzz" (soit, compte tenu d'un nombre d'entrée, il retourne "Fizz" si le nombre est multiple de 3, les "Buzz" si multiple de "5", "FizzBuzz" si plusieurs à la fois et le nombre d'origine si elle ne rentre pas tout de la condition précédente):
class FizzBuzz
def answer(number)
multiple3 = number%3 == 0
multiple5 = number%5 == 0
return case
when (multiple3 and multiple5) then "FizzBuzz"
when multiple3 then "Fizz"
when multiple5 then "Buzz"
else number
end
end
end
J'ai écrit un test à l'aide de RSpec pour valider chacune de ces conditions:
require "rspec"
require "./fizzBuzz"
RSpec.describe "#answer" do
it "returns Buzz when number is multiple of 3" do
result = FizzBuzz.new.answer(3)
expect(result).to eq("Fizz")
end
it "returns Buzz when number is multiple of 5" do
result = FizzBuzz.new.answer(5)
expect(result).to eq("Buzz")
end
it "returns a number when the input number is neither multiple of 3 nor 5" do
result = FizzBuzz.new.answer(11)
expect(result).to eq(11)
end
end
Le test fonctionne parfaitement, cependant, je suis en utilisant du béton de valeurs (c'est à dire 3, 5 et 11).
Ma question est: est ce que si je voulais tester mon FizzBuzz Ruby script à l'aide d'une large gamme de valeurs (par exemple de 1 à 10000)?
Je sais que je peux résoudre ce problème en utilisant chacun des boucles et des cas directement dans RSpec, cependant, mon souci est que si dans mon test j'ai adopter les mêmes expressions conditionnelles dans le script Ruby pour être testé (c'est à dire when number%3 == 0 then "Fizz"
, etc.) Je vais finir de tester mon code à l'aide d'un RSpec script qui suit exactement la même logique que le script pour être testé, donc le test sera probablement passer avec succès.
Quelle serait l'alternative? Existe-il des bonnes pratiques pour écrire des tests à l'aide d'un large pool de valeurs (par ex. à l'aide d'une boucle) plutôt que de codé en dur ou des valeurs spécifiques?
- Le point de l'ensemble de l'unité de contrôle est de vérifier que le code de la comparer avec des résultats connus entrées. Si vous testez votre code en utilisant un autre code, puis il ya une bonne chance que vous aurez un bug dans tous les deux et le test de réussite ou d'échec quand il ne devrait pas.
- Votre code n'a que 4 résultats possibles. Pourquoi pensez-vous qu'il existe un bénéfice à tester 10000 itérations?
Vous devez vous connecter pour publier un commentaire.
Un demi-point de passage ici est de faire une boucle par des réponses possibles à votre RSpec tests. En gardant votre code SEC est importante, mais en gardant vos tests SEC et c'est parfois sous-estimée.
Comment quelque chose comme cela:
De cette façon, vous pouvez ajouter des tests facilement en les ajoutant à la
expected_values
de hachage, mais si le nom de la méthode modifiée ou quelque chose de similaire, vous n'avez qu'à modifier dans un seul endroitJe vais faire semblant que vous demandez dans le cas où vous en aurez vraiment besoin et ce cas simple, c'est juste pour l'illustration.
Il est Bien à partir de Tests qui permettent de résoudre ce genre de problème dans une élégante manière, avec cette approche, vous devez trouver certains biens (par exemple, l'ajout de deux nombre le résultat est supérieur au nombre deux et a + b = b + a...). Et vous utilisez un cadre qui permettra de générer de façon aléatoire les entrées afin de couvrir un plus grand spectres que si c'était un cas particulier.
Il est un framework qui peut aider dans Ruby ainsi.
Une excellente explication de la Propriété en Fonction des Tests http://fsharpforfunandprofit.com/posts/property-based-testing/ (avis de non responsabilité le code est dans Fsharp)
Vous pouvez utiliser les cycles à l'intérieur de vos spécifications techniques:
RSpec a maintenant intégré dans les fonctionnalités sympas comme partagé des exemples. Plus d'infos ici.
Comme un résultat que nous allons obtenir partagé tel groupe (à noter que ce groupe peut être utilisé dans d'autres tests):
Et des tests seront plus lisibles et écrit en plus "rspec-comme" moyen:
À l'appui de la accepté de répondre, je voudrais suggérer habillage de l'ensemble de test dans un contexte de bloc, de sorte que le test reste isolé du reste du code: