10分钟学会自动化测试框架--Cucumber + Watir

上一篇 / 下一篇  2012-11-06 20:25:53

估计你早已厌烦了成百上千遍的网页点击测试,至少之前的我是这样的,那么,让自己的web测试自动化吧,本文使用Cucumber + Watir来完成自动化测试,从最简单例子入手,一步一步重构成一个完整的自动化测试框架。

 

(一)Cucumber和Watir的关系

    Cucumber和Watir可以没有任何关系,Cucumber只是一个BDD框架,而Watir只是一个Web Driver而已,两者的共同点是均属于Ruby世界。

 

(二)单独使用Cucumber

    关于Cucumber的执行过程请参考另一篇文章行为驱动开发: Cucumber的目录结构和执行过程

    由于Cucumber和Watir没有必然联系,因此两者均可单独使用,下面就让我们用Cucumber来写一个非常简单的单元测试。 定义一个需要测试的Calculator类如下:

1classCalculator
2def add num1, num2
3num1+num2
4end
5end
1classCalculator
2def add num1, num2
3num1+num2
4end
5end
 

    用于测试Calculator类的add方法的feature文件如下:

复制代码
1Feature: Unit testforCalculator
2
3Scenario: Add two numbers
4Given I have a calculator created
5WhenI add '3' and '5'
6ThenI should get the result of '8'
复制代码

    对应的step文件为:

复制代码
1require File.join(File.dirname(__FILE__), "../calculator")
2require 'rspec'
3
4Given /^I have a calculator created$/do
5@calculator = Calculator.new
6end
7
8When/^I add '([^"]*)' and '([^"]*)'$/do|num1, num2|
9@result = @calculator.add(num1.to_i, num2.to_i)
10end
11
12Then/^I should get the result of '([^"]*)'$/ do |expected_result|
13@result.should == expected_result.to_i
14end
复制代码

    在以上的step文件中,第1,2行分别require了自定义的Calculator类和rspec(用于assertion,参考第13行的“should”), 第5行新建了一个@calculator实例变量,第9行完成两个数相加(3+5),第13行为测试断言。运行cucumber命令,输出结果如下:

复制代码
1Feature: Unit testforCalculator
2
3Scenario: Add two numbers # features/Calculator.feature:4
4Given I have a calculator created # features/step_definitions/calculator_step.rb:4
5WhenI add '3' and '5' # features/step_definitions/calculator_step.rb:8
6ThenI should get the result of '8' # features/step_definitions/calculator_step.rb:12
7
81 scenario (1 passed)
93 steps (3 passed)
100m0.002s
复制代码

    测试成功,没有看到任何Watir的影子。

 

(三)单独使用Watir

    听说有非常fashionable的office lady用Watir来完成日常例行并且繁琐的网页点击工作的(当然不是测试),听说而已,但是Watir的确可以完成诸如此类的网页模拟操作,接下类我们就用Watir来完成google搜索功能,新建watir_google.rb文件并加入以下内容:

复制代码
1require 'watir-webdriver'
2browser = Watir::Browser.new :chrome
3browser.goto"www.google.com/"
4browser.text_field(:name=> "q").set"ThoughtWorks"
5browser.button(:name=> "btnG").click
复制代码

  当执行到第2行时,一个浏览器窗口会自动打开,之后访问google主页(第3行),设置搜索关键词"ThoughtWorks",最后点击搜索按钮,单独运行Watir成功,没有任何Cucumber的影子。

 

(四)用Cucumber+Watir写自动化测试

    由上文可知,Cucumber只是用接近自然语言的方式来描述业务行为,而Watir则只是对人为操作网页的模拟。当使用Cucumber+Watir实现自动化测试时,通过正则表达式匹配将Cucumber的行为描述与Watir的网页操作步骤耦合起来即可。同样以Google搜索为例,搜索关键字后,我们希望获得搜索结果,先用Cucumber完成搜索行为描述:

复制代码
1Feature:Googlesearch
2Scenario: search for keyword
3Given I amongoogle home page
4WhenI searchfor'ThoughtWorks'
5ThenI should be able toviewthe search result of 'ThoughtWorks'
复制代码

   对应的Watir代码如下:

复制代码
1require "rubygems"
2require "watir-webdriver"
3require 'rspec'
4Given /^I amongoogle home page$/do
5@browser = Watir::Browser.new :chrome
6@browser.goto("www.google.com")
7end
8
9When/^I searchfor'([^"]*)'$/ do |search_text|
10@browser.text_field(:name => "q").set(search_text)
11@browser.button(:name => "btnK").click
12end
13
14Then /^I should be able to view the search result of '([^"]*)'$/do|result_text|
15@browser.text.should include(result_text)
16end
复制代码

    运行cucumber,一个新的浏览器被打开,显示结果与(三)中相同。

(五)自动化测试的设计模式:Page对象

   在上面的例子中,我们在所有的step中均直接对@browser对象进行操作,对于这样简单的例子并无不妥,但是对于动则几十个甚至上百个页面的网站来说便显得过于混乱,既然要面向对象,我们就希望将不同的页面也用对象来封装,于是引入Page对象,既可完成对页面的逻辑封装,又实现了分层重用。此时位于high-level的Cucumber文件无需变动,我们只需要定义一个Page对象来封装Google页面(google-page.rb):

复制代码
1require "rubygems"
2require "watir-webdriver"
3require "rspec"
4
5class GooglePage
6def initialize
7@browser = Watir::Browser.new :chrome
8@browser.goto("www.google.com")
9end
10
11def search str
12@browser.text_field(:name=> "q").set(str)
13@browser.button(:name=> "btnK").click
14end
15
16def has_text text
17@browser.text.should include(text)
18end
19end
复制代码

   相应的step文件需要做相应的修改:

复制代码
1require File.join(File.dirname(__FILE__), "google-page")
2
3Given /^I amongoogle home page$/do
4@page = GooglePage.new
5end
6
7When/^I searchfor'([^"]*)'$/ do |search_text|
8@page.search search_text
9end
10
11Then /^I should be able to view the search result of '([^"]*)'$/do|result_text|
12@page.has_text result_text
13end
复制代码

     运行cucumber,一个新的浏览器被打开,显示结果与(三)中相同。

(六)加入角色用户

   既然是行为驱动,既然是模拟用户实际操作,那么直接对Page对象进行操作也显得不够了,于是我们引入了角色用户User对象,对于拥有多种用户角色的网站来说特别实用。加入User对象之后,step文件中不再出现对Page对象的直接引用,而是在User对象的行为方法中进行引用,定义User对象如下(user.rb):

复制代码
1require File.join(File.dirname(__FILE__), "google-page")
2
3class User
4def initialize
5@browser = Watir::Browser.new :chrome
6end
7
8def visit_google
9@page = GooglePage.new(@browser)
10end
11
12def search_text text
13@page.search text
14end
15
16def assert_text_exist text
17@page.has_text text
18end
复制代码

   feature文件保持不变,在step文件用User代替Page:

复制代码
1require File.join(File.dirname(__FILE__), "user")
2
3Given /^I amongoogle home page$/do
4@user = User.new
5@user.visit_google
6end
7
8When/^I searchfor'([^"]*)'$/ do |search_text|
9@user.search_text search_text
10end
11
12Then /^I should be able to view the search result of '([^"]*)'$/do|result_text|
13@user.assert_text_exist result_text
14end
复制代码

   运行cucumber,一个新的浏览器被打开,显示结果与(三)中相同。 

   对于拥有多个用户角色的网站,比如又customer,administrator等,可分别对这些角色定义相应的对象,再在step文件中应用这些角色对象即可。

 

  (七)用ruby的Module来封装不同的行为功能

     对于单个用户来说,比如网上购物网站的customer,既要购物操作,又要能修改自己的profile,此时为了对这些不同的逻辑功能进行组织,可引入ruby中的Module来进行封装,即将costomer的不同行为功能模块封装在不同的module中,然后在customer对象中include这些Module。为简单起见,依然用Google搜索来进行演示,此时可将搜索功能加入到Module中,定义搜索module(search-behavior.rb)如下:

复制代码
1module SearchBehavior
2
3def visit_google
4@page = GooglePage.new(@browser)
5end
6
7def search_text text
8@page.search text
9end
10
11def assert_text_exist text
12@page.has_text text
13end
14
15end
复制代码

    在User对象中include该Module:

复制代码
1require File.join(File.dirname(__FILE__), "search-behavior")
2class User
3include SearchBehavior
4def initialize
5@browser = Watir::Browser.new :chrome
6end
复制代码

  对step文件和feature文件均不用修改,运行cucumber,一个新的浏览器被打开,显示结果与(三)中相同。

(八)总结

   我们可以在Cucumber对应的step文件中直接访问Watir的API,这样的确也能达到测试目的,但这样的缺点在于缺少设计,于是我们引入Page对象来封装不同的页面,引入用户角色管理不同的用户行为,再引入Module来组织不同的功能模块,最后重构成了一个简单实用的自动化测试框架。


TAG:

蓝天伟测试之家 引用 删除 lantianwei   /   2012-11-07 13:12:51
5
 

评分:0

我来说两句

日历

« 2024-05-07  
   1234
567891011
12131415161718
19202122232425
262728293031 

数据统计

  • 访问量: 343685
  • 日志数: 46
  • 图片数: 2
  • 文件数: 4
  • 书签数: 1
  • 建立时间: 2012-08-01
  • 更新时间: 2019-02-20

RSS订阅

Open Toolbar