黄瓜特点:概述

已发表: 2022-04-20

介绍

Gherkin 是一种仍在许多测试自动化框架中使用的语言。 有时是因为客户要求我们使用它,有时是因为团队决定这样做。

老实说,这对我来说并不是一见钟情。 我个人与 Gherkin 有一段相当长的旅程——从一开始喜欢它,到一段时间厌恶这种语言,然后又重新喜欢它。 在本文中,我将介绍最重要的 Cucumber 特性以及 Java 实现。

以下是本文介绍的所有 Cucumber 功能:

特征描述
设想简单场景
情景大纲要求用户在“示例”部分提供测试数据
数据表要求用户提供测试步骤的测试数据
场景上下文在测试步骤之间共享值
黄瓜数据类型黄瓜处理的数据类型
黄瓜正则表达式黄瓜场景中正则表达式的使用
黄瓜钩在测试场景中执行附加代码
表 1. 本文介绍的 Cucumber 和 java 特性

特征文件

首先,什么是特征文件? 在技​​术领域,创建了一种非技术方法,以允许非技术人员在开发应用程序期间与团队合作。 Gherkin 语言是作为 BDD 方法中的附加层创建的。 Gherkin 测试位于与代码(Java、Kotlin、C# 等)粘合的所谓功能文件中。 通常 Gherkin 非常易于使用,并且需要最少的编程知识,但有些功能需要一些编码。

让我们从简单的事情开始。

设想

这是 Cucumber 测试中最基本和最容易使用的示例:

 特点:情景

 背景:测试场景之前
   鉴于我在步骤之前执行

 @测试
 场景:场景 
   鉴于我使用“场景 1”的参数化步骤

代码块 1. 场景

代码块 1. 包含一些需要解释的内容:

  • Feature :特征文件的标题
  • 背景:允许用户在功能文件中定义的每个测试场景之前执行测试步骤的关键字
  • @Test :告诉测试框架应该执行什么测试场景的标签。 “测试”由用户定义。 我们可以使用例如“@SmokeTest”
  • 场景:测试场景名称

Gherkin 测试在每个测试步骤之前使用 [Given, When, Then, But] 关键字。 在我们唯一的测试步骤中,除了背景步骤,我们使用了一个参数,我们在其中传递了值“场景 1”。

现在,让我们看看粘合的 Java 代码是什么样的:

 @Given("我在步骤之前执行")
公共无效 iExecuteBeforeStep() {
   //一些实现
}

@Given("我使用 {string} 的参数化步骤")
公共无效 iUseParametrizedStepOf(字符串 p){
   //一些实现
}

代码块2.场景的Java代码实现

情景大纲

让我们做一些更复杂的事情:

 特征:场景大纲

 @测试
 场景大纲:场景大纲
   鉴于我使用“<parameter1>”和“<parameter2>”运行该步骤
 例子:
     | 参数1 | 参数2 |
     | 参数1a | 参数2a |
     | 参数1b | 参数2b |

代码块 3. 场景大纲

这次我们将使用场景大纲,它允许我们使用不同的测试数据配置重复测试场景。 代码块 3. 包含一些需要解释的内容:

  • 示例:测试场景要使用的测试数据矩阵。 第一行是带有参数名称的标题。

和java实现:

 @Given("我用 {string} 和 {string} 运行这一步")
公共无效 iRunStepWithAnd(字符串 p1,字符串 p2){
   //一些实现
}

代码块 4. 场景大纲的 Java 实现

数据表

场景大纲非常有用,但是如果我们不想重复整个测试场景而只想重复一个测试步骤怎么办? Gherkin 有一种方法可以做到这一点,它被称为“数据表”。

 特征:数据表

@测试
场景:数据表场景
 鉴于我验证该列包含预期值
 | 列名 | 预期值 |
 | 一些列名 | 一些期望值 |

代码块 5. 数据表

带有数据表的场景与场景大纲没有太大区别。 唯一的问题是我们没有在表格之前放置“示例”关键字。

Java 实现看起来比以前的情况要复杂一些:

 @Given("我验证该列是否包含预期值")
公共无效 iVerifyColumnValuesInTableUsingQueryFromFileOnSchema(DataTable dataTable) {
   List<Map<String, String>> data = dataTable.asMaps();
   for (Map<String, String> 形式:数据) {
       String columnName = form.get("columnName");
       String expectedResult = form.get("expectedValue");
       //一些实现
       }
   }
}

代码块 6. 数据表的 Java 实现

为了访问数据表中的数据,我们创建了一个“DataTable”类型的特殊变量 dataTable。 所有数据都将存储在 List 变量中。

场景上下文

使用场景上下文,我们可以在步骤之间共享数据。 假设我们有一个两步场景,我们希望将值“数据”从第 1 步传递到第 2 步(代码块 7)。

 @测试
场景:场景上下文
 鉴于我设置场景上下文值“数据”
 鉴于我使用场景上下文值

代码块 7. 场景上下文

首先,我们需要构建一个名为 ScenarioContext 的特殊类,该类具有设置和获取数据的场景上下文功能(代码块 8)。 我们的场景上下文是一个带有键值对的 HashMap。 我们将通过它的键来识别值。

  • scenarioContext() : 键值对的HashMap
  • setContext() : 存储场景上下文数据的键值方法
  • getContext() : 获取数据提供键的方法
 公共类 ScenarioContext {

   私有 Map<String, Object> 场景上下文;

   公共场景上下文(){
       场景上下文 = 新的 HashMap<>();
   }

   public void setContext(上下文键,对象值){
       场景上下文.put(key.toString(), value);
   }

   公共对象getContext(上下文键){
       返回scenarioContext.get(key.toString());
   }

}

公共枚举上下文{
   ID;
}

代码块 8. Scenario Context 类的 Java 实现

有了这个,我们可以使用已实现的方法。 然后在第 1 步中,我们在场景上下文中设置该值,在第 2 步中我们获得该值(代码块 9)。

 ScenarioContext 场景上下文 = new ScenarioContext();

@Given("我设置了场景上下文值 {string}")
公共无效iSetScenarioContextValue(字符串值){
   场景上下文.setContext(上下文.ID,值);
}

@Given("我使用场景上下文值")
公共无效 iUseScenarioContextValue() {
   String sharedValue = scenarioContext.getContext(Context.ID).toString();
}

代码块 9. 场景上下文步骤

黄瓜数据类型

Cucumber 处理有限数量的数据类型。 我们可以定义字符串、整数和浮点值,但对于布尔值,我们需要编写一些变通方法。

 @测试
场景:有变量的场景
 鉴于我使用字符串“string”、int 1、float 1.1 和布尔值“false”

代码块 10. Cucumber 数据类型

Java 代码看起来像这样:

 @Given("我使用字符串 {string}、int {int}、float {float} 和 boolean {string}")
公共无效 iUseStringIntFloatAndBoolean(字符串 var1,int var2,双 var3,字符串 var4){
   布尔 f = Boolean.valueOf(var4);
   //一些代码
}

代码块 11. Cucumber 数据类型的 Java 实现

黄瓜正则表达式

这是另一个经常使用的功能。 代码块 12 显示了一个两步场景,其区别仅在于使用不同的变量值(var1 和 var2)。 这实际上只是一步,在 Java 代码(代码块 13)中,我们只定义了一种方法,但使用正则表达式和一个参数 var。

 @测试
场景:正则表达式场景
 鉴于我使用变量 var1
 鉴于我使用变量 var2

代码块 12. Cucumber 中的正则表达式

 @Given("^我使用变量 (.*)")
公共无效examTimeTableInSummerSeason(字符串变量){
   如果(var.equals(“var1”)){
       //一些代码
   }
   否则如果(var.equals(“var2”)){
       //一些代码
   }
}

代码块 13. Cucumber 正则表达式的 Java 实现

黄瓜钩

最后但同样重要的是:黄瓜钩。

代码块 14 展示了 4 个最重要的钩子:

  • @Before :在每个测试场景之前执行代码
  • @After :在每个测试场景之后执行代码
  • @BeforeStep :在每个测试步骤之前执行代码
  • @AfterStep :在每个测试步骤之后执行代码
 @前
public void beforeScenario() {
   //一些代码
}

@后
公共无效 afterScenario() {
   //一些代码
}

@BeforeStep
public void beforeStep() {
   //一些代码
}

@AfterStep
公共无效 afterStep() {
   //一些代码
}

代码块 14. 黄瓜钩

概括

我希望我说服了你在测试中使用 Gherkin。 这几个功能将使您的测试更具可读性,并且非技术人员更容易理解。 此外,对于新加入者来说,更容易理解业务逻辑并减少他们的入职时间。