28th Mar, 2008

RSpec Story简介

Story是RSpec的新功能,目前还处于试验阶段,在讲解RSpec Story之前,先让我们来看看什么是Story?

什么是Story?

Story是BDD中的概念,我们可以简单的将它看作是对应用特性的描述(feature),举个例子,比如我们现在要设计一个提款机的程序,那么以下两个story是必不可少的:

  1. 用户能够取出钱来
  2. 银行职员可以放钱进去

如何定义Story?

但是我们该如何描述一个Story呢?BDD对Story的结构进行了规范,下面给出Story的定义模板,这也是RSpec支持的格式:

Title (one line describing the story)

Narrative:
As a [role]
I want [feature]
So that [benefit]

Acceptance Criteria: (presented as Scenarios)

Scenario 1: Title
Given [context]
And [some more context]…
When [event]
Then [outcome]
And [another outcome]…

Scenario 2: …

我们可以看到,一个Story由2个部分组成:定义及场景,Story的定义包含3个部分:role(角色),feature(特性)以及benefit(结果),为了对结果进行度量,Story包含了许多的Scenario(场景),每个Scenario包含上下文,时间以及输出,有些抽象?让我们来看个例子,还以上面的取款机程序为例子,那么”用户能够取出钱来”的Story就可以这样定义:

Story: 允许用户取钱

作为一个用户
我想要从ATM取款
这样当银行下班之后我也可以得到现金

Scenario: 账户有足够的余额
Given 一张余额为 1000 块的卡
And 卡是有效的
And ATM机有足够现金
When 用户请求取款 100 块
Then ATM应该吐出 100 块现金
And 用户账户应该被扣除 100 块
And 卡应该被吐出

Scenario: 账户余额不足
Given 一张余额为50块的卡
And 卡是有效的
And ATM机有足够现金
When 用户请求取款100块
Then 提示用户余额不足
And ATM不应吐出钞票
And 用户账户余额应该为50
And 卡应该被吐出

应用RSpec测试Story

那么我们该如何使用RSpec来测试这个Story呢?假设我们将上面的Story保存为一个名为atm的文件,那么现在只需要定义一个atm.rb文件,并将他们保存在一个目录下,我们就可以通过atm.rb来运行这个Story了,atm.rb文件如下:

require ‘rubygems’
require ‘spec/story’

steps_for(:atm) do

# Given the string PeepCode
Given(“一张余额为 $credit 块的卡”) do |credit|
@origal = @credit = credit.to_i
end

Given(“卡是有效的”) do
end

Given(“ATM机有足够现金”) do
end

# When the string is reversed
When(“用户请求取款 $taken 块”) do |taken|
@credit = @credit – taken.to_i
end

# Then the result should be edoCpeeP
Then(“用户账户应该被扣除 $taken 块”) do |taken|
@credit.should == (@origal – taken.to_i)
end

Then(“ATM应该吐出 100 块现金”) do
end

Then(“卡应该被吐出”) do
end
end

with_steps_for(:atm) do
run “atm”
end

运行结果:

$ ruby atm.rb
Running 2 scenarios

Story: 允许用户取钱

作为一个用户
我想要从ATM取款
这样当银行下班之后我也可以得到现金

Scenario: 账户有足够的余额

Given 一张余额为 1000 块的卡
And 卡是有效的
And ATM机有足够现金

When 用户请求取款 100 块

Then ATM应该吐出 100 块现金
And 用户账户应该被扣除 100 块
And 卡应该被吐出

Scenario: 账户余额不足

Given 一张余额为50块的卡 (PENDING)
And 卡是有效的
And ATM机有足够现金

When 用户请求取款100块 (PENDING)

Then 提示用户余额不足 (PENDING)
And ATM不应吐出钞票 (PENDING)
And 用户账户余额应该为50 (PENDING)
And 卡应该被吐出

2 scenarios: 1 succeeded, 0 failed, 1 pending

Pending Steps:
1) 允许用户取钱 (账户余额不足): 一张余额为50块的卡
2) 允许用户取钱 (账户余额不足): 用户请求取款100块
3) 允许用户取钱 (账户余额不足): 提示用户余额不足
4) 允许用户取钱 (账户余额不足): ATM不应吐出钞票
5) 允许用户取钱 (账户余额不足): 用户账户余额应该为50

我们可以看到,第一个场景的测试获得了通过,而第二个场景则处于挂起状态,现在想必你已经对RSpec Story有了一个大概的了解,不过RSpec Story目前还处于试验阶段,因此不推荐应用到真实项目中,不过作为一种新的开发方式,保持一定的关注度还是有必要的。

参考:

留条评论?

Your response:

Categories