如何讲述功能规格的故事

时间:2014-01-04 17:47:27

标签: ruby-on-rails rspec capybara

您的应用程序的当前状态似乎已重置'规格之间。我不希望这种情况发生,因为我希望能够讲述一个故事':user_0这样做,然后他这样做,然后他决定删除它,然后他才会这样做登出。我想对这些要点中的每一点都抱有期望

如果你有这样的期望:

scenario "user_0 signs up with correct credentials" do      
    sign_up( @a999.first_name, @a999.last_name, @a999.profile_name, @a999.email, @a999.password )
    expect(page).to have_content("Welcome, " + @a999.full_name + "!")    

    sign_up( @a699.first_name, @a699.last_name, @a699.profile_name, @a699.email, @a699.password )
    expect(page).to have_content("Welcome, " + @a699.full_name + "!")
end

失败,因为用户@ a999已经登录,因此我们无法登录其他用户。如果我们将水豚代码写入sign_out @ a999,那么它会通过,正如我们所期望的那样。

那很好,这是我所期待的行为。但如果将两个符号序列分成不同的期望,就会发生一些奇怪的事情。

scenario "user signs up with correct credentials" do      
    sign_up( @a999.first_name, @a999.last_name, @a999.profile_name, @a999.email, @a999.password )
    expect(page).to have_content("Welcome, " + @a999.full_name + "!")    
end

scenario "user signs up with correct credentials" do         
    sign_up( @a699.first_name, @a699.last_name, @a699.profile_name, @a699.email, @a699.password )
    expect(page).to have_content("Welcome, " + @a699.full_name + "!")
end

基本上,期望都过去了,这导致得出的结论是应用程序被重置'期望之间。

但我不希望这种情况发生,我想讲一个故事,所以我该怎么做?

是用户上下文的答案,如下所示:

context "user_a999 signs up"
    before(:all) {
        sign_up( @a999.first_name, @a999.last_name, @a999.profile_name, @a999.email, @a999.password )     
    }

    scenario "has welcome message" do
        expect(page).to have_content("Welcome, " + @a999.full_name + "!")    
    end

        context "user_a999 signs out" do
            before(:all) {
                sign_out
            }

            scenario "has sign_out message" do
                 expect(page).to have_content("Signed out user " + @a999.full_name )                
            end

            context "user @a444 signs up" do
                before(:all) {
                    sign_up( @a444.first_name, @a444.last_name, @a444.profile_name, @a444.email, @a444.password )  
                }
            end

                context "user @a444" do
                    before(:all) {
                        visit "userfriendships/new/" + @a699.id
                    }

                    scenario "makes friend" do
                        click_link "confirm friend"
                        expect(page).to have_content( @a444.full_name + " and " + @a699.full_name + "are now friends!")
                    end    

                    scenario "deny friend" do
                        click_link "deny friend"
                        expect(page).to have_content( @a444.full_name + " and " + @a699.full_name + " are now denied a friendship!")
                    end    

                end
        end
end

使用上下文确实有效,我喜欢它的组织方式,有点像概率树,但我之所以这样问的原因有两个:

1)由于期望错综复杂,每个背景的缩进都将是疯狂的。在几个嵌套的上下文中,您需要在文本编辑器中向右滚动以便能够读取代码。我的意思是,我理解如何使用上下文在某种状态下设置应用程序,但这是一个集成规范,用于测试我的整个堆栈。我不想立即打出活动记录,我想通过与水豚一起阅读表格。

2)它读得不好。 scenario "has welcome message"并没有多大意义,所以我要感谢一些澄清。

1 个答案:

答案 0 :(得分:1)

首先,集成测试与验证测试不同,后者是特征规范。

无论如何,在编写规范时,您应该为要测试的每个功能都有单独的spec文件。在您的代码示例中,您应该在“朋友请求”功能规范文件的单独功能规范文件中测试“登录”功能。您的“朋友请求”规范看起来有点像这样:

feature 'Friend Requests' do
  let(:user) { User.make! } #using Machinist
  let(:other_user) { User.make! }

  background do
    sign_in(user) #have a helper method for sign_in
    #code for other_user to send friend request to user
  end

  scenario "accept friend request" do
    #code for user to accept friend request
  end

  scenario "deny friend request" do
    #code for user to deny friend request
  end
end

功能规范是验收测试,因此,并不意味着像单元测试那样工作,每次测试只应该有一个断言。在验收测试中,您可以在一次测试中使用多个断言,因为它们的运行速度要慢得多。

当你的context嵌套太深时,这通常表明你必须将测试分解为单独的规范。我尝试只使用一个context嵌套以便于阅读。

希望有所帮助!