基础用例
1. idea生成基础springboot项目,导入cumumber所需依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cucumber</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-core</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>4.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-testng</artifactId>
<version>4.3.1</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>com.cucumber.demo.DemoApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2. 文件结构
3. 编写feature文件(参数写在语句里)
Feature: Mernagria
Scenario: register new pet
Given I am on the "new pet" page
And I click the "register" button
Then I should go to the "register" page
4. 根据feature步骤定义类(如果idea识别feature文件可以点击黄色问号生成类中方法)
public class MyStepdefs {
@Given("^I am on the \"([^\"]*)\" page$")
public void iAmOnThePage(String arg0) throws Throwable {
// Write code here that turns the phrase above into concrete actions
System.out.println("I am on the " + arg0 + " page");
// throw new PendingException();
}
@And("^I click the \"([^\"]*)\" button$")
public void iClickTheButton(String arg0) throws Throwable {
// Write code here that turns the phrase above into concrete actions
System.out.println("I click the "+ arg0 +" button");
// throw new PendingException();
}
@Then("^I should go to the \"([^\"]*)\" page$")
public void iShouldGoToThePage(String arg0) throws Throwable {
// Write code here that turns the phrase above into concrete actions
System.out.println("I should go to the "+arg0+" page");
// throw new PendingException();
}
}
5. 运行文件
@RunWith(Cucumber.class)
//指定feature文件位置,和步骤类的位置(默认该类同一文件夹,所以此处没指定)和插件输出结果json文件位置
@CucumberOptions(features = "src/test/resources/facebook",plugin = {"pretty","html:target/cucumber","json:target/cucumber.json"})
public class Test {}
实现feature和java传参
6. 编写feature文件(参数写在examples里)
Feature: faceBook login
Scenario Outline: Login functionality for a social net working site.
Given user navigates to Facebook
When I enter Username as "<username>"
And Password as "<password>"
Then login should be unsuccessful
Then check status "<status>"
Then check msg "<msg>"
Examples:
|Scenario | username | password | msg | status |
|test1 | a | 123456 | success | 0000 |
|test2 | b | 123456 | success | 0000 |
|test3 | b | 123456 | | 0000 |
|test4 | b | 123456 | null | 0000 |
7. 根据feature步骤定义类
public class MyStepdefs {
@Given("^user navigates to Facebook$")
public void userNavigatesToFacebook() {
}
@When("^I enter Username as \"([^\"]*)\"$")
public void iEnterUsernameAs(String username) throws Throwable {
// Write code here that turns the phrase above into concrete actions
System.out.println(username);
}
@And("^Password as \"([^\"]*)\"$")
public void passwordAsPassword(String password) {
System.out.println(password);
}
@Then("^login should be unsuccessful$")
public void loginShouldBeUnsuccessful() {
}
@But("^check msg (.*)$")
public void checkMsg(String msg) {
Assert.assertEquals(msg,"0000");
System.out.println(msg);
}
@But("^check status \"([^\"]*)\"$")
public void checkStatus(String status) throws Throwable {
Assert.assertEquals(status,"0000");
// Write code here that turns the phrase above into concrete actions
System.out.println(status);
}
}
8. 运行文件
@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources/facebook",plugin = {"pretty","html:target/cucumber","json:target/cucumber.json"})
public class Test {}
实现运行前初始化资源,运行后清除资源功能
9. 添加初始化资源和关闭资源(只执行一次)
@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources/facebook",plugin = {"pretty","html:target/cucumber","json:target/cucumber.json"})
public class Test {
@BeforeClass
public static void init(){
System.out.println("init the dataSource");
}
@AfterClass
public static void close(){
System.out.println("clear the source");
}
}
10. 添加初始化资源和关闭资源(每次测试都执行一次只执行一次,必须新建文件放在run文件同一目录或者在运行文件注解上指定位置)
//junit的@Before和@After失效,要使用cumumber的@Before和@After
public class Hook {
@Before
public void init(){
System.out.println("init dataBase everyTime");
}
@After
public void clear(){
System.out.println("clear dataBase everyTime");
}
}
实现分支功能,可以在运行文件指定哪些分支会运行
11. 添加分支
Feature: faceBook login
Scenario Outline: Login functionality for a social net working site.
Given user navigates to Facebook
When I enter Username as "<username>"
And Password as "<password>"
Then login should be unsuccessful
Then check status "<status>"
Then check msg "<msg>"
@test1
Examples:
|Scenario | username | password | msg | status |
|test1 | a | 123456 | success | 0000 |
|test2 | b | 123456 | success | 0000 |
|test3 | b | 123456 | | 0000 |
|test4 | b | 123456 | null | 0000 |
@test2
Examples:
|Scenario | username | password | msg | status |
|test1 | ac | 123456 | success | 0000 |
|test2 | bc | 123456 | success | 0000 |
|test3 | bx | 123456 | | 0000 |
|test4 | bc | 123456 | null | 0000 |
@test3
Examples:
|Scenario | username | password | msg | status |
|test1 | acv | 123456 | success | 0000 |
|test2 | bcb | 123456 | success | 0000 |
|test3 | bvc | 123456 | | 0000 |
|test4 | bvn | 123456 | null | 0000 |
//CucumberOptions里指定运行分支
@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources/facebook",plugin = {"pretty","html:target/cucumber","json:target/cucumber.json"},monochrome = true,tags = {"@test1,@test3"})
public class Test {}
feature与java复杂类型传参
12. 传值(一个一个传)
参考官网链接
When I enter Username as "<username>"
Examples:
|Scenario | username | password | msg | status |
|test1 | ace | 123456 | success | 0000 |
@When("I enter Username as {string}")
13. 传值(二维数组, 一行行传)
Then login should be unsuccessful
|success | good | 0000 |
|fail | bad | 5555 |
@Then("^login should be unsuccessful$")
public void loginShouldBeUnsuccessful(List<List<String>> dataTable) {
System.out.println(dataTable);
//结果打印[[success, good, 0000], [fail, bad, 5555]]
}
14. 传值(二维数组, 一键一值, 键值对)
Then login should be unsuccessful
|success | msg | status |
|success | good | 0000 |
|fail | bad | 5555 |
@Then("^login should be unsuccessful$")
public void inShouldBeUnsuccessful(List<Map<String,String>> dataTable) {
System.out.println(dataTable);
//结果打印[{success=success, msg=good, status=0000}, {success=fail, msg=bad, status=5555}]
}
15. 传值(二维数组, 一键多值, 键值对)
Then login should be unsuccessful
|success | good | 0000 |
|fail | bad | 5555 |
@Then("^login should be unsuccessful$") public void inShouldBeUnsuccessful(Map<String,List<String>> dataTable) { System.out.println(dataTable); //结果打印{success=[good, 0000], fail=[bad, 5555]} }
16. 传一个对象(键值对)
Then login should be unsuccessful
|success | success |
|msg | good |
|state | 500 |
@Then("^login should be unsuccessful$")
public void inShouldBeUnsuccessful(Map<String,String> dataTable) {
System.out.println(dataTable);
//结果打印{success=success, msg=good, state=500}
}
17. 传值(二维数组)
Then login should be unsuccessful
| | msg | status |
|success | good | 0000 |
|fail | bad | 5555 |
@Then("^login should be unsuccessful$")
public void inShouldBeUnsuccessful(Map<String,Map<String,String>> dataTable) {
System.out.println(dataTable);
//结果打印{success={msg=good, status=0000}, fail={msg=bad, status=5555}}
}
18. 直接对象接收
Then login should be unsuccessful
|success | fail |
|msg | bad |
|status | 5555 |
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
可以在glue指定配置文件位置
@CucumberOptions(features = "src/test/resources/facebook",
plugin = {"pretty","html:target/cucumber","json:target/cucumber.json"},
glue = {"com.cucumber.demo.facebook"},
monochrome = true,
tags = {"@test1","@test3"})
必须定义配置类,在配置类里将DataTable数据转化为对应对象
public class Configurer implements TypeRegistryConfigurer {
private DataTableTypeRegistry registry = new DataTableTypeRegistry(Locale.ENGLISH);
//cumumber提供的一个默认实现DataTable.TableConverter的类
private DataTable.TableConverter converter = new DataTableTypeRegistryTableConverter(registry);
@Override
public Locale locale() {
return Locale.ENGLISH;
}
@Override
public void configureTypeRegistry(TypeRegistry typeRegistry) {
typeRegistry.defineDataTableType(new DataTableType(Res.class, (DataTable dataTable)->{
Map<String, String> dataMap = converter.toMap(dataTable, String.class, String.class);
return JSON.parseObject(JSON.toJSONString(dataMap),Res.class);
}));
}
}
@Then("^login should be unsuccessful$")
public void inShouldBeUnsuccessful(Res res) {
System.out.println(JSON.toJSONString(res));
//结果打印{"msg":"bad","status":"5555","success":"fail"}
}
19. 对象集合接收
Then login should be unsuccessful
|success | msg | status |
|success | good | 0000 |
|fail | bad | 5555 |
public class Configurer implements TypeRegistryConfigurer {
...
@Override
public void configureTypeRegistry(TypeRegistry typeRegistry) {
...
typeRegistry.defineDataTableType(new DataTableType(Res.class, (Map<String,String> dataMap)->{
return JSON.parseObject(JSON.toJSONString(dataMap),Res.class);
}));
}
}
@Then("^login should be unsuccessful$")
public void inShouldBeUnsuccessful(List<Res> res) {
System.out.println(JSON.toJSONString(res));
//打印结果[{"msg":"good","status":"0000","success":"success"},{"msg":"bad","status":"5555","success":"fail"}]
}