It is estimated that you have been bored with hundreds of web page Click tests. At least I did this before. So, let's automate your web testing. In this article, we will use Cucumber + Watir to complete automated testing, starting with the simplest example, we can reconstruct a complete automated testing framework step by step.
(1) Relationship between Cucumber and Watir
Cucumber and Watir can have nothing to do with it. Cucumber is just a BDD framework, while Watir is just a Web Driver. What they both have in common belongs to the Ruby world.
(2) Use Cucumber separately
For the execution process of Cucumber, please refer to the author's article: behavior-driven development: directory structure and execution process of Cucumber.
Because Cucumber and Watir are not necessarily related, both of them can be used independently. Let's use Cucumber to write a very simple unit test. Define a Calculator class to be tested as follows:
1 class Calculator
2 def add num1, num2
3 num1+num2
4 end
5 end
The feature file used to test the add method of the Calculator class is as follows:
1 Feature: Unit test for Calculator
2
3 Scenario: Add two numbers
4 Given I have a calculator created
5 When I add '3' and '5'
6 Then I should get the result of '8'
The corresponding step file is:
1 require File.join(File.dirname(__FILE__), "../calculator")
2 require 'rspec'
3
4 Given /^I have a calculator created$/ do
5 @calculator = Calculator.new
6 end
7
8 When /^I add '([^"]*)' and '([^"]*)'$/ do |num1, num2|
9 @result = @calculator.add(num1.to_i, num2.to_i)
10 end
11
12 Then /^I should get the result of '([^"]*)'$/ do |expected_result|
13 @result.should == expected_result.to_i
14 end
In the above step file, line 1 and 2 respectively require the customized Calculator class and rspec (for assertion, refer to "shocould" in line 2 "), in row 5th, a new @ calculator instance variable is created. In row 9th, the two numbers are added (3 + 5) and the 13th behavior test asserted. Run the cucumber command and the output result is as follows:
1 Feature: Unit test for Calculator
2
3 Scenario: Add two numbers # features/Calculator.feature:4
4 Given I have a calculator created # features/step_definitions/calculator_step.rb:4
5 When I add '3' and '5' # features/step_definitions/calculator_step.rb:8
6 Then I should get the result of '8' # features/step_definitions/calculator_step.rb:12
7
8 1 scenario (1 passed)
9 3 steps (3 passed)
10 0m0.002s
The test is successful and no Watir shadow is displayed.
(3) Separate use of Watir
I heard that office lady with very fashionable uses Watir to complete routine and tedious webpage click Work (of course not a test, however, Watir can indeed perform such web page simulation operations. In the next class, we will use Watir to complete the google search function, create the watir_google.rb file, and add the following content:
1 require 'watir-webdriver'
2 browser = Watir::Browser.new :chrome
3 browser.goto "www.google.com/"
4 browser.text_field(:name => "q").set "ThoughtWorks"
5 browser.button(:name => "btnG").click
When the number of rows reaches 2nd, a browser window will automatically open. Then, visit the google homepage (row 3rd), set the search keyword "ThoughtWorks", click the search button, and run Watir separately, no Cucumber shadow.
(4) Automated write test with Cucumber + Watir
We can see from the above that Cucumber only describes business behavior in a way close to natural language, while Watir only simulates manual webpage operations. When Cucumber + Watir is used for automated testing, the behavior description of Cucumber is coupled with the Web operation steps of Watir through regular expression matching. Take Google search as an example. After a keyword is searched, we want to get the search result and use Cucumber to describe the search behavior:
1 Feature:Google search
2 Scenario: search for keyword
3 Given I am on google home page
4 When I search for 'ThoughtWorks'
5 Then I should be able to view the search result of 'ThoughtWorks'
The corresponding Watir code is as follows:
1 require "rubygems"
2 require "watir-webdriver"
3 require 'rspec'
4 Given /^I am on google home page$/ do
5 @browser = Watir::Browser.new :chrome
6 @browser.goto("www.google.com")
7 end
8
9 When /^I search for '([^"]*)'$/ do |search_text|
10 @browser.text_field(:name => "q").set(search_text)
11 @browser.button(:name => "btnK").click
12 end
13
14 Then /^I should be able to view the search result of '([^"]*)'$/ do |result_text|
15 @browser.text.should include(result_text)
16 end
Run cucumber. A new browser is opened and the displayed result is the same as that in (3.
(5) design mode of automated testing: Page Object
In the above example, we operate the @ browser object directly in all the steps. There is nothing wrong with such a simple example, however, it is too confusing for websites with dozens or even hundreds of pages. To be object-oriented, we want to encapsulate different pages with objects, therefore, the Page object can be used to encapsulate pages logically and implement hierarchical reuse. At this point the Cucumber file at high-level does not need to change, we just need to define a Page object to encapsulate Google pages (google-page.rb ):
1 require "rubygems"
2 require "watir-webdriver"
3 require "rspec"
4
5 class GooglePage
6 def initialize
7 @browser = Watir::Browser.new :chrome
8 @browser.goto("www.google.com")
9 end
10
11 def search str
12 @browser.text_field(:name => "q").set(str)
13 @browser.button(:name => "btnK").click
14 end
15
16 def has_text text
17 @browser.text.should include(text)
18 end
19 end
Modify the corresponding step file:
1 require File.join(File.dirname(__FILE__), "google-page")
2
3 Given /^I am on google home page$/ do
4 @page = GooglePage.new
5 end
6
7 When /^I search for '([^"]*)'$/ do |search_text|
8 @page.search search_text
9 end
10
11 Then /^I should be able to view the search result of '([^"]*)'$/ do |result_text|
12 @page.has_text result_text
13 end
Run cucumber. A new browser is opened and the displayed result is the same as that in (3.
(6) Add a Role user
Since it is behavior-driven, it is not enough to directly perform operations on the Page object to simulate the actual User operations, so we introduced the Role User object, it is particularly useful for websites with multiple user roles. After the User object is added, the step file does not directly reference the Page object, but references it in the behavior method of the User object. The User object is defined as follows (user. rb ):
1 require File.join(File.dirname(__FILE__), "google-page")
2
3 class User
4 def initialize
5 @browser = Watir::Browser.new :chrome
6 end
7
8 def visit_google
9 @page = GooglePage.new(@browser)
10 end
11
12 def search_text text
13 @page.search text
14 end
15
16 def assert_text_exist text
17 @page.has_text text
18 end
The feature file remains unchanged. In the step file, use User instead of Page:
1 require File.join(File.dirname(__FILE__), "user")
2
3 Given /^I am on google home page$/ do
4 @user = User.new
5 @user.visit_google
6 end
7
8 When /^I search for '([^"]*)'$/ do |search_text|
9 @user.search_text search_text
10 end
11
12 Then /^I should be able to view the search result of '([^"]*)'$/ do |result_text|
13 @user.assert_text_exist result_text
14 end
Run cucumber. A new browser is opened and the displayed result is the same as that in (3.
For websites with multiple user roles, such as customer and administrator, you can define corresponding objects for these roles and then apply these role objects in the step file.
(7) using the ruby Module to encapsulate different behavior Functions
For a single user, for example, the customer of an online shopping website, both the shopping operation and the user's profile can be modified. In this case, in order to organize these different logical functions, modules in ruby can be introduced for encapsulation. Different behavior functional modules of costomer can be encapsulated in different modules, and these modules can be included in the customer object. For simplicity, Google search is still used for demonstration, where you can add the search feature to the Module, defining the search module (search-behavior.rb) as follows:
1 module SearchBehavior
2
3 def visit_google
4 @page = GooglePage.new(@browser)
5 end
6
7 def search_text text
8 @page.search text
9 end
10
11 def assert_text_exist text
12 @page.has_text text
13 end
14
15 end
Include this Module in the User object:
1 require File.join(File.dirname(__FILE__), "search-behavior")
2 class User
3 include SearchBehavior
4 def initialize
5 @browser = Watir::Browser.new :chrome
6 end
You do not need to modify the step and feature files. Run cucumber. A new browser is opened and the display result is the same as that in (3.
(8) Summary
We can directly access the Watir API in the step file corresponding to Cucumber, which can indeed achieve the purpose of testing, but this disadvantage lies in the lack of design, therefore, we introduce Page objects to encapsulate different pages, introduce user roles to manage different user behaviors, and then introduce modules to organize different functional modules, finally, a simple and practical automated testing framework is reconstructed.