依赖测试在rspec中的应用

8
我写功能测试,需要进行依赖于先前测试结果的测试。假设我有一个按钮,点击该按钮会打开一个窗口,在其中存在一些功能。也就是说,为了检查这个功能,我需要首先检查按钮的正确操作(即,是否打开窗口或功能是否正常)。因此,我需要做到如果测试在按钮点击时失败,则不运行测试以检查功能窗口。单独编写测试对我来说不是一个选项。我希望看到像这样的内容:
describe "some tests" do
  open_result = nil

  it "should check work button" do
    click_to_button()
    open_result = window_opened?
    open_result.should == true
  end

  if open_result

    describe "Check some functional" do

      it "should check first functional"

      it "should check second functional"

    end

  end

end

我知道这种方法不适用于rspec。这只是我想要看到的简单描述。使用rspec可以实现吗?如果不行,是否有其他方法(gems等)?


我认为这可能是离题的,因为有sqa.stackexchange.com。 - Nakilon
1个回答

14
RSpec被设计为一个单元测试框架,因此从中获得完美的功能测试行为可能有些困难。在RSpec的哲学中,测试必须是独立的。当你使用autotest时尤其重要:在这种情况下,执行顺序真的是不可预测的。悲伤但是真实的。
当然,你可以使用全局变量($a)或实例变量(@a,不确定)在测试之间保存一些状态。无论如何,你需要将if移动到it块中以便及时执行。如果前提条件不满足,你可以使用pending关键字来中断测试而不使其失败。 但是
我相信最好的解决方案是避免金鎚反模式,并不在单元测试框架中编写功能测试。你不想测试某些单独的函数,而是想要测试场景。因此,我建议尝试一些场景测试套件。
看哪,Cucumber! 使用方法很简单:
  1. 在 Ruby 中定义带参数的场景步骤,并在 RSpec 风格中定义期望
  2. 用自然语言编写场景(是的,不仅仅是英语,甚至包括俄语或其他语言——正则表达式的威力就在你这边)
在你的情况下,你将在 features/step_definitions/gui_steps.rb 中有类似以下内容:
Given /I pushed a button "(.*)"/ do |name|
    @buttons.find(name).click() # This line is pseudo-code, you know
end

还有类似的方法用于检查窗口是否打开等操作(请参见例子)。然后,您可以以任何方式组合定义的步骤,例如您的两个场景可能如下所示:

Scenario: Feature 1
    Given I pushed a button "go"
    And I focus on opened window
    When I trigger "feature 1"
    Then I should se "result 1" in text area

Scenario: Feature 2
    Given I pushed a button "go"
    And I focus on opened window
    When I trigger "feature 2"
    Then I should se "result 2" in text area

在这两种情况下,如果某个场景中的某一步骤失败(例如“我专注于打开的窗口”-如果它没有打开),则随后的步骤不会执行-就像您想要的那样。作为奖励,您可以获得发生了什么以及在哪个步骤上的极其详细的输出(请参见网站上的图片)。 好消息是,您并不总是需要自己定义所有步骤。例如,当您测试 Web 应用程序时,可以使用 webrat 步骤来处理典型的事情,例如当我转到 url/a/b/c 时然后我应该在页面上看到文本“foo”。我不知道您使用哪个 GUI 测试框架,但可能已经有了相应的步骤,因此建议您在 Google 上搜索Cucumber %框架名称%。即使没有,编写这些步骤也不会比尝试从 RSpec 制作 Cucumber 更困难。

5
尽管我们不愿用“不要那样做”的方式来回答问题,但黄瓜比钉子更适合这个场景。解释得很好。 - Wayne Conrad
除了语言之外,将步骤编写为方法并按顺序调用它们与普通的 RSpec 测试有什么真正的区别吗? - Frederick Cheung
1
@Frederick,“除了语言之外”,不,但是语言是一个非常重要的问题。Rspec是测试的DSL。Cucumber是测试的元DSL:它是一种DSL,可以让您轻松编写特定于您正在测试的内容的DSL。这可能看起来像一个小问题,但它在您思考和编写测试时会产生巨大的影响。 - Wayne Conrad
1
@FrederickCheung,简而言之,使用Cucumber相比于从不同的RSpec规范中调用方法的主要优势是**(1)测试的可读性(和可写性),以及(2)**失败消息的信息量和清晰度。这是因为Cucumber不仅是一个元DSL,还有一些逻辑在其中。可能看起来不重要,直到你尝试过,但相信我,当一个人尝试过后,他就不想再发明自行车了,因为已经有了一个好的工具。 - NIA
使用全局变量($a)或实例变量(@a)...在示例之间设置@a不会共享,但是在示例之间设置$a是被识别的。 - Unglued
@Unglued,好的,我划掉了那个不确定的部分。 - NIA

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