Selenium/Ruby/Very Basic Howto
This page is obsolete. It is being retained for archival purposes. It may document extensions or features that are obsolete and/or no longer supported. Do not rely on the information here being up-to-date. See Selenium instead. |
The work of creating browser tests is all conceptual and abstracted until the very last step. Here is a step by step description of a proper test development process.
Describe the behavior by which we will know that the feature being tested functions correctly
editIf you've installed all the stuff you need, you create a feature file in the /tests/browser/features folder, for example my_test.feature.
In my_test.feature, you'll have a Scenario and a Feature:
Feature: My First Cucumber Test Scenario: My First Scenario Given I am on my page that has the setup I need to test When I click the link on my page that takes me somewhere I need to test Then I see the special thing that tells me that the test has passed
Generate the steps file
editYou execute the test at this point
$ bundle exec cucumber features/my_test.feature
And the resulting output tells you what comes next:
Feature: My First Cucumber Test Scenario: My First Scenario # features/my_test.feature:3 Given I am on my page that has the setup I need to test # features/my_test.feature:4 When I click the link on my page that takes me somewhere I need to test # features/my_test.feature:5 Then I see the special thing that tells me that the test has passed # features/my_test.feature:6 1 scenario (1 undefined) 3 steps (3 undefined) 0m3.074s You can implement step definitions for undefined steps with these snippets: Given(/^I am on my page that has the setup I need to test$/) do pending # express the regexp above with the code you wish you had end When(/^I click the link on my page that takes me somewhere I need to test$/) do pending # express the regexp above with the code you wish you had end Then(/^I see the special thing that tells me that the test has passed$/) do pending # express the regexp above with the code you wish you had end
Fill in a step in the test
editThis work is done step by step by step. Take the first "pending" step and paste it into a file in the /features/step_definitions directory with the title "my_test_steps.rb"
Given(/^I am on my page that has the setup I need to test$/) do pending # express the regexp above with the code you wish you had end
and fill in the pending step
Given(/^I am on my page that has the setup I need to test$/) do visit(MyPage) end
and run the test and see the failure:
$ bundle exec cucumber features/my_test.feature Feature: My First Cucumber Test Scenario: My First Scenario # features/my_test.feature:3 Given I am on my page that has the setup I need to test # features/step_definitions/my_test_steps.rb:1 uninitialized constant MyPage (NameError) ./features/step_definitions/my_test_steps.rb:2:in `/^I am on my page that has the setup I need to test$/' features/my_test.feature:4:in `Given I am on my page that has the setup I need to test' When I click the link on my page that takes me somewhere I need to test # features/my_test.feature:5 Then I see the special thing that tells me that the test has passed # features/my_test.feature:6 Failing Scenarios: cucumber features/my_test.feature:3 # Scenario: My First Scenario 1 scenario (1 failed) 3 steps (1 failed, 2 undefined) 0m2.731s
Make the Page Object (if it does not already exist)
editIn the features/support/pages directory you'll need a file called my_page.rb. Inside you'll need to put
class MyPage include PageObject page_url "<%=params[:article_name]%><%=params[:hash]%>" end
There is a little bit of magic happening in that business of "<%=params[:article_name]%><%=params[:hash]%>" but don't worry about that for now...
Run the test again and the error is gone:
$ bundle exec cucumber features/my_test.feature Feature: My First Cucumber Test Scenario: My First Scenario # features/my_test.feature:3 Given I am on my page that has the setup I need to test # features/step_definitions/my_test_steps.rb:1 When I click the link on my page that takes me somewhere I need to test # features/my_test.feature:5 Then I see the special thing that tells me that the test has passed # features/my_test.feature:6 1 scenario (1 undefined) 3 steps (2 undefined, 1 passed) 0m5.427s
Implement the When step
editGo back to /features/step_definitions/my_test_steps.rb and add the pending step
When(/^I click the link on my page that takes me somewhere I need to test$/) do pending # express the regexp above with the code you wish you had end
Decide what the pending step should do:
When(/^I click the link on my page that takes me somewhere I need to test$/) do on(MyPage).my_special_link_element.click end
and run the test to watch it fail:
$ bundle exec cucumber features/my_test.feature Feature: My First Cucumber Test Scenario: My First Scenario # features/my_test.feature:3 Given I am on my page that has the setup I need to test # features/step_definitions/my_test_steps.rb:1 When I click the link on my page that takes me somewhere I need to test # features/step_definitions/my_test_steps.rb:5 undefined method `my_special_link_element' for #<MyPage:0x00000101cf2b80> (NoMethodError) ./features/step_definitions/my_test_steps.rb:6:in `/^I click the link on my page that takes me somewhere I need to test$/' features/my_test.feature:5:in `When I click the link on my page that takes me somewhere I need to test' Then I see the special thing that tells me that the test has passed # features/my_test.feature:6 Failing Scenarios: cucumber features/my_test.feature:3 # Scenario: My First Scenario 1 scenario (1 failed) 3 steps (1 failed, 1 undefined, 1 passed)
This tells us that the MyPage object does not contain a method called "my_special_link_element", which of course is true.
So far everything we have done has been conceptual and abstract. This next part is where we actually tie the test itself to the page being tested. Read over the documentation at https://github.com/cheezy/page-object/wiki/Elements and then add this to your page object:
class MyPage include PageObject page_url "<%=params[:article_name]%><%=params[:hash]%>" a(:my_special_link, href: /Special:UserLogin/) end
Here "my_special_link" is the first link on the page whose target contains "Special: UserLogin", and this test is going to click that link. Note that appending "_element" to a label in a Page Object has some special properties, noted in the documentation linked above.
Run the test again:
$ bundle exec cucumber features/my_test.feature Feature: My First Cucumber Test Scenario: My First Scenario # features/my_test.feature:3 Given I am on my page that has the setup I need to test # features/step_definitions/my_test_steps.rb:1 When I click the link on my page that takes me somewhere I need to test # features/step_definitions/my_test_steps.rb:5 Then I see the special thing that tells me that the test has passed # features/my_test.feature:6 1 scenario (1 undefined) 3 steps (1 undefined, 2 passed) 0m5.609s
Make an assertion in the Then step
editThe Given steps talk about what the test needs to have in place before it runs
The When steps talk about the actions that the test must perform to arrive at its final state
The Then steps talk about how we know that the feature functions correctly
So we will finish the test and make it pass. Put the last pending step into the steps file:
Then(/^I see the special thing that tells me that the test has passed$/) do pending # express the regexp above with the code you wish you had end
So this will become
Then(/^I see the special thing that tells me that the test has passed$/) do expect(on(MyPage).page_content).to match "Create Account" end
This step says "expect (some condition) to exist". We could also say things like
- expect(on(MyPage.my_special_element).to be_visible or
- expect(on(MyPage.my_crummy_element).not_to be_visible
or many other similar things the the RSpec assertion library allows.
The Page Object becomes
class MyPage include PageObject page_url "<%=params[:article_name]%><%=params[:hash]%>" a(:my_special_link, href: /Special:UserLogin/) div(:page_content, id: "content") end
Run the test and it passes:
$ bundle exec cucumber features/my_test.feature Feature: My First Cucumber Test Scenario: My First Scenario # features/my_test.feature:3 Given I am on my page that has the setup I need to test # features/step_definitions/my_test_steps.rb:1 When I click the link on my page that takes me somewhere I need to test # features/step_definitions/my_test_steps.rb:5 Then I see the special thing that tells me that the test has passed # features/step_definitions/my_test_steps.rb:9 1 scenario (1 passed) 3 steps (3 passed)