Every time I wrote some code in ruby and executed our cucumber features I craved for something similar in Java. I knew that there were several BDD frameworks for Java like JBehaveJDave, and EasyB, but none of them was right for me: either it used another language - like groovy -, had some unnecessary dependencies, or was hard to integrate with eclipse. A couple of weeks ago, I was looking for something in the source code of cucumber and found out that Aslak Hellesøy - author of cucumber - is working on a pure Java based implementation. It hasn’t been released yet, but I decided to give it a try and see what it can do.

The Basics

If you are not familiar with the BDD concept I recommend to read Dan North’s article before continuing. BDD means Behavior Driven Development, and in a nutshell, it means that you specify on a higher level, in a readable form, how the system is supposed to work. Programmers tend to call BDD the big brother of TDD, because TDD works on a class level, and BDD on the system level, but this isn’t 100 percent true: for me TDD defines what an entity - system or class - should exactly do, and BDD defines how it should work. There is a tiny difference, but it is recognizable.

Let’s see a very simple example:

Feature: simple text munger kata
Scenario: Do nothing with a two-letter word
Given I have an instance of my class
When I call my method with "an"
Then I receive "

The snippet above is self-explanatory: what my feature is supposed to do is described in Gherkinlanguage.

The Test Classes

When I try out a new framework, I use a Kata exercise. This time, I’ll try to implement a simple version of the famous text munger kata. Given an input sentence, modify it in the following way: in each word keep the first and the last letter, but the rest shall be returned in reverse order - in the original kata the rest should be randomized. For example:

In:   And the spice must flow
Out: And the scipe msut folw

As you can see, it will be simple, because my goal is to learn how to use cucumber under Java - I’ll refer to it as cucumber-jvm -, not to finish the kata exercise properly. Enough talking, let’s take out our eclipse and start working.

The first thing is to save the feature above into a .feature file where cucumber can find it. I’ll use the standard directory layout and create a simple_text_munger.feature file with the content above in src/test/resources:

Every feature should have its own .feature file. A feature may have multiple scenarios, and every scenario may have multiple steps. A step can be used in different scenarios and even across different features. This is not cucumber-jvm specific, this is how cucumber organizes its files.

Having a single .feature file has no use. Somehow the system should interpret this file and execute the referenced steps:

SimpleTextMunger_Test.java

package com.zsoltfabok.blog;

import cucumber.junit.Cucumber;
import cucumber.junit.Feature;
import org.junit.runner.RunWith; @RunWith(Cucumber.class)
@Cucumber.Options(features = "classpath:simple_text_munger.feature")
public class SimpleTextMunger_Test {
}

Java is not a dynamic language like ruby and it cannot “execute” a plain .feature file: it requires a wrapper file which loads the feature and executes it. Based on the examples ofcucumber-jvm, let’s name this file after the .feature and use the _Test suffix. The underscore differentiates the file from a regular Test file (update: after writing a couple of more features, I felt more comfortable with the Feature suffix, but for this example I kept the _Test in order keep the consistency between the posts and the source code). There is no need to put anything into the body of the wrapper class.

In cucumber, every ”sentence” is considered as a step which needs to be implemented. For example:

SimpleTextMungerStepsdef.java

import cucumber.annotation.en.Given;
import cucumber.annotation.en.Then;
import cucumber.annotation.en.When; public class SimpleTextMungerStepsdef {
@Given("^I have an instance of my class$")
public void I_have_an_instance_of_my_class() {
// Express the Regexp above with the code you wish you had
} @Then("^I receive \"([^\"]*)\"$")
public void I_receive_(String arg1) {
// Express the Regexp above with the code you wish you had
} @When("^I call my method with \"([^\"]*)\"$")
public void I_call_my_method_with_(String arg1) {
// Express the Regexp above with the code you wish you had
}
}

Exactly like in cucumber, cucumber-jvm maps each ”sentence” to a step. When I run my .feature, it will call the proper step method. If a step definition cannot be found, cucumber-jvmwill generate it for you and write it to the console. Mind the Stepdef suffix in the name of the class. It is not mandatory - everything works without it, because cucumber-jvm finds the definitions using reflection -, but it looks like a reasonable convention.

Compiling

The test classes are in place, let’s run the test cases. We’ll need the jar files of cucumber-jvm. They can be installed with maven, but since I’m not a huge fan of maven, and I need something easy to use for this example, I’m going with ivy. You can download and set the dependencies using the command line or the ivyDE eclipse plugin:

blog.cucumberjvm % ivy
...
confs: [compile, test]
found junit#junit;4.10 in public
found org.hamcrest#hamcrest-core;1.1 in public
found info.cukes#cucumber-java;1.0.14 in public
found info.cukes#cucumber-core;1.0.14 in public
found info.cukes#cucumber-jvm-deps;1.0.3 in public
found info.cukes#gherkin;2.11.2 in public
found info.cukes#gherkin-jvm-deps;1.0.2 in public
found info.cukes#cucumber-junit;1.0.14 in public
:: resolution report :: resolve 519ms :: artifacts dl 26ms
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| compile | 8 | 0 | 0 | 0 || 14 | 0 |
| test | 8 | 0 | 0 | 0 || 14 | 0 |
---------------------------------------------------------------------
blog.cucumberjvm %

Run the First Test

No compilation errors, let’s run the SimpleTextMunger_Test as a JUnit test. It looks good to me:

In the next post I’m going to continue with more scenarios and see how the cucumber-jvmhandles tables in a .feature file. Until then, you can find the source for this post under the episode_1 branch of the repository on github. Stay tuned!

Cucumber(一): Preparation的更多相关文章

  1. Windows建立Cucumber和Ruby测试环境

    1. 下载安装Ruby1.9.3, 不要用RubyInstall 一键安装,下载zip然后解压到c:\Ruby193 (不要用2.0,用2.0安装不成功,不要怪我) 2. 环境变量配置RUBY_HOM ...

  2. Cucumber测试驱动开发

     Cucumber是一种BDD实践开发工具,属于敏捷开发的组成部分.      在敏捷开发中,对用户进行需求分析时,不是像传统的P&D的开发方式,首先编写大量的用户需求分析文档,而是通过一个个 ...

  3. Ruby Cucumber环境

    1.http://rubyinstaller.org/downloads 下载rubyinstaller以及developmentkit(注意版本号要对应) 2.安装rubyinstaller以及解压 ...

  4. Cucumber语法及测试用例<一>

    工作原因,最近一直在研究cucumber的 语法以及它和java之间的关系.鉴于是初学者且代码基础薄弱,我开始摸索前行,感谢分享博客且也在一路前行的人儿们. 1.基本语法为:此处举例两种区别一看即知- ...

  5. cucumber:环境安装

    1.安装RubyInstallerhttp://rubyinstaller.org/downloads/注意:安装目录结构不要太深安装完成后在命令行运行: ruby –v 可以查看是否安装成功2.安装 ...

  6. Cucumber命令行接口

    1. cucumber的命令行选项 首先查看命令行选项.和其它命令行工具一样,cucumber提供了—help选项.下面是cucumber帮助的一个缩减版本: $ cucumber --help -r ...

  7. Cucumber

    http://www.ibm.com/developerworks/library/a-automating-ria/ Cucumber is a testing framework that hel ...

  8. cucumber learning : http://www.cnblogs.com/puresoul/category/340832.html

    link Generate cucumber report by json website Sample as json file for cucumber report: [ { "key ...

  9. Cucumber 入门一

    (转自:http://www.cnblogs.com/jarodzz/archive/2012/07/02/2573014.html) 第一次看到Cucumber和BDD(Behavior Drive ...

随机推荐

  1. [转]MySQL索引背后的数据结构及算法原理

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  2. python中不同包之间调用方法、

    在pycharm中... 当两个py文件在同一个文件夹下的时候.直接from 文件名 import *  即可 当两个文件在不同的文件夹下的时候.需要在文件中加入 _init_.py 文件.里面可以什 ...

  3. 自动布局报错(两条连线冲突):Unable to simultaneously satisfy constraints

    这个报错有些长: Unable to simultaneously satisfy constraints.    Probably at least one of the constraints i ...

  4. ng-repeat 里 使用ng-show ng-hide出现闪动

    在项目中使用ng-repeat在表格中循环输出一组数据的时候,需要对表格中的每一列(每一列为数组的一个元素--对象)添加控制按钮. 列表样式 我的期望是 初始化 ----每一行不可编辑,保存按钮是隐藏 ...

  5. 【krpano】加密XML手动解密分析

    krpano允许对XML文件进行加密,对XML进行相应的保护.加密分为两种,第一种为公共加密,即允许其他krpano全景读取该XML,而另一种为私有加密,仅允许加密的用户读取XML.两种加密方式的算法 ...

  6. HTML页面如何判断是手机访问还是电脑访问

    可以通过js来判断访问设备,代码如下: <script type="text/javascript"> var system ={}; var p = navigato ...

  7. Mongodb 基础(Z)

    Mongodb的客户端支持 作为一款非常成熟NoSQL数据库,Mongdb对各种编程语言的支持已经非常完善了,目前已经支持各大主流编程语言包括:1,mongo shell 2,Python 3,Jav ...

  8. CentOS7中安装MySQL(简便)及 网站的搭建

    一.首先,我们需要配置CentOS7中网络环境的搭建,物理机IP为192.168.100.39,虚拟机IP为192.168.100.139,网络模式设置为桥接模式 ,再进入系统挂载光盘.输入命令   ...

  9. 编译器警告:CGContextSaveGState: invalid context 0x0

    一.问题描述 下载图片,然后用Quartz2D绘制缩放的图片,运行无法显示图片并且编译器警告: Aug 18 21:41:50  02_计算UITableViewCell的行高[16777] < ...

  10. 使用JSOM检查文件或文件夹是否存在

    How to Check with SharePoint JSOM if File or Folder Exists Here's a code snippet showing how to use ...