TDD/BDD Rails Cucumber / RSpec duplication

12
请问Cucumber和RSpec各自的作用是什么?能否通过一个简单的用户故事来说明呢?我最近买了RSpec的书,并且正在学习。但有时候作者表述得不够清晰。
举个例子,如果用户输入了一个无效的电话号码,那么应该会弹出一个提示信息"Invalid Telephone Number"。如果我使用Cucumber写出所有检查代码,然后再写RSpec代码,这样做就会导致测试重复了。请问应该如何区分Cucumber测试和RSpec测试?
我感觉在各自的层面上测试都需要重复编写,是否有明确的答案呢?如果没有,我开始认为Cucumber 的设计只是为了避免与RSpec产生冲突。
希望得到帮助,我的头快要爆炸了。谢谢!
6个回答

13

你可能会发现在BDDCasts.com上观看屏幕录像很有用。它们会引导你创建应用程序的故事和规范。它确实帮助了我。此外,我也拥有rspec书籍,但仍感到困惑。你甚至可以在他们在Github上的源代码中查看。

对于我来说,测试分为以下两类:

  • Cucumber用来测试用户所看到的内容(全栈测试)。

  • Rspec用来测试其他所有东西(模型、控制器等)。


12

Cucumber是用来解释应用程序某一部分(story)的工具,而不是像RSpec专注于单元测试或行为测试。

所以,在我看来Cucumber测试(stories)不能替代RSpec测试。

RSpec测试往往推动模型和控制器的开发,而stories则倾向于推动视图的开发。

从您的描述中看来,您正在使用Cucumber来同时测试stories和behavior。


我完全同意,这也是我的经验。 - Paul Fedory

6
考虑将Cucumber视为从外部测试整个应用程序,而将RSpec视为对特定模块进行单元测试。您可以通过在Cucumber中指定您希望应用程序具有的行为,然后转入RSpec并描述使该行为正常工作的类和模块来开始。
我花了一段时间才真正理解这一点,但我发现Cucumber非常适合以广泛的角度描述您希望应用程序执行的功能,而RSpec非常适合描述它实际上应该如何执行此功能。
因此,在Cucumber中,您会描述您想要的功能类型,并编写超级简单的步骤以提供输入并查看输出。然后,您转到RSpec并编写有关实际执行操作方式的规范。
假设您的功能是在网站上搜索用户名。您可以编写一个Cucumber功能,第一个(仅第一个)场景可能如下所示:
Feature: Search users
  In order to find people with similar interests as myself
  As a user
  I want to search for people

Scenario: Search for similar hobbies
  Given there is a search page
    And there is a list of hobbies
    And one of the hobbies is "full contact ironing"
   When I select "full contact ironing"
    And press search
   Then a list of users with the hobby "full contact ironing" are shown

你运行了Cucumber,它告诉你你缺少的步骤,你复制这些步骤并创建简单的步骤来检查这些内容,但还没有写任何代码。
当你完成步骤定义后,你会进入RSpec并开始编写关于你想要这个功能如何工作的规范。(当然,Cucumber应该失败)
describe "SearchController" do

  it "should respond to searches" do
    sc = SearchController.new
    sc.should respond_to(:search)
  end

end

当您运行 RSpec 并看到它失败后,可以开始编写代码:

class SearchController

  def search
  end

end

就是这样。现在再运行一次您的测试。它应该会通过,所以开始更具体地描述如何实际使用搜索功能。我不想过多深入讨论,只想给您一个想法:您可以在Cucumber中描述您想要的内容,然后在RSpec中描述它应该如何实际工作。

当然,您可以在Cucumber中完成全部测试,也可以全部使用RSpec,但我发现Cucumber帮助我用非常简单的方式表达我想要的东西,如果我尝试在RSpec中做到这一点,我会被细节缠住。如果我先使用Cucumber来描述我想要的基本功能和原因,然后再进入RSpec并描述我想要的功能实际上如何工作,效果会更好。

有时候您的测试会出现重复,这并不十分DRY,但如果您将其视为一个细节问题,它可能不会困扰您太多。起初,我做了很多重复的工作,直到意识到我应该只是在Cucumber中概括地描述我想要的内容,然后在RSpec中具体描述我想要的内容。

这只是一个新手在使用这些工具时想法,但迄今为止,它似乎运行得很好。我可能给您举了个糟糕的例子,但我只是想让您明白,从一般细节到具体细节的想法在使用这些工具时会非常有用。


5
Rspec和Cucumber是独立的,你可以在测试中使用Cucumber和其他测试框架(如Test Unit、shoulda等)。
关键是,您想用Cucumber测试什么? 因为实际上您可能会重复测试,这并没有真正有用,不是吗? :)
Cucumber有不同的哲学。
使用Cucumber可以做到:
DMA(直接模型访问,意味着您可以完全像在rspec中一样测试模型)
模拟浏览器(访问整个MVC堆栈,无JavaScript)
自动化浏览器(使用webrat和selenium访问视图,带有JavaScript,速度较慢,真正的浏览器)
我喜欢使用Cucumber检查返回给用户的内容。当我定义我的故事时,这通常对我有意义,因为我没有真正考虑要编写的代码。 因此,我使用Cucumber测试最终结果->视图(使用模拟或自动化浏览器)
然后我使用rspec来测试我在控制器和模型中编写的任何代码。
因此,在您的情况下,
当用户输入无效电话号码时,他们会收到一个消息,显示“无效电话号码”。
我将使用Webrat检查用户是否在视图中收到“无效电话号码”消息。我将使用Rspec测试我的控制器操作和模型。

2

Cucumber可以用来运行几乎任何代码,这就是我认为你可能会感到困惑的原因。但是Cucumber不提供其他类型的测试工具,例如模拟和存根方法,这使得单元测试更加具体。

Rspec旨在解决小块行为并使所有内容非常离散化。如果您熟悉单元测试和相关框架,则应该更容易理解。

Cucumber的实用程序在于能够将高级描述转换为系统上的一组顶级操作。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接