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

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的测试进化过程,还是能够看到一些东西。

你可能感兴趣的:(Ruby,Rails,rspec,rack,Sinatra)