Cucumber-JVM 是一个支持 Behavior-Driven Development (BDD) 的 Java 框架。在 BDD 中,可以编写可读的描述来表达软件功能的行为,而这些描述也可以作为自动化测试。
Cucumber-JVM 的最小化环境
Cucumber-JVM是BDD的框架, 提供了GWT语法的相关库, 但是其本身没有提供断言库,需要借助其他的单元测试框架。
所以最小化环境需要导入Cucumber-JVM的库 + 单元测试框架(比如JUnit)。
1. 环境搭建
使用Maven 导入的方式如下:
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>7.15.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
2.测试规格和代码
基本环境导入之后, 就可以开始编写BDD的规格和步骤函数了, 以最简单的Hello World入门示例来看,
- 规格文件, 文件名是 hello_world.feature
内容如下:
Feature: Hello World
Scenario: Running a simple hello world function
Given the system is ready
When I ask it to say hello
Then it should answer with "Hello, World!"
- 步骤函数类文件 HelloWorldSteps.java
/**
* Description:
* Author: XM Chen
* Date: 2023-12-27
*/
package com.osxm.bdd.usage;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import static org.junit.Assert.*;
public class HelloWorldSteps {
private String actualAnswer;
@Given("the system is ready")
public void the_system_is_ready() {
// 在这里可以进行一些初始化操作
}
@When("I ask it to say hello")
public void i_ask_it_to_say_hello() {
actualAnswer = getHelloWorld();
}
@Then("it should answer with {string}")
public void it_should_answer_with(String expectedAnswer) {
assertEquals(expectedAnswer, actualAnswer);
}
private String getHelloWorld() {
// 这里是你的 Hello World 函数实现
return "Hello, World!";
}
}
项目的目录结构如下:
3. 测试的运行
可以使用命令行的方式运行BDD 测试,
java -cp "path/to/each/jar:path/to/compiled/.class/files" io.cucumber.core.cli.Main /path/to/your/feature/files --glue hellocucumber --glue anotherpackage
该命令的解释如下:
java
: 运行Java虚拟机的命令。-cp
: 设置classpath,用于指定要加载的类和包含依赖项的JAR文件的路径。"path/to/each/jar:path/to/compiled/.class/files"
: 指定JAR文件和编译后的.class文件的路径。多个路径用冒号分隔。io.cucumber.core.cli.Main
: 指定要运行的Cucumber主类。/path/to/your/feature/files
: 指定要运行的Cucumber特性文件的路径。--glue hellocucumber
: 指定要运行的Cucumber步骤定义文件的包名。在这个例子中,hellocucumber
是一个包含Cucumber步骤定义类的包。--glue anotherpackage
: 指定另一个包含Cucumber步骤定义类的包。在这个例子中,anotherpackage
是另一个包含Cucumber步骤定义类的包,可以在同一个测试中使用。
就本篇的例子来说, 要组成这个命令行,需要获取所有的需要的jar 档, 也就是 -cp 的选项的值, 获取的步骤如下:
- 使用maven 将所有jar 复制到target\test-classes目录下
方式是在pom.xml 加入以下配置:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>D:\devworkspace\vs\bdd-ency\target\test-classes\lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
- 接下来是获取lib 目录下的文件名,并且以分号分隔, 这个使用python 可以很容易实现,
python 的代码类似:
import os
# 获取Windows目录
windows_dir = os.environ['lib']
# 列出目录下的文件名
file_names = os.listdir(windows_dir)
# 以 ; 分割文件名
file_names_str = ';'.join(file_names)
print(file_names_str)
使用bat 命令也可以做到
dir lib /b /a-d > files.txt
汇总后的Java命令行是:
java -cp lib/apiguardian-api-1.1.2.jar;lib/ci-environment-10.0.0.jar;lib/cucumber-core-7.15.0.jar;lib/cucumber-expressions-17.0.1.jar;lib/cucumber-gherkin-7.15.0.jar;lib/cucumber-gherkin-messages-7.15.0.jar;lib/cucumber-java-7.15.0.jar;lib/cucumber-plugin-7.15.0.jar;lib/datatable-7.15.0.jar;lib/docstring-7.15.0.jar;lib/gherkin-26.2.0.jar;lib/hamcrest-core-1.3.jar;lib/html-formatter-20.4.0.jar;lib/junit-4.12.jar;lib/junit-xml-formatter-0.2.0.jar;lib/messages-22.0.0.jar;lib/tag-expressions-6.0.0.jar;./ io.cucumber.core.cli.Main features --glue com.osxm
执行的结果如下图:
在JUnit 4中导入 cucumber-junit 更便捷的运行测试
上面的命令行运行方式很麻烦, cucumber其实提供了很便捷的运行方式, 在使用JUnit 4的项目中, 可以导入cucumber-junit。
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>7.15.0</version>
<scope>test</scope>
</dependency>
导入之后, 新增一个RunCucumberTest.java 文件,内容如下:
/**
* Description:
* Author: XM Chen
* Date: 2023-12-27
*/
package com.osxm.bdd.usage;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;
@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources", plugin = {"pretty"})
public class RunCucumberTest {
// 不需要添加代码,这个类作为配置和测试运行的入口点
}
创建之后在IDE中就可以直接运行这个文件了, 比如在VS Code 中执行及结果如下: