Rails 集成测试写法的变化过程 Rails测试方法合集

在[url]http://giantrobots.thoughtbot.com[/url]逛的时候看到的,小夜觉得有些东西还是能说明问题的,就抄回来了。
[size=large]Productivity and happiness.[/size]这是Ruby和Rails升起的原因,也是integration testing能够持续变化的原因。当然,原文作者客气的说,这只是个人理解并没有科学证据。

[size=large]2006[/size]

使用如下方法[quote]get, post, follow_redirect!, xml_http_request, status, path, and open_session[/quote]通过assert_equal来验证。通常写法如下:

class ExampleTest < ActionController::IntegrationTest
def test_login
get "/login"
assert_equal 200, status

post "/login",
:username => people(:jamis).username,
:password => people(:jamis).password
follow_redirect!

assert_equal 200, status
assert_equal "/home", path
end
end


[size=large]2007[/size]

[size=large][color=red]RSpec[/color][/size]引入所谓行为驱动,就是故事模式如下:

Scenario "Root user" do
Given "a user named", "admin"
And "a company named", "Company1"
And "a company named", "Company2"

And "the user has the role", "root" do |role|
@user.update_attribute :role, role
end
And "logged in as", "admin"

When "visiting", "/"

Then "viewer should see", "main/root_home"
And "page should show company named", "Company1" do |name|
response.should have_text(/#{name}/)
end
And "page should show company named", "Company2"
end


[size=large][color=red]Webrat[/color][/size]在这个时候模拟浏览器行为用于测试网页。 [color=red]DSL[/color]通过[quote]click_link, fill_in, and click_button[/quote]

[color=red]Webrat[/color]可以和 配合使用[color=red]Nokogiri[/color]测试网页,使用XPath 和 CSS selectors来验证HTML的返回。
通常这样写:

def test_sign_up
visits "/"
clicks_link "Sign up"
fills_in "Email", :with => "good@example.com"
select "Free account"
clicks_button "Register"
...
end

[size=large]
2008[/size]

[size=large][color=red]Merb[/color][/size]推荐使用request方法。而这也比dispatch_to更容易。通常会用到[quote] be_successful and redirect_to[/quote]

这时[size=large][color=red]Cucumber[/color][/size]取代讲故事的Story Runner模式。如下:
Feature: Addition
In order to avoid silly mistakes
As a math idiot
I want to be told the sum of two numbers

Scenario: Add two numbers
Given I have entered 2 into the calculator
And I have entered 2 into the calculator
When I press add
Then the result should be 4 on the screen



Given /^I signed up with "(.*)\/(.*)"$/ do |email, password|
user = Factory :user,
:email => email,
:password => password,
:password_confirmation => password
end

[size=large]2009
[/size]
Integration testing 成为主流

[color=red][size=large]Rack::Test[/size][/color]通过给测试框架提供一个公用的接口来和Rack应用交互。

[quote]Rack::Test pays homage to the frameworks before it, using methods that match the HTTP verbs: get, post, put, and delete, head) and adding request (Merb) and follow_redirect! (Rails). It also handles HTTP authentication and stores requests and responses in last_request and last_response.[/quote]

示例如下:

class HelloWorldTest < Test::Unit::TestCase
include Rack::Test::Methods

def app
[color=red]Sinatra[/color]::Application
end

def test_it_says_hello_world
get '/'
assert last_response.ok?
assert_equal 'Hello World', last_response.body
end

def test_it_says_hello_to_a_person
get '/', :name => 'Simon'
assert last_response.body.include?('Simon')
end
end


[color=red]Cucumber and Webrat [/color]也得到发展


Feature "A Tomatoist does a pomodoro" do
Story <<-eos
In order to perform a focused unit of work
As a Tomatoist
I want to start a pomodoro
eos

Scenario "Starting a pomodoro" do
When "I go to the home page" do
executes { visit '/' }

Then "I should be sent to a new session" do
current_url.should =~ /\/\w{3,}/
end

And "I should see an unstarted timer" do
response.should have_tag('#timer .countdown_row','00:00')
end

When "I click the pomodoro button" do
executes do
@session_url = current_url
click_button 'Pomodoro'
end

Then "I should be on my session's page" do
current_url.should == @session_url
end

And "my timer history should show the current pomdoro" do
response.should have_tag('#history ul li', /Pomodoro/, 1)
end
end
end
end
end


[size=large][color=red]Coulda[/color][/size]同样使用定义语言通过[color=red]Webrat[/color]或者其他库来模拟浏览器行为如下:

Feature "Painfully obvious" do
in_order_to "demonstrate a simple test"
as_a "coulda developer"
i_want_to "provide a straight-forward scenario"

Scenario "Describing something obvious" do
Given "something without a value" do
@no_value = nil
end

When "I give it a value" do
@no_value = true
end

Then "it should have a value" do
assert(@no_value)
end
end
end

[color=red]Given[/color]同样

class StackBehavior < Given::TestCase
Invariant { expect(@stack.depth) >= 0 }
Invariant { expect(@stack.empty?) == (@stack.depth == 0) }

def empty_stack
@stack = Stack.new
end

Given(:empty_stack) do
Then { expect(@stack.depth) == 0 }

When { @stack.push(:an_item) }
Then { expect(@stack.depth) == 1 }
Then { expect(@stack.top) == :an_item }

When { @stack.pop }
FailsWith(Stack::UsageError)
Then { expect(exception.message) =~ /empty/ }
end
end


[quote]I write about 50 lines of horrible hacks. It brings the Given/When/Then DSL to Test::Unit. It relies on Webrat and Rack::Test to simulate the browser and theoretically work for all Rack apps (only tested on Sinatra). I keep the nesting totally flat, as is my style. It looks like this:[/quote]

Feature 'Shorten URL' do
Given 'I am on the homepage' do
visit '/'
end

When 'I submit http://example.com' do
fill_in 'url', :with => 'http://example.com'
click_button 'shorten'
end

Then 'I should see a short link' do
assert_have_selector 'a#short'
end

When 'I follow the short link' do
click_link 'short'
end

Then 'I should be on http://example.com' do
assert_equal 'http://example.com', current_url
end
end


原文还有一些解释,没太注意,然而,从这样一个Rails的测试进化过程,还是能够看到一些东西。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值