一、安装
- ruby使用
gem install rspec
# 文件夹下执行
rspec --init
# 生成
create .rspec
create spec/spec_helper.rb
- rails添加gem
group :development, :test do
gem 'rspec-rails'
end
# 生成
rails generate rspec:install
二、 配置
基础配置文件spec_helper.rb
# spec_helper.rb
config.default_formatter = "doc"
RSpec.describe :test_spec do
describe 'batch_confirm_qs' do
it 'should eq 5' do
expect(5).to eq(5)
end
end
end
- 配置formatter前,只显示绿点,配置formatter后,会显示测试的结构
三、执行
# 运行所有测试
rspec .
# 运行某个测试文件
rspec test_spec.rb
# 运行test_spec.rb中某个it用例, 加上it前面的行号
rspec test_spec.rb:19
# 运行test_spec.rb中多个it用例,行号用冒号隔开
rspec test_spec.rb:19:32:44
# 运行多个文件
rspec test1_spec.rb test2_spec.rb
四、使用
1. describe/ context /it 角色区别
describe “描述”一组测试
context 通常用来表示不同的状况,如“当”使用者是管理员,“使用者有某某某属性”,或者if…else等
it 用来写一条具体测试用例
2. describe起名字
class Ruby
def initialize(programmer)
end
def self.goal
"make programmer happy"
end
def happy?
true
end
end
# foo/programmer.rb
class Programmer
end
# foo/ruby_spec.rb
require_relative "./ruby"
require_relative "./programmer"
RSpec.describe Ruby do
describe ".goal" do
it {
expect(Ruby.goal).to eq "make programmer happy" }
end
describe "#happy?" do
it "yes, always happy" do
programmer = Programmer.new
rubyist = Ruby.new(programmer)
expect(rubyist.happy?).to eq true
end
end
end
- 类别方法的测试,使用一个点(.),加上方法名称:.method_name来引用。
- 实体方法的测试,使用一个井号(#),加上方法名称:#method_name来引用。
RSpec.describe "#even? method" do
context "with even number" do
it "should return true" do
expect(6.even?).to eq(true)
end
end
context "with odd number" do
it "should return false" do
expect(9.even?).to eq(false)
end
end
end
# 每个方法内有if-else,不同的情况,可以用context 来区分。
describe ".find_or_create_with" do
context "with existing user" do
...
end
context "with new user" do
...
end
end
- 有人用describe 来替代context,也是完全可以的,两者在实际做用上没有什么差别。
- 整个context 方法最重要的就是组织程式码,使其易读,且当你使用context 时,请用when with without 来做开头!
3. let before方法
RSpec.describe Store do
it 'have name' do
store = Store.new 'Happy'
expect(store.name).to eq 'Happy'
end
it 'sale product' do
store = Store.new 'Happy'
expect(store.sale).to eq('Earn money')
end
end
- 两个测试用例中都有 store = Store.new ’Happy’,使用 let 重构
RSpec.describe Store do
let(:store) {
Store.new 'Happy' }
it 'have name' do
expect(store.name).to eq 'Happy'
end
it 'sale product' do
expect(store.sale).to eq('Earn money')
end
end
- 使用before重构
RSpec.describe Store do
before(:all) do
@store = Store.new 'Happy'
end
it 'have name' do
expect(@store.name).to eq 'Happy'
end
it 'sale product' do
expect(@store.sale).to eq('Earn money')
end
end
- before(:each)会在每个测试用例前执行, 不管有没有调用,都会执行(每段it之前執行),可以只写before
- before(:all) 会所有测试用例执行前,只执行一次,(一個RSpec.describe只執行一次。)
- let == before(:each),寫法不同外,有 lazy load 的特性,只有呼叫時才執行,如果你寫了一堆 let 但 example 裡沒使用,那麼就不會被賦值。
- let! 和 before(:each)一样,会在每个let前都执行
4.Subject
- 基础使用
RSpec.describe Hash do
it "should be empty" do
expect(subject.length).to eq(0) # 注意里边的subject
end
end
-
如果你的最上层RSpec.describe 后方接的是class 类名,那subject 就会依照这个类的预设值去做new 的动作。
-
相当于
let(:subject) { Hash.new }
-
给subject初始化
RSpec.describe Hash do
subject {
{
a: 3, b