RSpec基础介绍

343 阅读2分钟

RSpec是用于Ruby语言的BDD测试框架。主要有3个独立的部分组成:

  1. rspec-core
  2. rspec-expectation
  3. rspec-mocks

RSpec提供的API允许我们以一种贴近自然语言表达的方式来编写测试用例。

目录结构

通常使用RSpec的项目目录结构如下:

<your project>
    |--> lib/ # 源代码目录
    |-->spec/ # 测试文件放入spec目录
        |-->xxxx_spec.rb # xxxx_spec.rb为测试文件

基础概念

RSpec中包括如下基础概念:Group,Example, Expectation

  1. Group:表示测试用例的集合
  2. Example:功能API的使用示例
  3. Expectation:功能API的执行期望结果

test,spec和example的区别

这3个概念都表示我们编写的测试用例,可以互相替换使用,但是各自的语义侧重不同:

  1. test:验证一段代码执行正确
  2. spec:描述一段代码的期望行为
  3. example:展示API的期望应用方式

针对上述概念,RSpec提供了如下的API:

  1. RSpec.describe:创建example结合(测试用例集合,记得test、spec和example是可替换的概念,只是语义侧重不同)
  2. it:创建单个的example(单个的测试用例)
  3. expect:验证期望的结果(其他测试框架中的assert语句)

举例子:

Sandwich = Struct.new(​:taste​, ​:toppings​)

RSpec.describe 'An ideal sandwich' do
  it 'is delicious' do
    sandwich = Sandwich.new(​'delicious', [])
    taste = sandwich.taste
    expect(taste).to eq('delicious')
  end
end

执行测试

在项目目录下执行rspec命令,RSpec会在spec目录下寻找xxxx_spec.rb的文件,将其作为测试文件,并运行其中的测试用例。

共享设置

一个example组里,多个example执行前可能会设置相同的东西,RSpec提供了3种方式方便我们抽取设置(set up)逻辑:

Hooks

RSpec提供了before方法,该方位会在每个example(test,或者叫spec)执行前执行。

Sandwich = Struct.new(​:taste​, ​:toppings​)

RSpec.describe 'An ideal sandwich' do

  before {@sandwich = Sandwich.new('sandwich', [])}

  it 'is delicious' do
    taste = @sandwich.taste
    expect(taste).to eq('delicious')
  end
end

Helper方法

每个example组都是一个Ruby类。所以,我们可以在类中定义helper方法,达到设置共享的目的,如:

Sandwich = Struct.new(​:taste​, ​:toppings​)

RSpec.describe 'An ideal sandwich' do

  def sandwich 
    @sandwich ||= Sandwich.new('sandwich', [])
  end

  it 'is delicious' do
    taste = sandwich.taste
    expect(taste).to eq('delicious')
  end
end

使用let

RSpec提供了let函数,方便设置共享,可以将上述例子的helper方法替换成如下的函数定义。

let(:sandwich) { Sandwich.new('delicious', [])}

let将变量sandwich与后面的block绑定,使用了memoization技术,当有example首次访问sandwich变量的时候,关联的block执行将结果保存,后续对sandwich的访问都会直接返回。

Content mainly from 「Effective testing with Rspec 3」by Myron Maston, Ian Dees