2010-12-13 103 views
6

我想了解使用rspec测试多步骤工作流程的习惯用法或最佳实践。在rspec中测试多步骤工作流程

让我们作为一个例子的“购物车”系统,其中当用户提交到篮下,我们没有使用HTTPS购买过程中可能会

  1. ,重定向到https
  2. 当用户提交到篮子,我们使用的是HTTPS并没有什么饼干,创建并显示一个新的篮子里,当用户提交篮发送回一个cookie
  3. ,我们使用的是HTTPS,有一个有效的cookie和新的项目是不同的产品比第一个项目,添加一条线到篮子并显示两条线
  4. 当用户提交到购物篮并且我们使用的是https并且有一个有效的cookie,并且新项目用于与前一个产品相同的产品时,增加该购物篮的数量并显示两行
  5. 当用户单击“结帐”篮子页面上,并使用HTTPS并有一个cookie和篮非空和...
  6. ...

我读过http://eggsonbread.com/2010/03/28/my-rspec-best-practices-and-tips/,其职责IA每个“它阻止”应该只包含一个断言:不是进行计算,然后在同一个块中测试多个属性,在上下文中使用“before”来创建(或检索)测试中的对象并将其分配给@some_instance_variable,然后将每个属性测试写为一个单独的块。这有点帮助,但是在上面所述的测试步骤n需要执行步骤[1..n-1]的所有设置的情况下,我发现自己要么复制设置代码(显然不好),要么创建大量辅助函数越来越笨拙的名字(def create_basket_with_three_lines_and_two_products),并在每一步的前一个块中连续调用它们。

如何做到这一点不太冗长/繁琐任何提示吗?我很欣赏这个想法背后的一般原则,即每个例子不应该依赖于前面例子留下的状态,但是当你测试一个多步骤的过程并且在任何步骤都会出错的时候,为每一步设置上下文是不可避免地会需要重新运行所有前面的n个步骤中的设置,所以......

回答

2

这里是一个可能的方法 - 定义创建每个步骤的必需状态的对象和直传它对于每个连续的。基本上你需要模拟/存根方法调用所有的设置条件:

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

肯定来不及了OP,但是这可能是方便别人 - RSpec的步骤宝石似乎对这个确切情况要建:https://github.com/LRDesign/rspec-steps

看看https://github.com/railsware/rspec-example_stepshttps://github.com/jimweirich/rspec-given也是值得的。我决定采用rspec步骤,但我很忙,这些其他选项实际上可能对我所知道的更好。

+0

现在您已经使用rspec-steps gem,您是否满意解决多步骤尊重问题的结果? – Angela 2015-05-11 04:16:55

+0

@Angela:恩,好问题。我简单地使用了它,但小组的其他成员并不热衷于此,所以我们最终放弃了它,并有更多的重复。我*认为*理由是我们需要更多的可读性,但这是一个很长的时间....在这一点上,我发现真正的集成测试是最简单的,只是写作一个大功能,每个测试只执行一次“工作流程”。不是最习惯或流行的方法,但我喜欢可读性。 – Nerdmaster 2015-05-11 15:56:58

+0

我在rspec中只看到一个'describe'? – Angela 2015-05-13 05:54:47