Rspec 基础

Posted by devon on February 18th, 2008 filed in 测试方法

gem方式安装(spec example.rb)

1
gem install rspec

plugin方式安装(script/spec example.rb)

1
2
ruby script/plugin install svn://rubyforge.org/var/svn/rspec/tags/CURRENT/rspec
ruby script/plugin install svn://rubyforge.org/var/svn/rspec/tags/CURRENT/rspec_on_rails

生成spec

1
2
3
script/generate rspec_model person
script/generate rspec_controller person
/script/generate rspec_scaffold post title:string body:text author:integer created_at:datetime updated_at:datetime

运行

1
2
3
4
script/spec spec/ (所有spec)
script/spec spec/controller/ (所有controller)
script/spec spec/model/ (所有model)
script/spec spec/controller/example_controller_spec.rb (测试单个controller)

更快的运行测试(需安装gem install rspec,推荐这种方式)
先运行

1
script/spec_server

然后,另开窗口运行(–drb)

1
script/spec spec/controller/example_controller_spec.rb --drb

Rake方式运行

1
2
3
4
5
6
7
8
rake spec (不包括plugins中的测试)
rake spec:all (包括plugins中的测试)
rake spec:app
rake spec:models
rake spec:controllers
rake spec:views
rake spec:helpers
rake spec:plugins

Controller中的常用断言

1
2
3
4
5
6
7
8
9
10
11
response.should be_success
response.should be_redirect
response.should render_template("path/to/template/for/action")
response.should have_text("expected text")
response.should redirect_to(:action => 'other_action')
 
assigns[:key]
flash[:key]
session[:key]
 
response.headers["Status"].should == "404 Not Found"

View中的常用断言

1
2
3
4
5
6
7
8
9
response.should have_tag('div') #passes if any div tags appear
response.should have_tag('div#interesting_div')
response.should have_tag('div', 'expected content')
response.should have_tag('div', /regexp matching expected content/)
response.should have_tag('ul') do
  with_tag('li', 'list item 1')
  with_tag('li', 'list item 2')
  with_tag('li', 'list item 3')
end

Model中的常用断言

1
2
3
4
5
6
Model.should have(:no).records
Model.should have(1).record
Model.should have(3).records
model.should have(:no).errors_on(:attribute)
model.should have(1).error_on(:attribute)
model.should have(3).errors_on(:attribute)

Mock

1
2
3
post = mock_model(Post) #使用mock object来代替真是的post对象
Post.should_receive(:find).and_return(post)  # @post = Post.find(params[:id]),返回这个mock object
Post.should_receive(:find).with({:title => 'post title', :body => 'post body'}).and_return(post)

Strings:

1
2
3
4
5
6
7
  'foo'.should == 'foo'
  'foo'.should === 'foo'
  'foo'.should_not equal('foo')
  ''.should be_empty
  'foo with bar'.should include('with')
  'http://fr.ivolo.us'.should match(/http:\/\/.+/i)
  nil.should be_nil

Numbers:

1
2
3
4
5
  100.should = 100
  (200 - 100).should == 100
 
  # (100 - 80) is less than 21
  100.should be_close(80,21)

Arrays:

1
2
3
  [1,2,3].should have(3).items
  [].should be_empty
  [1,2,3].should include(2)

Hashes:

1
2
3
4
5
  {}.should be_empty
  {:post => {:title => 'test'}}.should have_key(:post)
  {:post => {:title => 'test'}}.should_not have_key(:title)
  false.should be_false
  true.should be_true

Before与After filter

1
2
3
4
5
  before(:each) do
  end
 
  after(:all) do
  end

用户登录
增加该方法到spec_helper.rb的未尾

1
2
3
def login_as(user)
  @request.session[:user] = user ? users(user).id : nil
end

然后在controller_spec中

1
2
3
4
5
  fixtures :users
 
  before :each do
    login_as :normal
  end

integrate_views
在controller中加入该声明,则在controller中可以直接调用model spec中的方法,比如 response.should have_tag

1
2
3
4
describe ArticlesController do
  integrate_views
  ...
end

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
require File.dirname(__FILE__) + '/../spec_helper'
 
describe RecommendsController do
  fixtures :users
 
  before :each do
    login_as :normal
  end
 
  it "[post] /create should create a new recommend" do
    post :create, :type => 'Blog', :id => 1
    response.should be_success
 
    assigns[:recommend].should_not be_nil
    assigns[:recommend].recommendable_id.should equal(1)
  end
 
end

在users.yml中定义用户normal

1
2
3
4
5
normal:
    login: normal
    email: normal@example.com
    salt: 7e3041ebc2fc05a40c60028e2c4901a81035d3cd
    crypted_password: 00742970dc9e6319f8019fd54864d3ea740f04b1 # test

参考:
使用 RSpec 进行行为驱动测试
Rspec Rdoc
Rspec for Rails Rdoc

Related posts:

  1. shoulda on rails 在新项目中配置shoulda rails shoulda_demo -d mysql cd shoulda_demo/ script/plugin install git://github.com/thoughtbot/shoulda.git...

Related posts brought to you by Yet Another Related Posts Plugin.

Leave a Comment