在
http://giantrobots.thoughtbot.com逛的时候看到的,小夜觉得有些东西还是能说明问题的,就抄回来了。
Productivity and happiness.这是Ruby和Rails升起的原因,也是integration testing能够持续变化的原因。当然,原文作者客气的说,这只是个人理解并没有科学证据。
2006
使用如下方法
引用
get, post, follow_redirect!, xml_http_request, status, path, and open_session
通过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
2007
RSpec引入所谓行为驱动,就是故事模式如下:
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
Webrat在这个时候模拟浏览器行为用于测试网页。
DSL通过
引用
click_link, fill_in, and click_button
Webrat可以和 配合使用
Nokogiri测试网页,使用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
2008
Merb推荐使用request方法。而这也比dispatch_to更容易。通常会用到
引用
be_successful and redirect_to
这时
Cucumber取代讲故事的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
2009
Integration testing 成为主流
Rack::Test通过给测试框架提供一个公用的接口来和Rack应用交互。
引用
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.
示例如下:
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
Cucumber and Webrat 也得到发展
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
Coulda同样使用定义语言通过
Webrat或者其他库来模拟浏览器行为如下:
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
Given同样
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
引用
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:
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的测试进化过程,还是能够看到一些东西。