在[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 => "[email protected]"
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模式。如下:
[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]或者其他库来模拟浏览器行为如下:
[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的测试进化过程,还是能够看到一些东西。