(转自:http://www.cnblogs.com/jarodzz/archive/2012/07/02/2573014.html)

第一次看到Cucumber和BDD(Behavior Driven Development, 行为驱动开发),是在四年前。那时才開始工作,对软件測试工具相当着迷。仅仅要是开源的、免费的,我就一定要下载,安装,试用。有的工具用途单一、好懂(如Jmeter,Watir);有的工具,则涉及到一些软件领域的独有概念,不好懂,(如STAF,Cucumber)。好懂的,我上手、试用、推广,不亦乐乎;不好懂的,就仅仅能丢在一边,这里面就包含Cucumber。

再次看到Cucumber,已是两年前。我对软件开发的理解也深了些,这一看,可真是个好东西。之后我与Cucumber间发生的故事,稍后慢慢向大家交代。这开篇的第一章,我想献给如当年的我一样,偶然见到了Cucumber和BDD,却不明所以将之丢在一边的家伙们。

初闻Cucumber的人,第一件事一定是来到Cucumber的首页,第一眼看到的一定是

非常不幸的是,这六张图不太好懂。由于它们依照BDD的流程来编写的。为了让它们好懂些,我们抛开BDD,採用传统的软件开发模型(设计->编码->測试)来看它。传统流程例如以下:

图1,这是一个被測系统——用ruby编写的计算器。

为了便于大家理解,我试着改动了一些。

?
class Calculator 
  def push(n)   
#记数
    @args ||=
[]
#初始化空数组
    @args <<
  end
  def sum()     
#返回全部数字和
    sum
=
0
    @args.each do |i|
      sum
+= i
    end
    @result =
sum
  end
  def result
    @result
  end
end

计算器Calculator提供两个功能: 记数push;加和sum。push将数字一一记录在@args数组中;sum则将全部@args数组中的数字累加得和,存入@result中。写完了被測系统,我们来编写測试用例。

图2,这是为了測试上述计算器,使用Cucumber描写叙述的測试用例。

原图中的英文描写叙述,被我翻译成了中文。:

?
Feature:
计算器
  Scenario:
两数相加
    Given
我有一个计算器
    And
我向计算器输入
50
    And
我向计算器输入
70
    When
我点击累加
    Then
我应该看到结果
120

支持中、英等自然语言,是Cucumber的特点之中的一个。在Cucumber的帮助文档里,声明它支持包含中文简体、繁体中文、日文、韩文和英文在内的45种语言。

注意:我并未将全部英文都翻译成中文,而是留下了几个keyword:

  • Feature(功能)
  • Scenario(情景)
  • Given(给定)
  • And(和)
  • When(当)
  • Then(则)

它们的含义与原有自己主动化測试工具中的概念同样,类比方下:

Cucumber Unit Test
Feature (功能) test suite (測试用例集)
Scenario(情景) test case (測试用例)
Given(给定) setup(创建測试所需环境)
When(当) test(触发被測事件)
Then(则) assert(断言,验证结果)

Cucumber放弃了原有的keyword,而选择了左边五种,仅仅是为了更加流畅地支持自然语言。使用Cucumber的keyword,创建了測试用例,接下来,要怎样使用Cucumber来执行它呢?

图3,这是执行Cucumber时的画面。

在一台安装好Cucumber的机器上,执行上述測试用例,便能够看到下列输出:

?
Feature:
计算器
 
  Scenario:
两数相加   
#
features/calculator.feature:3
    Given
我有一个计算器  
#
features/calculator.feature:4
    And
我向计算器输入
50   #
features/calculator.feature:5
    And
我向计算器输入
70   #
features/calculator.feature:6
    When
我点击累加     
#
features/calculator.feature:7
    Then
我应该看到结果
120 #
features/calculator.feature:8
 
1 scenario
(
1 undefined)
5 steps
(
5 undefined)
0m0.005s
 
You
can implement step definitions
for undefined
steps with these snippets:
 
Given
/^我有一个计算器$/
do
  pending
#
express the regexp above with the code you wish you had
end
 
Given
/^我向计算器输入(\d+)$/
do |arg1|
  pending
#
express the regexp above with the code you wish you had
end
 
When
/^我点击累加$/
do
  pending
#
express the regexp above with the code you wish you had
end
 
Then
/^我应该看到结果(\d+)$/
do |arg1|
  pending
#
express the regexp above with the code you wish you had
end

Cucumber首先输出的是測试用例的描写叙述,然后3行总结性地输出:本功能(Feature)有1个情景(1 scenario);5个步骤(5 steps),所有5个步骤均没有定义(undefined);执行耗时0.005秒。这里出现了两个新名词:步骤(steps)和步骤定义(step definitions)。在Cucumber中,以keywordGiven, And, When, Then开头的每一行,为一个步骤。在两数相加的情景中,一共同拥有5行。因此,结果显示:5个步骤。

怎样定义一个步骤,在Cucumber的执行结果中也给出了具体的办法。在3行总结性输出后,紧接着便是:You can implement…即:你能够使用以下的代码段实现步骤定义,然后是4个小的代码段。这些代码段,便是Cucumber按照情境中我们使用的5个步骤,帮助我们生成的步骤定义框架。每一个框架都将内容部分空白出来,等待填充。以下,我们来进行步骤定义。

图4, 这是一个步骤定义的代码示范。

我们按照图2的样子,向中文步骤中填入代码,例如以下:

?
Given
/^我有一个计算器$/
do
  @c =
Calculator.
new
end
 
Given
/^我向计算器输入(\d+)$/
do |num|
  @c.push(num.to_i)
end
 
When
/^我点击累加$/
do
  @c.sum
end
 
Then
/^我应该看到结果(\d+)$/
do |result|
  @c.result.should
== result.to_i
end

步骤定义的过程,就是向代码段——步骤定义框架——中填入代码的过程,即:用代码来描写叙述你期望的,该步骤应该运行的动作。完整的步骤定义是一个函数,它:

  • 以正則表達式作为函数名
  • 匹配值作为參数
  • 以測试人员输入的代码作为内容

由于有了正則表達式的匹配,5个步骤仅须要4个步骤定义。“我向计算器输入50、70”两个步骤,都能够用“我向计算器输入(\d+)”一个正則表達式来描写叙述。匹配值被自己主动提取出来作为參数,传入代码。注意:全部匹配值,即參数,都是以字符串的形式传递,因此,我增加了num.to_i
与 result.to_i,将得到的字符串转为整形。步骤定义完毕,再次运行Cucumber。屏幕将会显示一片绿色。

图5,它是一个运行Cucumber測试用例,并成功通过的画面。

步骤定义完毕后,再次执行Cucumber。Cucumber会找到步骤定义,并依照其代码去执行。结果例如以下:

?
Feature:
加法
 
  Scenario:
两数相加   
#
features/calculator.feature:3
    Given
我有一个计算器  
#
features/step_definitions/a.rb:2
    And
我向计算器输入
50   #
features/step_definitions/a.rb:6
    And
我向计算器输入
70   #
features/step_definitions/a.rb:6
    When
我点击累加     
#
features/step_definitions/a.rb:10
    Then
我应该看到结果
120 #
features/step_definitions/a.rb:14
 
1 scenario
(
1 passed)
5 steps
(
5 passed)
0m0.003s

步骤定义被我保存在目录step_definitions下的a.rb其中。步骤定义所在文件与起始行数,被打印在每一个步骤结尾,以方便查找和改动。最后,Cucumber总结性地输出执行结果:1个情景,5个步骤,所有通过。

图6, 这是一个运行Cucumber測试用例,但失败的画面。

为了让这个已经十分简单的计算器产生bug,我仅仅好将它改错为:

?
class Calculator
  def sum()
    sum
=
0
    @args.each do |n|
      sum
= n   
#此处原为:sum
+= n
    end
    @result =
sum
  end
end

再次执行Cucumber,结果为:

?
Feature:
加法
 
  Scenario:
两数相加   
#
features/calculator.feature:3
    Given
我有一个计算器  
#
features/step_definitions/a.rb:2
    And
我向计算器输入
50   #
features/step_definitions/a.rb:6
    And
我向计算器输入
70   #
features/step_definitions/a.rb:6
    When
我点击累加     
#
features/step_definitions/a.rb:10
    Then
我应该看到结果
120 #
features/step_definitions/a.rb:14
      expected:
120
           got:
70 (using
==) (RSpec::Expectations::ExpectationNotMetError)
      ./features/step_definitions/a.rb:15:in `/^我应该看到结果(\d+)$/'
      features/calculator.feature:8:in `Then
我应该看到结果
120'
 
Failing
Scenarios:
cucumber
features/calculator.feature:
3 #
Scenario: 两数相加
 
1 scenario
(
1 failed)
5 steps
(
1 failed,
4 passed)
0m0.004s

失败的步骤是用红色标示出来的。在最后一个步骤中,Cucumber期待的结果为120,但得到的是70。注意:失败的情景列表(Failing Scenarios)里列出的是:“两数相加”这个情景所在的文件与起始行数。这是由于一个功能文件内,可能含有多个情景,这样的输出能够便于找到出错的情景。

接下来的总结性结果为:1个情景失败(1 failed),5个步骤中,4个通过,1个失败。

作为自己主动化測试工具的Cucumber,就介绍到这里。

在继续之前,我们先回想一下本章内容。

回想:

    • Cucumber是一个自己主动化測试工具
    • 它提供了自然语言的支持,我们能够用自然语言描写叙述、并运行測试用例
    • 它提供了自然语言与代码的衔接,通过步骤与步骤定义
    • 它提供了自然语言对代码的调用,当步骤定义结束后,执行Cucumber,它会自己主动调用步骤定义内的代码执行
    • 它提供了良好的断言(assert)机制。当运行失败时,我们能够看到完毕的測试用例,以及明白的失败原因。

Cucumber 入门一的更多相关文章

  1. 使用calabash测试开源中国Android客户端

    Calabash-android是支持android的UI自动化测试框架,前面已经介绍过<中文Win7下成功安装calabash-android步骤>,这篇博文尝试测试一个真实应用:开源中 ...

  2. cucumber java从入门到精通(4)Scenario Outline及数据驱动

    cucumber java从入门到精通(4)Scenario Outline及数据驱动 到目前为止,我们的TodoList类工作良好,不过离我们的预期--任务清单系统还是有不少差距,究其原因不过如下: ...

  3. cucumber java从入门到精通(3)简单实现及断言

    cucumber java从入门到精通(3)简单实现及断言 上一节里我们定义了step的java代码实现文件,step就是测试步骤及断言的集合,我们先定义出来,以后可以驱动开发以及在持续集成时重用. ...

  4. cucumber java从入门到精通(2)用代码定义步骤

    cucumber java从入门到精通(2)用代码定义步骤 上一节里我们定义了feature文件,feature文件就是自然语言描述的用例文件,它有一定的章法,具体的潜规则是: 使用Feature关键 ...

  5. cucumber java从入门到精通(1)初体验

    cucumber java从入门到精通(1)初体验 cucumber在ruby环境下表现让人惊叹,作为BDD框架的先驱,cucumber后来被移植到了多平台,有cucumber-js以及我们今天要介绍 ...

  6. Apple Swift编程语言入门教程

    Apple Swift编程语言入门教程 作者: 日期: 布衣君子 2015.09.22 目录 1   简介 2   Swift入门 3   简单值 4   控制流 5   函数与闭包 6   对象与类 ...

  7. Swift语言入门之旅

    Swift语言入门之旅  学习一门新的计算机语言,传统来说都是从编写一个在屏幕上打印"Hello world"的程序開始的.那在 Swift,我们使用一句话来实现它: printl ...

  8. [转]Swift 编程语言入门教程

    今天在网上看到一篇非常好的教程,分享给大家 原文地址:http://gashero.iteye.com/blog/2075324 目录 1   简介 2   Swift入门 3   简单值 4   控 ...

  9. Apple Swift编程语言入门

    1   简单介绍 今天凌晨Apple刚刚公布了Swift编程语言,本文从其公布的书籍<The Swift Programming Language>中摘录和提取而成.希望对各位的iOS&a ...

随机推荐

  1. Solr部署如何启动

    我刚接触solr,我要怎么启动,这是群里的朋友问得比较多的问题, solr最新版本下载地址: http://www.apache.org/dyn/closer.cgi/lucene/solr/ 1.准 ...

  2. 锋利的jQuery读书笔记---jQuery中动画

    jQuery中的动画: 1.show和hide 2.fadeIn和fadeOut 3.slideUp和slideDown <!DOCTYPE html> <html> < ...

  3. System Services -> Memory Management -> About Memory Management

    Virtual Address Space Memory Pools Memory Performance Information Virtual Memory Functions Heap Func ...

  4. 【转】一致性hash算法(consistent hashing)

    consistent hashing 算法早在 1997 年就在论文 Consistent hashing and random trees 中被提出,目前在 cache 系统中应用越来越广泛: 1  ...

  5. JVM 性能调优实战之:使用阿里开源工具 TProfiler 在海量业务代码中精确定位性能代码

    本文是<JVM 性能调优实战之:一次系统性能瓶颈的寻找过程> 的后续篇,该篇介绍了如何使用 JDK 自身提供的工具进行 JVM 调优将 TPS 由 2.5 提升到 20 (提升了 7 倍) ...

  6. 38、FragmentStatePagerAdapter分页

    [ ViewPager ] ViewPager 如其名所述,是负责翻页的一个 View.准确说是一个 ViewGroup,包含多个 View 页,在手指横向滑动屏幕时,其负责对 View 进行切换.为 ...

  7. IOS 类别

    在编写面向对象的程序时,你经常希望向现有的类添加一些新的行为:你总是能够为对象提供使用这些新方法的新手段.当希望为现有的类增加新行为时,我们通常会创建子类,但是有时候子类并不方便.例如,你可能会希望为 ...

  8. Linux(CentOs)下安装Phantomjs + Casperjs

    Linux(CentOs)下安装Phantomjs + Casperjs 是参照cnMiss's Blog http://ju.outofmemory.cn/entry/70691的博客进行安装的 1 ...

  9. C++ static内容小结

    C++中static总结比较好的博客:http://blog.csdn.net/laixingjun/article/details/9139839 http://blog.csdn.net/xiaj ...

  10. 通过库函数API和C代码中嵌入汇编代码剖析系统调用的工作机制

    作者:吴乐 山东师范大学<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 本次实验的主要内容就是分别采用A ...