Cucumber---行为驱动开发的利器(一)
Cucumber 是一个BDD的测试框架,它从业务角度出发,使用业务相关的语言(非技术语言),描述系统具有的行为。它更关注的是业务层面而非代码层面的逻辑。
在这篇文章里,我将首先介绍BDD, 然后介绍Cucumber以及相关概念。
一 BDD
Enough is enough:
Up-front planning, analysis, and design all have a diminishing return. We shouldn’t do less than we need to get started, but any more than that is wasted effort. This also applies to process automation. Have an automated build and deployment, but avoid trying to automate everything.
Cucumber 是一个基于BDD的测试框架,它能够帮助团队使用业务上的语言对软件系统的行为进行测试。同单元测试相比,Cucumber的测试更多关注的是业务级别的行为,因此非开发人员、业务专家或者客户能够容易的参与,从而保证软件系统的行为切实符合业务需求。同时,通过Cucumber的测试,开发人员也能更正确、清晰的理解业务需求,保证开发出来的系统满足客户的期望。由于Cucumber采用几乎近于自然语言的方式描述了软件的行为过程,因此可以直接作为软件的需求文档,也可以直接作为测试或者系统验收的标准文档。 这种方式也淋漓尽致的体现了敏捷的思想:代码即是最有效的文档。
三 Cucumber的概念
Cucumber中有几个重要的概念:
1. Feature
Feature指的是软件系统所提供的某个功能,一般对应 User Story。在一个Cucumber 的feature文件中,主要定义了用户如何使用软件提供的该功能。通常我们这样定义feature:
在feature的定义中,通常会涉及如下几个问题:
a) Who is using the system?
b) What are they doing?
c) Why do they care?
比如说:
通常一个feature文件中会包括一个或者多个Scenario。
2. Scenario
Scenario描述了用户使用软件的场景,即在某种前提条件下,当用户使用软件触发某个行为,那么应该会得到一个预期的结果。 比如说:
即当使用计算器求和时,假如给定了2+2的前提条件,那么当点击计算时,期望的结果应该是4.
通常Scenario由一组步骤(step)组成。
3. Step
Step 描述了在完成一次同软件交互的过程中,所需要的每个动作。
通常有三种step:
1) 给定的条件(Given)
2)触发的行为(When)
3)期待的结果(Then)
比如上个例子中定义当完成一次计算两数相加的行为时,需要3个步骤
4. Step definition(implementations)
Step是使用业务层面的描述语言完成的,比如刚才提到的测试计算器的例子。 针对这种业务层面的描述语言,必然有对应的技术层面的实现,才能将这些业务描述语言转变成对系统进行测试的代码。 我们称这种对业务语言的技术实现为step definition. 比如对上个例子的step,我们使用的实现伪代码如下所示 :
四 总结
本文介绍了BDD、Cucumber的背景, 以及Cucumber中涉及的概念(Feature, Scenario, Step, Step definition),后续将介绍如何使用Cucumber来帮助我们测试软件系统的行为。
在这篇文章里,我将首先介绍BDD, 然后介绍Cucumber以及相关概念。
一 BDD
Behavior-Driven Development is about implementing an application by describing its behavior from the perspective of its stakeholders.
这里需要注意两点:
1)stakeholders:软件的使用者,受益者,通俗的说就是软件的客户。
2)behavior:这里的behavior,指的是从stakeholders的角度看到的软件系统的行为。
BDD的作用:
其实BDD和agile是紧密相关的。在agile中,我们使用BDD测试作为acceptance test。也就是说,当分析出一个user story后,我们应该有一个BDD的case与之对应,作为衡量软件是否满足该需求的一个标准。其实,从某种程度上讲,BDD就是TDD的发展,BDD出现的背景,就是开发人员在TDD时,不清楚到底该将一个什么样的story作为自己TDD开发需要实现的目标。
而BDD简单的回答了这个问题:让stakeholders用一个test case告诉你,你的具体目标是什么。同时强调了,每一个开发目标都应该是系统的behavior的体现。
BDD的三原则:
We sum this up using the following three principles of BDD:
Enough is enough:
Up-front planning, analysis, and design all have a diminishing return. We shouldn’t do less than we need to get started, but any more than that is wasted effort. This also applies to process automation. Have an automated build and deployment, but avoid trying to automate everything.
这一点秉承的原则:不做多余的事。
Deliver stakeholder value:
If you are doing something that isn’t either delivering value or increasing your ability to deliver value, stop doing it, and do something else instead.
If you are doing something that isn’t either delivering value or increasing your ability to deliver value, stop doing it, and do something else instead.
这一点秉承的原则:做对客户有价值的事。
It’s all behavior:
It’s all behavior:
Whether at the code level, the application level, or beyond, we can use the same thinking and the same linguistic constructs to describe behavior at any level of granularity.
这一点秉承的原则:实现的都是有价值的行为。
二 Cucumber
Cucumber 是一个基于BDD的测试框架,它能够帮助团队使用业务上的语言对软件系统的行为进行测试。同单元测试相比,Cucumber的测试更多关注的是业务级别的行为,因此非开发人员、业务专家或者客户能够容易的参与,从而保证软件系统的行为切实符合业务需求。同时,通过Cucumber的测试,开发人员也能更正确、清晰的理解业务需求,保证开发出来的系统满足客户的期望。由于Cucumber采用几乎近于自然语言的方式描述了软件的行为过程,因此可以直接作为软件的需求文档,也可以直接作为测试或者系统验收的标准文档。 这种方式也淋漓尽致的体现了敏捷的思想:代码即是最有效的文档。
三 Cucumber的概念
Cucumber中有几个重要的概念:
1. Feature
Feature指的是软件系统所提供的某个功能,一般对应 User Story。在一个Cucumber 的feature文件中,主要定义了用户如何使用软件提供的该功能。通常我们这样定义feature:
Feature: <description>
As a <role>
I want <feature>
So that <business value>
即作为某个角色,我想使用系统做些事情,从而得到期望的实现业务价值的结果。
As a <role>
I want <feature>
So that <business value>
在feature的定义中,通常会涉及如下几个问题:
a) Who is using the system?
b) What are they doing?
c) Why do they care?
比如说:
Feature: Adding the numbers by calculator
As a customer,
I want to calculate the two numbers,
so that I can get the right results.
As a customer,
I want to calculate the two numbers,
so that I can get the right results.
通常一个feature文件中会包括一个或者多个Scenario。
2. Scenario
Scenario描述了用户使用软件的场景,即在某种前提条件下,当用户使用软件触发某个行为,那么应该会得到一个预期的结果。 比如说:
Scenario: Add two numbers
Given the input "2+2"
When the calculator is run
Then the output should be "4"
Given the input "2+2"
When the calculator is run
Then the output should be "4"
即当使用计算器求和时,假如给定了2+2的前提条件,那么当点击计算时,期望的结果应该是4.
通常Scenario由一组步骤(step)组成。
3. Step
Step 描述了在完成一次同软件交互的过程中,所需要的每个动作。
通常有三种step:
1) 给定的条件(Given)
2)触发的行为(When)
3)期待的结果(Then)
比如上个例子中定义当完成一次计算两数相加的行为时,需要3个步骤
Given the input "2+2"
//
步骤1,确定前提条件,如我希望计算的数字是2+2;
When the calculator is run // 步骤2,运行计算器,并开始计算;
Then the output should be "4" // 步骤3, 验证期待的结果是4.
When the calculator is run // 步骤2,运行计算器,并开始计算;
Then the output should be "4" // 步骤3, 验证期待的结果是4.
4. Step definition(implementations)
Step是使用业务层面的描述语言完成的,比如刚才提到的测试计算器的例子。 针对这种业务层面的描述语言,必然有对应的技术层面的实现,才能将这些业务描述语言转变成对系统进行测试的代码。 我们称这种对业务语言的技术实现为step definition. 比如对上个例子的step,我们使用的实现伪代码如下所示 :
Given /^the input([^"]*)"$/
do |input_number|
// get the input expression by the regexp match
input = input_number
end
When /^the calculator is run$/ do
// run the calculator and trigger it to do calculation by input
result = calculator(input)
end
Then /^the output should be ([^"]*)"$/ do |expected_result|
// get the expected result by the regexp match
// verify whether the result is as we expected
result == expected_result
end
// get the input expression by the regexp match
input = input_number
end
When /^the calculator is run$/ do
// run the calculator and trigger it to do calculation by input
result = calculator(input)
end
Then /^the output should be ([^"]*)"$/ do |expected_result|
// get the expected result by the regexp match
// verify whether the result is as we expected
result == expected_result
end
四 总结
本文介绍了BDD、Cucumber的背景, 以及Cucumber中涉及的概念(Feature, Scenario, Step, Step definition),后续将介绍如何使用Cucumber来帮助我们测试软件系统的行为。