iaimstar 写道
@RednaxelaFX 你最近ruby魔障了?
好吧……那魔障给你看看。
这次的玩法是使用 Watir打开浏览器到Google上搜索iaimstar,并用 RSpec来确认行为。
首先确保以安装Watir和RSpec这两个gem:
gem install watir rspec
然后编写一个spec。首先确认一下希望看到什么结果,并且达成该结果需要经过怎样的流程:
预期结果:在Google上搜iaimstar应当看到他JavaEye的blog为第一个结果。
流程:
1、打开浏览器;
2、到Google中文站
3、在搜索框中输入“iaimstar”;
4、点击搜索按钮;
5、找到第一个搜索结果;
6、该结果应该指向“http://iaimstar.iteye.com/”;
最后记得浏览器要关掉。
任意新建一个Ruby源文件(本例中叫watir_spec.rb),把上述流程写成代码。
watir_spec.rb:
require 'rubygems' require 'watir' require 'spec' describe Watir::Browser do it "should get iaimstar's JavaEye blog as the first Google search result" do begin browser = Watir::Browser.new browser.goto 'http://g.cn' browser.text_field(:name, 'q').set 'iaimstar' browser.button(:name, 'btnG').click anchor = browser.element_by_xpath 'div#cnt/div#res.med/div/ol/li.g/h3.r/a.l[1]' anchor.href.should == 'http://iaimstar.iteye.com/' ensure browser.close end end end
在命令行使用spec命令来执行测试:
spec watir_spec.rb --format specdoc
一切顺利的话,可以看到输出结果为:
Watir::Browser - should get iaimstar's JavaEye blog as the first Google search result Finished in 6.694 seconds 1 example, 0 failures
如图:
![To囧:拿你来测测Watir..._第1张图片](http1://img.it610.com/image/product/4979f656c9074abda058c1d74786f8be.jpg)
(这个测试是昨晚做的,发帖时Google的搜索结果发生了变化,JavaEye的结果跑到第二位了。有兴趣的同学可以照着做一次这个测试,观察一下测试失败时的输出)
![To囧:拿你来测测Watir..._第2张图片](http1://img.it610.com/image/product/e1ddffd8dc4c45008a0681fefec792a0.jpg)
关于Watir支持的操作,可以参考 Watir出猫纸
另外,刚装上Nokogiri 1.4.0的同学可能会碰到这种警告:
C:/Ruby/lib/ruby/gems/1.8/gems/nokogiri-1.4.0-x86-mingw32/lib/nokogiri/xml/builder.rb:272: warning: parenthesize argument(s) for future version
正好在JavaEye问答频道有同学问了这个问题,请参考: http://www.iteye.com/problems/29853
===========================================================================
不过既然有要达成某个结果有清晰的流程,那干脆把流程在代码里再写得清晰些。
确保安装上 Cucumber、 Rake、 Win32::Console这几个gem:
gem install cucumber rake win32console
先随便建一个目录,以存放本例的文件;我是放在了D:\temp_code\test_cucumber。
编写一个rakefile来自动化测试的执行:
rakefile:
require 'rubygems' require 'cucumber/rake/task' Cucumber::Rake::Task.new :features do |t| t.cucumber_opts = "features --format pretty" end
然后在rakefile所在目录下再创建一个features目录以存放“功能描述”。
可以在rakefile所在目录运行cucumber试试看:
D:\temp_code\test_cucumber>rake features (in D:/temp_code/test_cucumber) C:/Ruby/bin/ruby.exe -I "C:/Ruby/lib/ruby/gems/1.8/gems/cucumber-0.4.4/lib;lib" "C:/Ruby/lib/ruby/gems/1.8/gems/cucumber-0.4.4/bin/cucumber" features --format pretty 0 scenarios 0 steps 0m0.000s
这说明rakefile编写正确,而当前尚未有需要测试的功能。
那么就来添加一个功能描述文件。在features目录里创建一个.features文件。Feature块表示一个功能点,其中可以包含一到多个Scenario。Scenario就是使用到某功能点的案例,用Given、When、Then来描述流程。其中Given表示前置条件,在这里可以建立好测试需要的环境;When表示场景中的步骤;Then表示后置条件,也就是检查结果的正确性。如果多个Scenario在开始出含有共同的步骤,可以抽出来放到Background块里。把可能有变化的描述写在双引号内。
features/search_friends.feature
Feature: search for friends on Google I want to know where my friends' blogs are So that I can read their blog posts Background: Given I start up a browser And I goto "http://g.cn" Scenario: search for iaimstar When I enter "iaimstar" in the search field And I click the search button Then the first search result exists And it should read "尘星似海:囧冏有神的java空间- JavaEye技术网站" And it should point to "http://iaimstar.iteye.com/" Scenario: search for RednaxelaFX When I enter "RednaxelaFX" in the search field And I click the search button Then the first search result exists And it should read "Script Ahead, Code Behind - JavaEye技术网站" And it should point to "http://rednaxelafx.iteye.com/"
再回到rakefile所在目录运行一次rake:
D:\temp_code\test_cucumber>rake features (in D:/temp_code/test_cucumber) C:/Ruby/bin/ruby.exe -I "C:/Ruby/lib/ruby/gems/1.8/gems/cucumber-0.4.4/lib;lib" "C:/Ruby/lib/ruby/gems/1.8/gems/cucumber-0.4.4/bin/cucumber" features --format pretty Feature: search for friends on Google I want to know where my friends' blogs are So that I can read their blog posts Background: # features/search_friends.feature:5 Given I start up a browser # features/search_friends.feature:6 And I goto "http://g.cn" # features/search_friends.feature:7 Scenario: search for iaimstar # features/search_friends.feature:9 When I enter "iaimstar" in the search field # features/search_friends.feature:10 And I click the search button # features/search_friends.feature:11 Then the first search result exists # features/search_friends.feature:12 And it should read "尘星似海:囧冏有神的java空间- JavaEye技术网站" # features/search_friends.feature:13 And it should point to "http://iaimstar.iteye.com/" # features/search_friends.feature:14 Scenario: search for RednaxelaFX # features/search_friends.feature:16 When I enter "RednaxelaFX" in the search field # features/search_friends.feature:17 And I click the search button # features/search_friends.feature:18 Then the first search result exists # features/search_friends.feature:19 And it should read "Script Ahead, Code Behind - JavaEye技术网站" # features/search_friends.feature:20 And it should point to "http://rednaxelafx.iteye.com/" # features/search_friends.feature:21 2 scenarios (2 undefined) 14 steps (14 undefined) 0m0.032s You can implement step definitions for undefined steps with these snippets: Given /^I start up a browser$/ do pending # express the regexp above with the code you wish you had end Given /^I goto "([^\"]*)"$/ do |arg1| pending # express the regexp above with the code you wish you had end When /^I enter "([^\"]*)" in the search field$/ do |arg1| pending # express the regexp above with the code you wish you had end When /^I click the search button$/ do pending # express the regexp above with the code you wish you had end Then /^the first search result exists$/ do pending # express the regexp above with the code you wish you had end Then /^it should read "([^\"]*)"$/ do |arg1| pending # express the regexp above with the code you wish you had end Then /^it should point to "([^\"]*)"$/ do |arg1| pending # express the regexp above with the code you wish you had end If you want snippets in a different programming language, just make sure a file with the appropriate file extension exists where cucumber looks for step definitions.
如图:
![To囧:拿你来测测Watir..._第3张图片](http1://img.it610.com/image/product/cf31d67068c14ae4a209e2799c85022c.jpg)
可以看到有了描述的场景在还没有代码去实现它的时候是黄色的。
在features目录下创建一个step_definitions目录,并创建search_friends_step.rb文件来实现测试的场景。可以复制Cucumber的提示的实现代码到该文件中:
features/steps/search_friends_step.rb
Given /^I start up a browser$/ do pending # express the regexp above with the code you wish you had end Given /^I goto "([^\"]*)"$/ do |arg1| pending # express the regexp above with the code you wish you had end When /^I enter "([^\"]*)" in the search field$/ do |arg1| pending # express the regexp above with the code you wish you had end When /^I click the search button$/ do pending # express the regexp above with the code you wish you had end Then /^the first search result exists$/ do pending # express the regexp above with the code you wish you had end Then /^it should read "([^\"]*)"$/ do |arg1| pending # express the regexp above with the code you wish you had end Then /^it should point to "([^\"]*)"$/ do |arg1| pending # express the regexp above with the code you wish you had end
再运行rake,可以看到所有步骤都有实现了,不过每一步的实现都是pending,所以测试到第一个pending之后,后面的步骤就被跳过(skip)了:
D:\temp_code\test_cucumber>rake features (in D:/temp_code/test_cucumber) C:/Ruby/bin/ruby.exe -I "C:/Ruby/lib/ruby/gems/1.8/gems/cucumber-0.4.4/lib;lib" "C:/Ruby/lib/ruby/gems/1.8/gems/cucumber-0.4.4/bin/cucumber" features --format pretty Feature: search for friends on Google I want to know where my friends' blogs are So that I can read their blog posts Background: # features/search_friends.feature:5 Given I start up a browser # features/step_definitions/search_friends_step.rb:1 TODO (Cucumber::Pending) ./features/step_definitions/search_friends_step.rb:2:in `/^I start up a browser$/' features/search_friends.feature:6:in `Given I start up a browser' And I goto "http://g.cn" # features/step_definitions/search_friends_step.rb:5 Scenario: search for iaimstar # features/search_friends.feature:9 When I enter "iaimstar" in the search field # features/step_definitions/search_friends_step.rb:9 And I click the search button # features/step_definitions/search_friends_step.rb:13 Then the first search result exists # features/step_definitions/search_friends_step.rb:17 And it should read "尘星似海:囧冏有神的java空间- JavaEye技术网站" # features/step_definitions/search_friends_step.rb:21 And it should point to "http://iaimstar.iteye.com/" # features/step_definitions/search_friends_step.rb:25 Scenario: search for RednaxelaFX # features/search_friends.feature:16 When I enter "RednaxelaFX" in the search field # features/step_definitions/search_friends_step.rb:9 And I click the search button # features/step_definitions/search_friends_step.rb:13 Then the first search result exists # features/step_definitions/search_friends_step.rb:17 And it should read "Script Ahead, Code Behind - JavaEye技术网站" # features/step_definitions/search_friends_step.rb:21 And it should point to "http://rednaxelafx.iteye.com/" # features/step_definitions/search_friends_step.rb:25 2 scenarios (1 skipped, 1 pending) 14 steps (13 skipped, 1 pending) 0m0.026s
如图:
![To囧:拿你来测测Watir..._第4张图片](http1://img.it610.com/image/product/ab08f61b9ec6465d9794d006f9dd974a.jpg)
被跳过的步骤用蓝色表示。
现在只剩把测试的实现与测试对象组装到一起了。为了准备好要用的库,在features目录下创建support目录,在里面创建env.rb文件:
features/support/env.rb
require 'rubygems' require 'watir' require 'iconv'
然后给先前创建的search_friends_step.rb添加逻辑:
features/steps/search_friends_step.rb
Given /^I start up a browser$/ do @browser = Watir::Browser.new end Given /^I goto "([^\"]*)"$/ do |url| @browser.goto url end When /^I enter "([^\"]*)" in the search field$/ do |keyword| @browser.text_field(:name, 'q').set keyword end When /^I click the search button$/ do @browser.button(:name, 'btnG').click end Then /^the first search result exists$/ do @result = @browser.element_by_xpath 'div#cnt/div#res.med/div/ol/li.g/h3.r/a.l[1]' @result.should_not be(nil) end Then /^it should read "([^\"]*)"$/ do |title| Iconv.conv('gbk', 'utf-8', @result.innerText).should == title end Then /^it should point to "([^\"]*)"$/ do |expected_url| @result.href.should == expected_url end After do @browser.close end
此时目录结构应该像这样:
test_cucumber │ rakefile │ └─features │ search_friends.feature │ ├─step_definitions │ search_friends_step.rb │ └─support env.rb
再运行rake,可以看到:
D:\temp_code\test_cucumber>rake features (in D:/temp_code/test_cucumber) C:/Ruby/bin/ruby.exe -I "C:/Ruby/lib/ruby/gems/1.8/gems/cucumber-0.4.4/lib;lib" "C:/Ruby/lib/ruby/gems/1.8/gems/cucumber-0.4.4/bin/cucumber" features --format pretty Feature: search for friends on Google I want to know where my friends' blogs are So that I can read their blog posts Background: # features/search_friends.feature:5 Given I start up a browser # features/step_definitions/search_friends_step.rb:1 And I goto "http://g.cn" # features/step_definitions/search_friends_step.rb:5 Scenario: search for iaimstar # features/search_friends.feature:9 When I enter "iaimstar" in the search field # features/step_definitions/search_friends_step.rb:9 And I click the search button # features/step_definitions/search_friends_step.rb:13 Then the first search result exists # features/step_definitions/search_friends_step.rb:17 And it should read "尘星似海:囧冏有神的java空间- JavaEye技术网站" # features/step_definitions/search_friends_step.rb:22 expected: "\263\276星似\272\243:\207鍍子猩馶265膉ava\277占? JavaEye\274\274术网站", got: "iaimstar - ChinaonRails" (using ==) Diff: @@ -1,2 +1,2 @@ -尘星似海:囧冏有神的java空间- JavaEye技术网站 +iaimstar - ChinaonRails (Spec::Expectations::ExpectationNotMetError) ./features/step_definitions/search_friends_step.rb:23:in `/^it should read "([^\"]*)"$/' features/search_friends.feature:13:in `And it should read "尘星似海:囧冏有神的java空间- JavaEye技术网站"' And it should point to "http://iaimstar.iteye.com/" # features/step_definitions/search_friends_step.rb:26 Scenario: search for RednaxelaFX # features/search_friends.feature:16 When I enter "RednaxelaFX" in the search field # features/step_definitions/search_friends_step.rb:9 And I click the search button # features/step_definitions/search_friends_step.rb:13 Then the first search result exists # features/step_definitions/search_friends_step.rb:17 And it should read "Script Ahead, Code Behind - JavaEye技术网站" # features/step_definitions/search_friends_step.rb:22 And it should point to "http://rednaxelafx.iteye.com/" # features/step_definitions/search_friends_step.rb:26 Failing Scenarios: cucumber features/search_friends.feature:9 # Scenario: search for iaimstar 2 scenarios (1 failed, 1 passed) 14 steps (1 failed, 1 skipped, 12 passed) 0m11.862s rake aborted! Command failed with status (1): [C:/Ruby/bin/ruby.exe -I "C:/Ruby/lib/ruby/...] (See full trace by running task with --trace)
如图:
![To囧:拿你来测测Watir..._第5张图片](http1://img.it610.com/image/product/4a097b7363be476d8fa85bb385a1addd.jpg)
Well .. . . 这次就玩到这里。Have fun ^_^
上面用RSpec和Cucumber的测试用文件打包放在附件里了
(嗯……原来这边用的测试框架是Test::Unit,我还以为会用到RSpec的说……)