[转帖]自动化测试之cucumber(一)

自动化测试之cucumber(一)

https://www.jianshu.com/p/3857f2c3a8d4

 

简介

cucumber是BDD(Behavior-driven development,行为驱动开发)的一个自动化测试的副产品。它使用自然语言来描述测试,使得非程序员可以理解他们。Gherkin是这种自然语言测试的简单语法,而Cucumber是可以执行它们的工具。关于BDD有兴趣自行了解。附cucumber官网链接,里面也有关于BDD的信息。
cucumber本质上是使用根据正则表达式匹配自然语言,然后依次执行对应的方法,以达到测试的目的。

本文基本上只是官网的搬运工,摘要了部分信息,最好还是看官网文档。

Gherkin

Gherkin是自然语言测试的简单语法。
一个完整的测试是由多个step组成的,step即最小单元,如何复用step是非常关键的问题。多个step组成一个Scenario,即一个完整的测试case。多个Scenario组成一个Feature,即一组相关的测试case。

关键字

  • Feature
  • Example(or Scenario)
  • Given,When,Then,And,But(steps)
  • Background
  • Scenario Outline (or Scenario Template)
  • Examples (or Scenarios)

一个简单的例子

Feature: Is it friday yet?
  this is a descriptions
  Everybody want to know when it's Friday

  Scenario: Sunday isn't Friday
    Given today is Sunday
    When I ask whether it's Friday yet
    Then I should be told "Nope"

  Scenario: Friday is Friday
    Given today is Friday
    When I ask whether it's Friday yet
    Then I should be told "TGIF"

Feature

Feature是所有测试的开头。后面跟一段描述性的文字,表明这个测试文件是干什么的。

description

description是一段扩展性的文字描述,可以跟在Feature、Example、Background、Scenario、Scenario Outline下面。

Example和Scenario

Example和Scenario是一对同义词,是一个具体的测试case,包含了多个step。一般情况下,都是由Given(给定一个初始条件),When(发生了什么),Then(结果是什么)组成的。

Steps

step是cucubmer的最小单元,每个step是由Given, When, Then, And, 或者But开头的。如果关键词后面的内容是完全一样的话,那么cucumber会认为这两句话是重复的,哪怕前面的关键词不一样,如

Given there is money in my account
Then there is money in my account

这种限制也促使我们使用更加准确的语言去描述

Given my account has a balance of £430
Then my account should have a balance of £430

Given

Given一般用于在Scenario中描述系统的初始状态。它的目的是使系统在使用前处于一个已只的状态,要避免在Given中谈论交互上的事情。

When

When描述一个事件或者动作。他可以是与系统间的交互,也可以是由另一个系统触发的事件。cucumber强烈推荐每个Scenario只有一个When,当你觉得需要加更多的When的时候,通常就是需要拆分成多个Scenario的信号。

Then

Then描述期望的输出或者结果。对Then的step definition应该使用断言去比较期望值和实际值,就和单元测试差不多。

But和And

当有几个Given,When,Then的时候,可以写成

Example: Multiple Givens
  Given one thing
  Given another thing
  Given yet another thing
  When I open my eyes
  Then I should see something
  Then I shouldn't see something else

也可以用And和But增加其可读性

Example: Multiple Givens
  Given one thing
  And another thing
  And yet another thing
  When I open my eyes
  Then I should see something
  But I shouldn't see something else

step definition里个人并不建议使用@And和@But,只使用@Given,@When,@Then,这样语言更加明确,因为And和But都可以在Given,When,Then的下面使用。

Background

当在同一个Feature里有多个Scenario有相同Given的时候,可以使用Background将这些Given抽到一起。这样这个Feature的每个Scenario在运行的时候,都会先运行一次Background。每个Feature里只能有一个Background。

tips
  • 不要设置复杂的状态,除非该状态实际上是客户需要知道的
  • 保持background简短,因为在阅读Scenario的时候,是需要记住background的。最好不要超过4行
  • 一个feature只能有一个background,如果需要不同的background针对不同的方案,就需要分拆成不同的feature

Scenario Outline

Scenario Outline即Scenario的模板,也可写作Scenario Template。它可运行相同的Scenario多次。

Scenario: eat 5 out of 12
  Given there are 12 cucumbers
  When I eat 5 cucumbers
  Then I should have 7 cucumbers

Scenario: eat 5 out of 20
  Given there are 20 cucumbers
  When I eat 5 cucumbers
  Then I should have 15 cucumbers

可用Scenario Outline简化

Scenario Outline: eating
  Given there are <start> cucumbers
  When I eat <eat> cucumbers
  Then I should have <left> cucumbers

  Examples:
    | start | eat | left |
    |    12 |   5 |    7 |
    |    20 |   5 |   15 |

DataTable

Gherkin可以传递List,Map,称为DataTable,具体例子查看该github上的文档

方言

Gherkin支持多种方言,对应关键字转换查看该文档

状态共享

不同step里定义的变量,可以通过java类的成员变量达到共享上下文变量的目的。如上例子的today和actualAnswer。
而状态泄露会使得scenarios变得脆弱和难以维护。详细信息查看该文档

注释

Gherkin使用#作为注释符号

step definition

step definition是指通过正则表达式对应到一个或多个Gherkin step的java方法。如下例子是上面例子对应的step definition

public class FridayYet {

    private String today;
    private String actualAnswer;


    @Given("^today is (.*)$")
    public void todayIsSunday(String day) {
        this.today = day;
    }

    @When("^I ask whether it's Friday yet$")
    public void iAskWhetherItsFridayYet() {
        if (this.today.equals("Friday")) {
            this.actualAnswer = "TGIF";
        } else {
            this.actualAnswer = "Nope";
        }
    }

    @Then("^I should be told \"(.*)\"$")
    public void iShouldBeToldNope(String expectedAnswer) {
        Assert.assertEquals(expectedAnswer, actualAnswer);
    }
}

替代文本

使用/作为替代文本。如下例子可匹配I have {int} cucumber(s) in my belly和I have {int} cucumber(s) in my stomach

I have {int} cucumber(s) in my belly/stomach

3.0.1版本前,无法转义/,始终被解释为替代文本,3.0.1后用\/转义/
附github版本变更记录

tag

tag提供2个作用

  1. 提供@before和@after的钩子(tagged-hooks)
  2. 运行时只运行指定tag的用例
    tag具有继承特性,即在Feature上标记tag,该Feature下的Scenario,step会继承该tag。
@simpleDemo
Feature: Is it friday yet?
@RunWith(Cucumber.class)
@CucumberOptions(tags = "@simpleDemo")// 指定只运行代用@simpleDemo的
public class CucumberTest {
}
@Before("@simpleDemo")
public void beforeOperation() {
        
}

@After("@simpleDemo")
public void afterOperation() {

}

测试过写两个tag,两个都会生效
结合Background具体的运行顺序是 before tag -> Background -> Scenario -> after tag

  1. 以上2点是官网提出的,个人认为还有第三点作用:生成report的时候提供分类作用

update at 2019年03月25日
tips: cucumber.api.spring.SpringTransactionHooks(cucmber-spring包)提供了一个spring事务的钩子@txn,提供回滚功能。

IDE插件

IDEA Cucumber for Java

report

具体没看,有兴趣可以自行了解
自动化测试之cucumber(四)

上一篇:Inference Stage Optimization for Cross-scenario 3D Human Pose Estimation


下一篇:数据结构——树状数组