如何使用Capybara&测试多步骤表单最小测试? [英] How can I test multistep forms with Capybara & Minitest?

查看:79
本文介绍了如何使用Capybara&测试多步骤表单最小测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个单页Sinatra应用程序,该应用程序具有多步骤表单/向导界面.如果我想用水豚来测试表格,是否需要为每个测试重复所有步骤?我希望避免这样的事情:

I have a single page Sinatra app that has a multistep form/wizard interface. If I want to test the form with Capybara, will need to repeat all the steps for each test? I'm hoping to avoid something like this:

it "visits the home page" do 
  vist "/"
  page.should have_content('foo')
end

it "clicks the first button" do 
  vist "/"
  page.should have_content('foo')
  button_click("Next")
end

it "clicks the second button" do 
  vist "/"
  page.should have_content('foo')
  button_click("Next")
  page.should_have_content('bar')
end

it "clicks the third button" do 
  vist "/"
  page.should have_content('foo')
  button_click("Next")
  page.should_have_content('bar')
  button_click("Next")
end

我找到了有关

I found an article about nested tests using RSpec and Capybara, but haven't been able to get a similar technique to work with Minitest.

推荐答案

我已经为您做过一些研究,并将与您分享我发现的内容.

I've done some research for you, and I'll share with you what I've found.

为此,您应该考虑将您的Minitest测试转换"为

In order for doing this, you should consider "converting" your Minitest tests, to specs. This gives you access for similar syntax, as RSpec's - describe with capability of nesting them.

我将简化代码以提供示例,但是应该清楚地将逻辑放在哪里.

我们来看几个例子.

1).让我们对Array做一些简单的测试:

1). Let's do some simple test for Array:

require "minitest/autorun"

describe Array do
  before do
    @arr = []
  end

  describe "when initialized" do
    it "is empty" do
      @arr.length.must_equal 0
    end
  end
end

这应该过去了,这里没有什么好看的.

This should pass, nothing really fancy here.

2).让我们添加另一个describe,嵌套在我们拥有的describe中:

2). Let's add another describe, nested to one we have:

describe Array do
  before do
    @arr = []
  end

  describe "when initialized" do
    it "is empty" do
      @arr.length.must_equal 0
    end

    describe "when element added" do
      it "length reflects the change" do
        @arr << "a"
        @arr.length.must_equal 1
      end
    end
  end
end

这也有效-元素已添加到数组中,并且其length指示正确.

This also works - an element has been added to the array, and its length indicates that properly.

3).让我们尝试嵌套另一个块.我们希望保留@arr << "a",因此,如果添加另一个元素,@arr.length将为2.让我们看看:

3). Let's try nesting another block. We're hoping, that @arr << "a" will be preserved, so if we add another element, @arr.length will be 2. Let's see:

describe Array do
  before do
    @arr = []
  end

  describe "when initialized" do
    it "is empty" do
      @arr.length.must_equal 0
    end

    describe "when element added" do
      it "length reflects the change" do
        @arr << "a"
        @arr.length.must_equal 1
      end

      describe "when another element added" do
        it "length also reflects the change" do
          @arr << "b"
          p @arr
          @arr.length.must_equal 2
        end
      end
    end
  end
end

describe嵌套在另一个describe-中,就像我们对RSpec 所做的那样,但不幸的是,似乎@arr << "a"的结果并未保留,并且嵌套的describe@arr.length也是1.

describe is nested within another describe - as we would do for RSpec, but unfortunately, it seems that the result of @arr << "a" is not preserved, and the nested describe's @arr.length is also 1.

我在代码中保留了p @arr,因此您可以轻松地在控制台中查看@arr中当前存储的内容.

I have left p @arr in the code, so you can easily see in your console what is currently stored in @arr.

绝对不是我们所期望的...让我们尝试一些疯狂然后...

Definitely not what we expected... Let's try something crazy then...

4).让我们将describe嵌套在... it:

4). Let's nest describe within... it:

describe Array do
  before do
    @arr = []
  end

  describe "when initialized" do
    it "is empty" do
      @arr.length.must_equal 0
    end

    describe "when element added" do
      it "length reflects the change" do
        @arr << "a"
        @arr.length.must_equal 1

        describe "when another element added" do
          it "length also reflects the change" do
            @arr << "b"
            p @arr
            @arr.length.must_equal 2
          end
        end
      end
    end
  end
end

事实证明,这是完全有效的,并且其行为完全符合我们的预期! (再次,p @arr留在这里,所以您可以在控制台中检查@arr中当前存储的内容.)

Well, it turns out, that this is completely valid and it behaves exactly as we expected! (Again, p @arr left here so you an check in console what is currently stored in @arr).

老实说-我没有使用Capybara进行检查,但是这个简单的示例很有希望.尝试相应地修改您的代码,以便在您的规范中实现Capybara交互.

To be honest - I didn't check that with Capybara, but this simple example is quite promising. Try modifying your code accordingly, so in your specs the Capybara interactions are implemented.

让我清楚提供的解决方案:我再次强烈建议这种方法:

Let me be clear about provided solution: I strongly advise agains this approach:

  • 这样的规范很难阅读,因此很难维护.
  • 这被认为是错误的模式. 下一步步骤不应依赖上一步步骤的结果.
  • Specs like this are difficult to read - and in result - difficult to maintain.
  • This is considered bad pattern. Next steps should not rely on result of previous steps.

如果要正确测试控制器,则应尝试与此类似的操作(这是伪代码,仅用于说明想法):

If you want to test your contoller properly, you should try something similar to this (this is pseudo code just to illustrate idea):

测试步骤1

post "/url-to-my-form", { params_step_1: { ... } }

测试第2步

post "/url-to-my-form", { params_step_1: { ... }, params_step_2: { ... } }

使用这种方法很容易看到params是什么,因此更易于测试例如.违反任何规则(空值,无效的电子邮件等).

With this approach is very easy to see what params are posted, thus it's easier to test against eg. violations of any rules (empty values, invalid email, etc...).

希望有帮助!祝你好运!

Hope that helps! Good Luck!

这篇关于如何使用Capybara&amp;测试多步骤表单最小测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆