To囧:拿你来测测Watir...

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张图片

(这个测试是昨晚做的,发帖时Google的搜索结果发生了变化,JavaEye的结果跑到第二位了。有兴趣的同学可以照着做一次这个测试,观察一下测试失败时的输出)
To囧:拿你来测测Watir..._第2张图片

关于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

===========================================================================

不过既然有要达成某个结果有清晰的流程,那干脆把流程在代码里再写得清晰些。
确保安装上 CucumberRakeWin32::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张图片
可以看到有了描述的场景在还没有代码去实现它的时候是黄色的。

在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张图片
被跳过的步骤用蓝色表示。

现在只剩把测试的实现与测试对象组装到一起了。为了准备好要用的库,在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张图片

Well .. . . 这次就玩到这里。Have fun ^_^
上面用RSpec和Cucumber的测试用文件打包放在附件里了

(嗯……原来这边用的测试框架是Test::Unit,我还以为会用到RSpec的说……)

你可能感兴趣的:(Google,C#,Ruby,rubygems,rspec)