2010-12-13 67 views
6

Je voudrais connaître les idiomes ou les meilleures pratiques pour tester un flux de travail en plusieurs étapes à l'aide de rspec.test d'un flux de travaux en plusieurs étapes dans rspec

Prenons comme exemple un système « panier », où le processus d'achat pourrait être

  1. lorsque l'utilisateur soumet au panier et nous ne sommes pas en utilisant https, redirigent vers https
  2. lorsque l'utilisateur soumet à panier et nous utilisons https et il n'y a pas de cookie, créer et afficher un nouveau panier et renvoyer un cookie
  3. lorsque l'utilisateur soumet à panier et nous utilisons https et il y a un cookie valide et le nouvel article est pour un autre produit que le premier article, ajouter une ligne au panier et afficher les deux lignes
  4. lorsque l'utilisateur soumet au panier et nous utilisons https et il y a un cookie valide et le nouvel article est pour le même produit qu'un précédent, incrémenter la quantité de la ligne de panier et afficher les deux lignes
  5. lorsque l'utilisateur clique sur 'Commander' sur la page du panier et utilise https et il y a un cookie et le panier est non vide et ...
  6. ...

J'ai lu http://eggsonbread.com/2010/03/28/my-rspec-best-practices-and-tips/ qui ia conseille que chaque « il bloque » ne devrait contenir qu'une seule assertion: au lieu de faire le calcul puis de tester plusieurs attributs dans le même bloc, utiliser un "avant" dans un contexte pour créer (ou récupérer) l'objet sous test et l'assigner à @some_instance_variable, puis écrivez chaque test d'attribut en tant que bloc distinct. Cela aide un peu, mais dans un cas comme décrit ci-dessus où l'étape n de test nécessite de faire toute la configuration pour les étapes [1..n-1] je me trouve soit en dupliquant le code d'installation (évidemment pas bon) ou en créant beaucoup de fonctions auxiliaires avec des noms de plus en plus lourds (def create_basket_with_three_lines_and_two_products) et en les appelant consécutivement dans chaque étape avant le bloc.

Des conseils sur la façon de le faire moins verbeusement/fastidieusement? J'apprécie le principe général derrière l'idée que chaque exemple ne doit pas dépendre de l'état laissé par les exemples précédents, mais lorsque vous testez un processus en plusieurs étapes et que les choses peuvent mal tourner à n'importe quelle étape, va inévitablement exiger de réexécuter toute la configuration pour les n étapes précédentes, donc ...

Répondre

2

Voici une approche possible - définir un objet qui crée l'état nécessaire pour chaque étape et le transmettre pour chaque étape successive. Fondamentalement, vous devez railler/stub la méthode appelle à toutes les conditions de configuration:

class MultiStep 
    def initialize(context) 
    @context = context 
    end 

    def init_vars 
    @cut = @context.instance_variable_get(:@cut) 
    end 

    def setup(step) 
    init_vars 
    method(step).call 
    end 

    def step1 
    @cut.stub(:foo).and_return("bar") 
    end 

    def step2 
    step1 
    @cut.stub(:foo_bar).and_return("baz_baz") 
    end 
end 

class Cut # Class Under Test 
    def foo 
    "foo" 
    end 
    def foo_bar 
    "foo_bar" 
    end 
end 

describe "multiple steps" do 
    before(:each) do 
    @multi_stepper = MultiStep.new(self) 
    @cut = Cut.new 
    end 

    it "should setup step1" do 
    @multi_stepper.setup(:step1) 
    @cut.foo.should == "bar" 
    @cut.foo_bar.should == "foo_bar" 
    end 

    it "should setup step2" do 
    @multi_stepper.setup(:step2) 
    @cut.foo.should == "bar" 
    @cut.foo_bar.should == "baz_baz" 
    end 

end 
1

Certainement trop tard pour OP, mais cela pourrait être utile pour les autres - le joyau rspec étapes semble être construit pour cette situation exacte : https://github.com/LRDesign/rspec-steps

Il peut être utile de regarder https://github.com/railsware/rspec-example_steps et https://github.com/jimweirich/rspec-given ainsi. Je me suis installé sur les pas rspec, mais j'étais pressé et ces autres options pourraient être meilleures pour tout ce que je sais.

+0

maintenant que vous avez utilisé rspec-steps gem êtes-vous satisfait du résultat pour résoudre le problème de respect en plusieurs étapes? – Angela

+0

@Angela: Hmm, bonne question. Je l'ai utilisé brièvement, mais le reste du groupe ne l'aimait pas, alors nous avons fini par l'abandonner et avoir plus de duplication. Je pense que le raisonnement était que nous avions besoin de plus de lisibilité, mais cela fait longtemps ... À ce stade, je trouve que les vrais tests d'intégration sont plus faciles à écrire comme de grandes fonctions qui font un seul flux de travail par test. Pas l'approche la plus idiomatique ou populaire, mais j'aime la lisibilité. – Nerdmaster

+0

Je vois donc juste un seul 'describe' dans le rspec? – Angela