基于 YAML 接口自动化测试框架设计

在设计自动化测试框架的时候,我们会经常将测试数据保存在外部的文件(如Excel、YAML、CSV),或者数据库中,实现脚本与数据解耦,方便后期维护。目前非常多的自动化测试框架采用通过Excel或者YAML文件直接编写测试用例,通过脚本读取出来驱动自动化测试代码执行。至于采用Excel还是YAML格式各位小伙伴都有不同见解,比如用Excel维护直观、修改数据方便,劣势是通过Git这样的版本控制工具不太好比较历史版本差异(因为是二进制格式);YAML的优势是支持数据格式完备、版本控制管理方便(文本格式),劣势是没有Excel这么直观。Excel这种方式大家比较熟悉了,本文带着大家来了解如何基于YAML设计自动化测试框架。

YAML格式测试用例设计

以接口自动化为例,用YAML编写测试用例要实现的基本功能需求:

  1. 一个YAML文件能够支持多个用例存储需求,不然几千个用例对应几千个YAML文件管理起来也受不了
  2. 用例中能够支持单接口测试用例也能支持业务场景用例(多个接口调用组合)
  3. 用例中需要包含所属模块、用例名、请求信息、断言信息、提取响应(实现接口关联)等信息

基于上述需求我们来设计一版YAML格式用例:

 
 
  1. - casename: 登录成功

  2. module: 用户模块

  3. teststeps:

  4. - name: 正确用户名、密码进行登录

  5. request:

  6. method: POST

  7. url: /login

  8. headers:

  9. Content-Type: application/json

  10. json:

  11. username: lemon_auto

  12. password: lemon123456

  13. appType: 3

  14. loginType: 0

  15. extract:

  16. token: access_token

  17. validate:

  18. - eq: ["status_code", 200]

  19. - eq: ["nickName", "lemon_auto"]

casenamemodule字段简单,我们来看下teststeps,为什么teststeps是数组类型?

因为用例中包含一个/多个接口请求步骤,也就是一个TestCase包含了多个teststep,每一个teststep就是一个接口请求。

request中指定接口请求信息,包括接口请求方法、请求地址、请求头、请求参数;其中不同的请求参数类型我们需要进行区别,上述的是json传参,如果是form表单、查询参数传参我们都可以约定为类似的key-value结构,只需要将json改为formparam、queryparam。

需要注意的是文件上传接口的参数会比较特殊,一般来说我们只需要设置要上传文件路径即可,所以我们可以这样设计:

 
  1. - casename: 上传图片

  2. module: 用户模块

  3. teststeps:

  4. - name: 正常上传图片

  5. request:

  6. method: POST

  7. url: /p/file/upload

  8. headers:

  9. Content-Type: multipart/form-data

  10. file: src/test/resources/upload.png

  11. extract:

  12. resourcesUrl: resourcesUrl

  13. filePath: filePath

  14. validate:

  15. - eq: [ "status_code", 200 ]

extract字段为要提取的响应数据字段,传递给后续的接口使用。一般我们要求能够支持JsonPath表达式或者正则表达式来提取,对应的key为要提取的字段名,对应的值为要提取的字段表达式。

validate字段是断言信息,也就是验证响应结果是否符合预期。这里我们需要支持常用的判断方法包括:等于、大于、小于、大于等于、小于等于,通过简写eq代替equals(等于)判断,其他的类似:大于等于(ge)、小于等于(le)、小于(lt)、大于(gt)。

上述的是单接口测试用例,我们看下多接口串联(业务场景)用例编写的样式:

ModifyUserProfile.yaml

 
 
  1. - casename: 修改用户头像

  2. module: 用户模块

  3. teststeps:

  4. - name: 登录成功

  5. request:

  6. method: POST

  7. url: /login

  8. json:

  9. username: lemon_auto

  10. password: lemon123456

  11. appType: 3

  12. loginType: 0

  13. headers:

  14. Content-Type: application/json

  15. extract:

  16. token: access_token

  17. validate:

  18. - eq: ["status_code", 200]

  19. - eq: ["nickName", "lemon_auto"]

  20. - name: 进入到个人中心

  21. request:

  22. method: GET

  23. url: /p/user/userInfo

  24. headers:

  25. Authorization: ${token}

  26. validate:

  27. - eq: ["status_code", 200]

  28. - name: 上传头像

  29. request:

  30. method: POST

  31. url: /p/file/upload

  32. headers:

  33. Authorization: ${token}

  34. Content-Type: multipart/form-data

  35. file: src/test/resources/upload.png

  36. extract:

  37. resourcesUrl: resourcesUrl

  38. filePath: filePath

  39. validate:

  40. - eq: ["status_code", 200]

在多接口测试中重要的是要能够支持参数传递,这里我们在前一个接口使用extract提取接口的响应字段,在后续要使用的接口中通过${token}方式进行引用,熟悉Jmeter接口测试工具的同学应该非常熟悉这种格式。

脚本读取YAML数据

在读取YAML文件数据之前,我们首先需要了解两个概念:序列化与反序列化

  • 把对象转换为字节序列的过程称为对象的序列化;
  • 把字节序列恢复为对象的过程称为对象的反序列化。

而我们读取YAML的过程就可以称之为反序列化。

主流的编程语言都能实现对YAML的解析,接下来以Java语言为例讲解如何读取YAML文件的内容:

Java中能够实现YAML序列化和反序列化的库有很多,包括SnakeYamlJacksonjYaml等,使用起来大同小异。以使用Jackson为例:

步骤一:Maven POM文件中添加库的坐标
 
 
  1. <dependency>

  2. <groupId>com.fasterxml.jackson.core</groupId>

  3. <artifactId>jackson-databind</artifactId>

  4. <version>2.10.2</version>

  5. </dependency>

  6. <dependency>

  7. <groupId>com.fasterxml.jackson.dataformat</groupId>

  8. <artifactId>jackson-dataformat-yaml</artifactId>

  9. <version>2.10.2</version>

  10. </dependency>

  11. <dependency>

  12. <groupId>org.projectlombok</groupId>

  13. <artifactId>lombok</artifactId>

  14. <version>1.18.12</version>

  15. <scope>provided</scope>

  16. </dependency>

这里用到了jackson-databind与jackson-dataformat-yaml,其中jackson-databind是Jackson的主库,jackson-dataformat-yaml是支持YAML数据格式的库,在这里同时引入了lombok,是为了后面编写实体类时简化一些代码的书写:

Lombok可以来帮助我们简化一些必须有但显得很臃肿(比如get/set方法)的Java代码的工具,通过使用对应的注解,可以在编译源码的时候自动生成对应的方法。
步骤二:编写YAML实体类

对照YAML文件内容比如字段名(比如 “姓名”)和字段的数据类型(比如字符串),创建一个对应的类,用来在 Java 中表示YAML文件的信息。目的是为了能够将YAML文件保存到Java对象中(反序列化)。

TestCase实体类:

 
  1. @Data

  2. @NoArgsConstructor

  3. @AllArgsConstructor

  4. public class TestCase {

  5. private String casename;

  6. private String module;

  7. private List<Teststep> teststeps;

  8. }

Teststep实体类:

 
  1. @Data

  2. @NoArgsConstructor

  3. @AllArgsConstructor

  4. public class Teststep {

  5. private String name;

  6. private Request request;

  7. private HashMap<String,String> extract;

  8. private List<Validate> validate;

  9. }

Validate实体类:

 
  1. @Data

  2. @NoArgsConstructor

  3. @AllArgsConstructor

  4. public class Validate {

  5. private List<Object> eq;

  6. private List<Object> gt;

  7. private List<Object> ge;

  8. private List<Object> lt;

  9. private List<Object> le;

  10. }

通过Jackson读取YAML文件内容并保存到TestCase实体类对象中

 
  1. public static List<TestCase> loadYaml(String path){

  2. ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());

  3. List<TestCase> cases = null;

  4. try {

  5. cases = objectMapper.readValue(new File(path), new TypeReference<List<TestCase>>() {});

  6. } catch (IOException e) {

  7. System.out.println(path+"格式非法,请检查配置");

  8. e.printStackTrace();

  9. }

  10. return cases;

  11. }

其中new TypeReference<List<TestCase>>() {}是因为读取到的YAML文件中有多个TestCase用例,所以我们需要定义为List集合类型来接收。

来看看读取之后的效果:

后续即可通过返回的testCase发起接口请求(比如通过REST-assured)、进行接口断言、提取响应字段等操作。

感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!有需要的小伙伴可以点击下方小卡片领取   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值