行为驱动测试方法已经在敏捷软件开发模式中普遍使用,通过使用标准化语言将客户需求人员,开发人员和测试人员关联在一起,让产品开发相关人员在沟通上保持一致。行为驱动开发是一种敏捷软件开发技术,它的英文全称是Behavior Driven Development,英文缩写BDD.它包括验收软件项目中的开发者,QA,非技术人员或商业参与者之间进行协作。在过去数年里,BDD开发模式得到了很大的发展,BDD的流行已然无法逆转。
lettuce 是实现BDD开发模式的一种测试框架,实现了使用自然语言来执行相关联测试的代码的需求。letttuce是基于Cucumber的一款非常易于使用的BDD工具,可以执行纯文本的功能描述。Lettuce使用Gherkina语言来描述测试功能,测试场景,测试步骤和测试结果,Gherkin语言支持超过40种语言,包括英文和中文,Gherkin语言使用的主要英文关键词有Scenario.Given,When,And,Then和But等,这些关键词也可以转换为中文关键词,例如“场景”“如果” “当”“那么”。根据用户story,需求人员或测试人员使用Gherkin语言编写好测试场景的每个执行步骤,Lettuce就会一步步地解析关键词右侧的自然语言并执行相应的代码。
关键词的含义如下:
1 Feature:特性,将多个测试用例集合到一起,对应于unittest中的test suite(测试用例集)。
2 Scenario:情景,用于描述一个用例,对应于unittest中的test case
3 Given:如果,用例开始执行前的一个前置条件,类似于unittest中setuo方法中的一些步骤。
4 When:当,用例开始执行时的一些关键操作步骤,类似于unittest中的以test开头的方法,比如执行一个单机元素的操作。
5 Then: 那么,验证结果,就是平时用例中的验证步骤,比如assert方法
6 And: 和,一个步骤中如果存在多个Given操作,后面的Given可以用And替代。
7 But:一个步骤中如果存在多个Then操作,第二个开始后面的Then可以用BUT替代。
使用Gherkin语言编写测试场景的执行步骤,并将执行步骤保存在扩展名为feature的文件中,每个.feature文件都要开始于Feature(功能)关键词,Feature之后的描述可以自定义,直到出现Scenario关键词。一个.feature文件中可以有多个Scenario.每个Scenario包含步骤(step)列表,不同步骤使用Given,when,Then,But,And这些关键词进行区分。
BDD开发模式的好处在于,可以将用户故事(scrum)或者需求和测试用例建立起一一对应的映射关系,保证开发和测试的目标与范围严格的和需求保持一致,可以更好的让需求方,开发者以及测试人员用唯一的需求进行相关的开发工作,防止对需求理解的不一致,并且BDD框架的测试结果很容易被参与者理解。
参考代码结构:
|lettuce
|MyBDD
|features
- zero.feature
- setps.py
##zero.feature
Feature: Compute sum
In order to play with Lettuce
As beginners
We'll implement sum
Scenario: sum of 1,2
Given I have the number 1,2
When I compute its sum
Then I see the number 3
Scenario: sum of 1,4
Given I have the number 1,4
When I compute its sum
Then I see the number 5
##setps.py
def sum(a,b):
return a+b
@step('I have the numbers (\d+),(\d+)')
def have_the_number(step, number1,number2):
# 将通过正则表达式匹配的数字存于全局变量world中
world.number1 = int(number1)
world.number2 = int(number2)
@step('I compute its sum')
def compute_its_sum(step):
# 从全局变量world中取出匹配的数字,
# 计算其阶乘,并将结果再存回world中
world.sum = sum(world.number1,world.number2)
@step('I see the number (\d+)')
def check_number(step, expected):
# 通过正则匹配到预期数字
expected = int(expected)
expected = int
(expected)
# 断言计算阶乘结果是否等于预期
assert world.sum == expected, "Got %d"