java 生成自定义xml_走进Java接口测试之从0到1搭建数据驱动框架(用例管理)

本文介绍了如何在SpringBoot项目中,通过MyBatis与TestNG实现数据驱动的接口测试用例管理,包括MySQL数据库的配置、自定义SQL查询、TestNG的参数化测试和脚本驱动。从表结构设计到代码实现,一步步教你落地搭建测试框架。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

8f1f57af613ccba5650070ba7d0df501.png

前言

先吐个槽,参加过很多技术大会,也看过个很多技术类文章,发现大部分存在一个通病,即:都会提问题,提思路,但是都不会讲具体的落地方案,所以我写东西给自己定了一个目标,即:能够落地,尽量提供一个小而简单的 Demo 让感兴趣的同学能快速上手。好了,这里啰嗦两句,下面进入正题。

在上两篇中,我们先介绍了需求功能,然后讲解了大概的框架设计,今天这篇主要看用例管理功能怎么落地去实现。

走进Java接口测试之从0到1搭建数据驱动框架(需求篇)走进Java接口测试之从0到1搭建数据驱动框架(设计篇)

开发环境

  • SUN JDK1.8及以上

  • Maven 3.5.4及以上

  • IntelliJ IDEA 2018及以上

  • windows/macOS

  • Git 不限

  • MySQL 5.7及以上

  • Navicat Premium 11.2.7及以上 或 SQLyog 11.3及以上

新建Spring Boot项目

这里使用的 IDE 是 IntelliJIDEA2018: 5d7fda1661e5e4d374c12421b8425d21.png引包,配置 pom.xml:

org.mybatis.spring.boot

mybatis-spring-boot-starter

2.1.1

mysql

mysql-connector-java

runtime

org.projectlombok

lombok

true

org.springframework.boot

spring-boot-starter-test

test

org.junit.vintage

junit-vintage-engine

org.testng

testng

6.14.3

compile

全部代码骨架结构

├─logs

│ └─spring-boot-logback # 日志文件

│ all_api-test-logback.log # 所有日志

│ err_api-test-logback.log # 错误日志

├─src

│ ├─main

│ │ ├─java

│ │ │ └─com

│ │ │ └─zuozewei

│ │ │ └─springbootdatadrivendemo

│ │ │ │ SpringbootDataDrivenDemoApplication.java # 启动类

│ │ │ │

│ │ │ ├─db

│ │ │ │ ├─auto # 存放MyBatis Generator生成器生成的数据层代码,可以随时删除再生成

│ │ │ │ │ ├─mapper # DAO 接口

│ │ │ │ │ └─model # Entity 实体

│ │ │ │ └─manual # 存放自定义的数据层代码,包括对MyBatis Generator自动生成代码的扩展

│ │ │ │ ├─mapper # DAO 接口

│ │ │ │ └─model # Entity 实体

│ │ │ ├─handler # 数据转换

│ │ │ └─service # 业务逻辑

│ │ │ └─impl # 实现类

│ │ │

│ │ └─resources

│ │ │ application.yml # 全局配置文件

│ │ │ generatorConfig.xml # Mybatis Generator 配置文件

│ │ │ logback-spring.xml # logback 配置文件

│ │ │ spy.properties # P6Spy 配置文件

│ │ │

│ │ ├─db

│ │ ├─mapper

│ │ │ └─com

│ │ │ └─zuozewei

│ │ │ └─springbootdatadrivendemo

│ │ │ └─db

│ │ │ ├─auto # 存放MyBatis Generator生成器生成的数据层代码,可以随时删除再生成

│ │ │ │ └─mapper # 数据库 Mapping 文件

│ │ │ │

│ │ │ └─manual # 存放自定义的数据层代码,包括对MyBatis Generator自动生成代码的扩展

│ │ │ └─mapper # 数据库 Mapping 文件

│ │ └─testng

│ │ │ APICollection-TestSuite.xml # 所用测试用例集

│ │ └─jdbcbapi

│ │ jdbcAPI-TestSuite.xml # 某API测试用例集

│ │

│ └─test

│ └─java

│ └─com

│ └─zuozewei

│ └─springbootdatadrivendemo

│ └─demo # 接口测试用例

├─pom.xml

测试用例管理

MySQL数据库

创建测试用例表:

CREATE DATABASE /*!32312 IF NOT EXISTS*/`autotest` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_vietnamese_ci */;

USE `autotest`;

/*Table structure for table `api_testdata_demo` */

DROP TABLE IF EXISTS `api_testdata_demo`;

CREATE TABLE `api_testdata_demo` (

`id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '测试ID',

`Protocol` enum('Http','RPC','jdbc') DEFAULT NULL COMMENT '协议',

`Category` enum('Webapi','db') DEFAULT NULL COMMENT '接口类别',

`Method` varchar(128) DEFAULT NULL COMMENT '接口名称',

`Parameters` varchar(1000) DEFAULT NULL COMMENT '参数',

`expected` varchar(128) DEFAULT NULL COMMENT '检查点',

`description` varchar(1000) DEFAULT NULL COMMENT '描述',

`isRun` enum('1','0') DEFAULT NULL COMMENT '运行状态,1:运行,0:未运行',

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

/*Data for the table `api_testdata_demo` */

insert into `api_testdata_demo`(`id`,`Protocol`,`Category`,`Method`,`Parameters`,`expected`,`description`,`isRun`) values (1,'jdbc','db','demo','latte','CNY 25.00','测试demo','1');

创建完成大概是这样: 64c32b6b16fe8de12e3edc536728c15b.png 这里的 SQL 主要决定了选取哪些测试用例进行测试: abce2b2976d24b639fa480e797abae87.png

SELECT * FROM autotest.api_testdata_demo

WHERE Protocol = 'jdbc'

AND Category = 'db'

AND Method = 'demo'

AND isRun = 1;

注意:SQL 取用例是非常灵活,可以根据自己的业务调整表结构。

持久层开发

这里使用 mybatis 直接使用原生的 SQL 查询测试用例的数据。

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

Mapper.xml

编写对应的 TestDataMapper.xml:

xml version="1.0" encoding="UTF-8" ?>

namespace="com.zuozewei.springbootdatadrivendemo.db.manual.mapper.TestDataMapper" >

id="selectBysql" parameterType="String" resultType="java.util.LinkedHashMap">

${value};

注意:

  • 这里是使用的是 ${},而不是 #{},这是因为如果我们使用 #{} 的时候,MyBatis 会自动帮我们把我们的字段自动加上单引号',使用 ${} 的时候就不会;

  • 使用 java.util.LinkedHashMap 作为返回类型,可以保持结果集本来的字段顺序。

Dao接口

dao 层增加 TestDataMapper.java:

/**

* 描述:

* 自定义sql查询

*

* @author zuozewei

* @create 2019-11-21 21:18

*/

public interface TestDataMapper {

// 自定义sql查询

List<LinkedHashMap<String, Object>> selectBysql(String sql);

}

Service 的接口 TestDataService :

/**

* 描述: TestDataService

*

* @author zuozewei

* @create 2019-11-21 18:00

*/

public interface TestDataService {

// 自定义查询

List<LinkedHashMap<String, Object>> selectBysql(String sql);

}

实现 Service 的接口调用方法:

/**

* 描述: 参数化自定义查询实现类

*

* @author zuozewei

* @create 2019-11-21 16:04

*/

@Service

public class TestDataServiceImpl implements TestDataService {

@Resource

private TestDataMapper testDataMapper;

@Override

public List<LinkedHashMap<String, Object>> selectBysql(String sql) {

return testDataMapper.selectBysql(sql);

}

}

为了避免出现值 null 的列,不能被保存到 LinkedHashMap 对象 中,需要在 application.yml 的配置文件中 mybatis 如下配置:

mybatis:

configuration:

call-setters-on-nulls: true # 调用setter null,返回空也必须设置到bean中(直接执行sql专用)

脚本参数化

脚本参数化主要使用 TestNG 的 @DataProvider & Testng.xml

首先我们在resource下创建一个 testng 配置文件:

name="jdbc 测试" verbose="1" preserve-order="true" >

name="测试demo" preserve-order="true">

name="sql"

value="SELECT * FROM autotest.api_testdata_demo

WHERE Protocol = 'jdbc'

AND Category = 'db'

AND Method = 'demo'

AND isRun = 1;"/>

name="com.zuozewei.springbootdatadrivendemo.demo.TestMapperService"/>

解释一下配置文件:

  • SQL的话,这里的SQL主要决定了选取哪些测试用例进行测试。

  • 一个标签,就代表一组测试,可以写多个标签。

  • “listener”是为了最后能够生成一个报告。

编写脚本代码 TestMapperService.java:

@SpringBootTest

@Slf4j

public class TestMapperService extends AbstractTestNGSpringContextTests {

private String sql; // SQL参数

@Autowired

private TestDataService testDataService;

@Parameters({"sql"})

@BeforeClass

public void beforeClass(String sql) {

this.sql = sql;

}

/**

* XML中的SQL决定了执行什么用例, 执行多少条用例, SQL的搜索结果为需要测试的测试用例

*/

@DataProvider(name = "testData")

private Object[][] getData() {

List<LinkedHashMap<String, Object>> results = testDataService.selectBysql(sql);

Object[][] objects = new Object[results.size()][];

for (int i = 0; i < results.size(); i++) {

objects[i] = new Object[]{results.get(i)};

}

return objects;

}

@Test(dataProvider = "testData",description = "测试demo")

public void testSelect(Map<String, String> data) throws InterruptedException {

// to do something...

}

}

注意:

  • SpringBoot 中使用 TestNg 必须加上 @SpringBootTest,并且继承 AbstractTestNGSpringContextTests,如果不继承AbstractTestNGSpringContextTests,会导致 @Autowired 不能加载 Bean。

  • @Parameters({"sql"}):从 xml 配置文件中获取 SQL语句;

  • @DataProvider 的数据来源是 MySQL;

  • @Test:测试逻辑地方。

工程结构

最后,用例管理的工程结构大概是以下的样子:

a7ca824501b65ecdc5ad0bc0991f3a71.png

小结

在今天这篇文章中,主要基于 SpringBoot 框架的能力,和大家分享了实现一个用例管理的过程。在实现过程中,你最需要关注的几部分内容是:

  • 使用目前的主流 SpringBoot 2.2.0 作为项目的主体框架;

  • 使用 Maven 作为构建项目,方便管理依赖的 JAR 包;

  • 使用 MySQL 集中式管理测试用例,结构化数据;

  • 使用 TestNG 作为测试框架,强大的参数化功能,方便执行测试脚本;

  • MySQL 数据库管理测试用例,SQL 参数化驱动用例运行,实现测试脚本和数据的解耦;

至此,我们要实现接口用例集中式管理功能,也算是完成了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值