ruby - 在 rspec 中测试多步骤工作流程

标签 ruby rspec bdd

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

我们以“购物车”系统为例,其中的购买流程可能是

  1. 当用户提交购物篮并且我们没有使用 https 时,重定向到 https
  2. 当用户提交购物篮并且我们使用 https 并且没有 cookie 时,创建并显示一个新的购物篮并发回 cookie
  3. 当用户提交到购物车并且我们使用 https 并且有一个有效的 cookie 并且新商品与第一个商品用于不同的产品时,向购物车添加一行并显示这两行
  4. 当用户提交到购物篮并且我们使用 https 并且有一个有效的 cookie 并且新商品与之前的商品相同时,增加该购物篮行的数量并显示这两条线
  5. 当用户点击购物车页面上的“结帐”并使用 https 并且有一个 cookie 并且购物车非空并且...
  6. ...

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

关于如何不那么冗长/乏味地执行此操作的任何提示?我很欣赏每个示例不应依赖于先前示例留下的状态这一想法背后的一般原则,但是当您测试多步骤过程并且任何步骤都可能出错时,为每个步骤设置上下文是不可避免地需要重新运行前 n 个步骤的所有设置,所以 ...

最佳答案

这是一种可能的方法 -- 定义一个对象,该对象为每个步骤创建必要的状态,并将其传递给每个后续步骤。基本上你需要模拟/ stub 所有设置条件的方法调用:

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

关于ruby - 在 rspec 中测试多步骤工作流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4430831/

相关文章:

ruby - 在 Jekyll 中过滤 site.related_posts

ruby-on-rails - 奇怪的问题 has_many 通过更新的 Rails 中的关联

ruby-on-rails - 如何测试 Rails Helper 是否定义了方法?

ruby - 期望创建一个新对象

ruby-on-rails - 如果有的话,rspec 相对于 test::unit 的主要优势是什么?

ruby-on-rails - 使用 capybara/rails 运行 selenium 时,如何配置服务器?

ruby-on-rails - 对大量记录进行分页

ruby-on-rails - Rspec - 未定义的方法 'let'

java - 如何在 BDD 中创建良好的可重复日期测试?

rest - API REST BDD Cucumbers Gherkins 是否应包含有关 API 或数据的具体详细信息