Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependent tests in rspec

I write functional tests, and I need to do tests that were being would depend on the passage of previous tests. Let's say I have a button that opens a window in which there is a functional. That is, in order to check this functionality, I need to first check the correct operation of the button (ie, open window or not functional). So, I need to do so that would be if the test failed on a button click, the tests did not run to check the functional window. Writing tests separately - for me is not an option. I would like to see something like this:

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

I know that this method does not work for rspec. It's just a simple description of what I want to see. Is it achievable using rspec? If not, are there other ways (gems, etc.)

like image 266
facetostool Avatar asked Feb 12 '13 14:02

facetostool


1 Answers

RSpec is designed as a unit tests framework, so it may be a little difficult to get perfect functional-test behavior from it. In RSpec's philosophy tests must be independent. It is especially important when you use autotest: in this case the order of execution is truly unpredictable. Sad but true.

Still, of course you can save some state between test using global ($a) or instance (@a, not sure here) variables. Anyway you need to move if into it block so that it will be executed in time. You may use pending keyword to interrupt a test without failing it in case if pre-condition is not met.

BUT

I'm sure that the best solution is to avoid golden hammer antipattern, and not to write functional tests in unit-test framework. You want not to test some separate functions. You do want to test scenarios. So I suggest trying some scenario-testing suite.

Behold, Cucumber! Usage is simle:

  1. Define parametrized scenario steps in Ruby, and expectations in RSpec-style
  2. Write scenarios in natural language (yes, not only English, but even Russian or whatever — the power of Regexps is on your side)

In your case, you will have in features/step_definitions/gui_steps.rb something like

Given /I pushed a button "(.*)"/ do |name|
    @buttons.find(name).click() # This line is pseudo-code, you know
end

and something similar for checking window opening, etc (see examples). Then you can combine defined steps in any way, for example your two scenarios might look like

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

In both cases, if some step of scenario fails (like I focus on opened window — if it is not opened), the consequent steps are not executed — just as you want. As a bonus you get an extremely detailed output of what happened and on what step (see pics on the site).

The good news is that you don't always need to define all the step yourself. For example, when you test a web app, you can use webrat steps for typical things like When I go to url/a/b/c and Then I should see text "foo" on the page. I don't know which GUI testing framework you use, but probably there are already steps for it, so I suggest you to google on Cucumber %framework name%. Even if not, writing these steps once will not be more difficult than trying to make Cucumber from RSpec.

like image 114
NIA Avatar answered Oct 07 '22 22:10

NIA