InfoQ

新闻

RSpec增加了众所翘首以待的RBehave功能以供集成测试所需

作者 Sean Miller 译者 张海龙 发布于 2007年10月31日 上午9时56分

社区
Ruby,
Agile
主题
质量交付,
客户及需求
标签
行为驱动开发,
测试,
RBehave,
RSpec

RSpec是 一个为Ruby编写的基于行为驱动开发(简称BDD,即Behaviour-Driven Development)的验收测试框架,同时也可用于Java(事实上它一直都可以运行于JRuby中),它提供了一种机制,即由开发人员从业务中获取 验收标准并将它们转换为可读、可运行的示例,以此替代文档、测试和适用于业务的构建报告。

尽管RSpec对单元级测试很有用,但它在集成测试中一直存在一个盲点。Dan North创建了一个独立的扩展,RBehave,它用Given…With…Then…这样的格式以一系列的步骤从故事级别来描述行为。(North最早是在JBehave中描述了这种用于获得需求故事的模式)

David Chelimsky现在已经向RSpec trunk中合并了一个纯文本故事运行器(Plain Text Story Runner),它给RSpec添加了RBehave功能,就像他 他的 博客中描述的那样。

现在看看North的经典RBehave示例:

So, North's classic RBehave example:
require ‘rubygems’
require ‘rbehave’
require ’spec’ # for "should" method

require ‘account’ # the actual application code

Story "transfer to cash account",
%(As a savings account holder
  I want to transfer money from my savings account
  So that I can get cash easily from an ATM) do

  Scenario "savings account is in credit" do
    Given "my savings account balance is", 100 do |balance|
      @savings_account = Account.new(balance)
    end
    Given "my cash account balance is", 10 do |balance|
      @cash_account = Account.new(balance)
    end
    When "I transfer", 20 do |amount|
      @savings_account.transfer_to(@cash_account, amount)
    end
    Then "my savings account balance should be", 80 do |expected_amount|
      @savings_account.balance.should == expected_amount
    end
    Then "my cash account balance should be", 30 do |expected_amount|
      @cash_account.balance.should == expected_amount
    end
  end

  Scenario "savings account is overdrawn" do
    Given "my savings account balance is", -20
    Given "my cash account balance is", 10
    When "I transfer", 20
    Then "my savings account balance should be", -20
    Then "my cash account balance should be", 10
  end
end

在新的RSpec中它可以变成这样,由一个Ruby文件定义可用的步骤:

class AccountSteps < Spec::Story::StepGroup
  steps do |define|
    define.given("my savings account balance is $balance") do |balance|
      @savings_account = Account.new(balance.to_f)
    end

    define.given("my cash account balance is $balance" do |balance|
      @cash_account = Account.new(balance.to_f)
    end

    define.then("my savings account balance should be $expected_amount" do |expected_amount|
      @savings_account.balance.should == expected_amount.to_f
    end

    define.then("my cash account balance should be $expected_amount" do |expected_amount|
      @cash_account.balance.should == expected_amount.to_f
    end
  end
end

steps = AccountSteps.new do |define|
  define.when("I transfer $amount") do |amount|
    @savings_account.transfer_to(@cash_account, amount.to_f)
  end
end
在一个纯文本文件中按照那些步骤定义故事的行为:
Story: transfer to cash account
  As a savings account holder
  I want to transfer money from my savings account
  So that I can get cash easily from an ATM

  Scenario: savings account is in credit
    Given my savings account balance is 100
    And my cash account balance is 10
    When I transfer 20
    Then my savings account balance should be 80
    And my cash account balance should be 30

  Scenario: savings account is overdrawn
    Given my savings account balance is -20
    And my cash account balance is 10
    When I transfer 20
    Then my savings account balance should be -20
    And my cash account balance should be 10

由一个Ruby文件将他们粘在一起,并运行这些故事:

require 'spec'
require 'path/to/your/library/files'
require 'path/to/file/that/defines/account_steps.rb'

# assumes the other story file is named the same as this file minus ".rb"
runner = Spec::Story::Runner::PlainTextStoryRunner.new(File.expand_path(__FILE__).gsub(".rb",""))
runner.steps << AccountSteps.new
runner.run

纯文本文件中的那些步骤描述,必须与StepGroup中定义的步骤相匹配,这些描述可能会随着步骤数量的增加变得难以理解。Aslak Hellesøy正在为一个基于浏览器的编缉器工作,它将提供步骤的自动补全,并可以在恰当的位置对参数进行编辑,从而使这一问题得以简化。

查看英文原文RSpec Trunk Now Includes RBehave-like Story Runner

RSpec 用起来还是相当棒的 发表人 Raecoo cao 发表于 2007年11月2日 下午10时1分
  1. 返回顶部

    RSpec 用起来还是相当棒的

    2007年11月2日 下午10时1分 发表人 Raecoo cao

    RSpec 用起来还是相当棒的
    特别是以测试代码来表现文档,不需要再去特意撰写相关文档
    希望有机会可以和大家一起交流
    raecoo AT gmail.com

深度内容

模块化Java:声明式模块化

本文是模块化Java系列文章的第4篇,介绍的是声明式模块化。文中描述了组件如何以声明的方式来定义并组织在一起,而无需让代码依赖于OSGI API。

Ian Robinson和Jim Webber谈论基于Web的整合

本采访是在伦敦举行的QCon2009上记录的,Ian Robinson和Jim Webber探讨了如何将Web作为整合平台以及REST在理论上和实践中的好处。

项目管理修炼之道(精选版)

项目管理对于项目成败至关重要,但实践中每个项目都有自己的独特性,没有现成的解决方案可以套用。书中从应对实际风险的角度出发,讲述了从项目启动、项目规划到项目结束的整个管理流程,展示了作者的思考过程。本迷你书从原书中精选出5个章节。

那是鸟,还是飞机?不,那是超人!

在这个演讲中,Fred将会揭示敏捷的一些外在因素,并会重点关注敏捷获得成功的内在原因。从案例研究和真实的项目经验来看,Fred认为:工具、管理体系都不能让你变得敏捷。敏捷的成功,植根于士气高涨、充分授权的工作者身上,他们能够以不同以往的方式思考问题。

访谈和书摘:Eben Hewitt的新书《Java SOA Cookbook》

Java SOA Cookbook

Eben Hewitt的新书《Java SOA Cookbook》从Java实现的角度讨论了面向服务架构。Eben在书中讨论了SOA基础、工具、最佳实践和SOA治理等主题。

Mark Richard的《Java消息服务》第二版

Mark Richards的新书《Java消息服务》第二版覆盖了JMS的许多主题, 包括发布和订阅模式以及点对点模式,消息过滤和事务等。InfoQ与Mark谈论了跟他的新作。

模块化Java:动态模块化

本文是“模块化Java”系列文章的第三篇,讨论动态模块化,内容涉及如何解析bundle类、bundle如何变化、以及bundle之间如何通信。

让测试也敏捷起来

对于测试组织来说,敏捷方法带来的快速迭代却让测试本身变得困难起来:缺乏“足够详细的文档”,缺乏“仔细设计用例的时间”等等。在本演讲中,段念将与大家探讨如何在敏捷过程中进行测试。