# api-test
**Repository Path**: taylortaurus/api-test
## Basic Information
- **Project Name**: api-test
- **Description**: 一整套接口测试解决方案
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 4
- **Forks**: 0
- **Created**: 2021-01-29
- **Last Updated**: 2024-08-18
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## 分层思想: 分为三层,相互独立(接口,数据,用例)
一个用例对应多个接口 一个接口可以对应多个数据 一个数据只能对应一个接口
## 接口层: 实现方式为动态代理,spring容器启动后,生成代理接口注入容器
#### 编写方式:
注:如果不进行通用头部等rest-assured过滤器与通用BaseUrl设置,可直接注入com.ly.api.DefaultApiClient类进行接口调用
eg.
```java
@HttpServer(baseUrl = "${driver-api.url}")
@Filters({RestAssuredLogFilter.class, DriverHeadersFilter.class})
public interface DriverApiClient extends BaseHttpClient{
}
```
1. 定义一个接口类继承com.ly.api.BaseHttpClient,类上注解@HttpServer注解标明该接口是一个http接口类
2. 注解
- @HttpServer: 接口类上注解,必填,可设置整个接口类的baseUrl,可用通配符${},读取对应的application.xml配置
- @Filters: 用于传递rest-assured过滤器注解,接收一个io.restassured.filter.Filter类数组, 如果注释在类上,则整个类接口都会使用该注解里面的过滤器,如果注解在方法上,则作用域该方法,如: 需要设置该类下所有接口默认headers,可继承com.ly.core.listener.BaseHeadersFilter类,重写defHeaders()方法进行设置默认固定头部,如果与yaml文件中headers重复,优先headers中参数,两个地方都可用${}通配符调用
## 数据层: 通过yaml文件作为数据载体,其中headers,requests,validate中的值都支持${}通配符调用,validate中断言key支持jsonpath与xpath语法
#### 编写模板:
```
name: login
type: json
description: 登录成功
url: /login
method: POST
headers:
x-request-client-imei: "222222222222"
requests:
{
"phone": "${phone, 13000000001}",
"code": "0000"
}
setup:
- method: createTimestamp
- method: setUptest
args: ${request}
teardown:
- method: teardowm
args: args1111, args222
- method: teardowm1
args: ${response}, ${timestamp}
onFailure:
- method: onFailure
args: args1111, args222
validate:
eq: ["result": 0, "error_code": "0"]
notNull: ["data.token"]
plugin:
- method: "teardowm"
args: args1111, ${orderId}
saveGlobal: ["orderId": "response.data.orderId"]
saveMethod: ["orderId": "response.data.orderId"]
saveClass: ["orderId": "response.data.orderId"]
saveThread: ["orderId": "response.data.orderId"]
parameters:
- name: login-phone-unregistered
description: 手机号未注册
headers:
requests:
"phone": "13000000009"
"code": "0000"
validate:
eq: ["result": 1]
- name: login-phone-not-found
description: 手机号不存在
requests:
"phone": "10000000000"
"code": "0000"
validate:
eq: ["result": 1]
- name: login-code-length-error
description: 验证码长度错误
requests:
"phone": "10000000000"
"code": "000"
validate:
eq: ["result": 1]
- name: login-code-error
description: 验证码错误
requests:
code: "0001"
validate:
eq: ["result": 1]
```
- name:为该数据唯一标识,用例中引入需要
- type:标识该接口请求方式,目前支持(form,json,xml)
- description:简介,标明该数据作用
- url:接口url,可以是一个带http/https的全的url,也可是baseUrl + url
- method:http请求方法
- headers:接口头部,非必填
如果有默认固定头部可继承com.ly.core.listener.HeadersFilterAdapter,重写defHeaders()方法进行设置默认固定头部,如果与yaml文件中headers重复,优先headers中参数,两个地方都可用${}通配符调用
- requests接口请求数据,非必填
- setup, teardown: 接口请求前后的两个hook函数,setup在接口执行前会执行,teardown在接口执行后且各种断言执行完后执行, 支持${}参数
- validate断言非必填
断言方法内key为固定,比如eq,notNull,isNull,plugin等,value为一个数组,支持jsonpath取接口返回值与支持通配符${}取前面接口缓存,其中plugin为插件式断言,里面为com.ly.plugin.PluginSupport类中的一个方法,用法如hook函数
- onFailure接口失败调用
如果接口调用失败或者validate校验不过会调用onFailure中的方法,用于进行一些有状态的数据回滚
- saveGlobal保存一个作用域在整个测试生命周期的值
- saveMethod保存一个作用域在该测试方法的值(多线程运行时候会进行线程隔离,线程安全)
- saveClass保存一个作用域在该测试类的值
- saveThread保存一个作用域在该线程的值(用于多线程执行用例时候进行线程隔离)
- parameters接口参数化设置,可为空
parameters节点结构为一个list,list里面每一个值相当于一份完整的接口数据
parameters除了定义下的5个节点数据与save节点(saveMethod,saveThread,saveGlobal)外,其他数据全取父case内容,组装成一份完整的case数据,运行模式为SINGLE时候,会把父case与parameters节点下的case都运行一遍
parameters节点下包括:
1. name节点: 单接口SINGLE模式下该值可省略, MULTIPLE串行时候如果需要调用该参数化数据需要填写唯一的name
2. description节点: 简介,可省略,省略取父节点description值
3. headers节点: 参数化节点与父case节点headers差异值,其本质为一个map,会和父case节点headers节点合并,key相同的参数用parameters中headers值覆盖,如无差异可省略
4. requests节点: 参数化节点与父case节点requests差异值,其本质为一个map,会和父case节点requests节点合并,key相同的参数用parameters中requests值覆盖,key会递归替换,如无差异可省略
5. validate节点:参数化数据自有的一份断言, 如果为空会取父case断言,如无差异可省略
6. headers节点与requests节点会递归替换, 如果需要验证某个字段不存在,可将该字段设置为null
- 参数化说明
yaml模板中支持参数化|jsonpath|xpath等写法,如${phone, 13000000001}, 该用法为该参数化值设置一个default值,如果缓存中无该值,那就取default值
jsonpath一般用于validate与saveGlobal中,用于取返回值校验与保存
setup支持${response}参数化,${response}会转换成com.ly.core.parse.BaseModel
teardown支持${response}参数化,${response}会转换成com.ly.core.base.Response
## 用例层: 通过深度集成testng进行用例执行
#### 编写格式:
定义一个类继承com.ly.core.base.BaseTestCase.class,然后通过spring @Autowired注入编写的接口层的类,再调用接口类中定义的接口,返回一个com.ly.core.base.Response对象
###### 测试用例方法注解说明:
1. allure测试报告注解:
- @Feature("driver-api")
类上注解, 标注主要功能模块, 可以理解为testsuite
- @Story("登录模块接口")
类上注解,属于feature之下的结构,可以理解为testcase
- @Severity(SeverityLevel.CRITICAL)
标注测试用例的重要级别
1. Blocker级别——中断缺陷
2. Critical级别――临界缺陷
3. Major级别——较严重缺陷
4. Normal级别――普通缺陷
5. Minor级别———次要缺陷
6. Trivial级别——轻微缺陷
7. Enhancement级别——测试建议、其他(非缺陷)
- @Description("司机基础信息")
用例说明
2. testng核心驱动注解@Test:
@Test(groups = "driver-api")
3. 测试数据引入核心注解@DataModel:
eg.
```
@DataModel(path = {"test-driver-api.yml", "test-ck.yml"}, format = DataModel.Format.MULTIPLE)
```
eg.
```
@DataModel(value = {"login1", "login2", "login3"}, format = DataModel.Format.SINGLE)
```
- value: 对应的数据层中的name, 做数据层引入, format = DataModel.Format.MULTIPLE可省略value值, 引入path所有值
- format:
- DataModel.Format.MULTIPLE 串行, value中只做数据引入,测试方法入参为com.ly.core.parse.MultipleModel, 需要使用指定数据时候调用MultipleModel.getModel("name")
- DataModel.Format.SINGLE 单接口, value中有多少份数据引入就会执行多少次,测试方法入参为com.ly.core.parse.BaseModel
4. 请求与响应
com.ly.api.BaseHttpClient对象, 一个用于发起请求http的Client
com.ly.core.base.Response对象, 链式调用方法处理接口返回值
eg.
```
driverApiClient.wait(TimeUnit.SECONDS, 1)
.saveAsk("key", "key")
.doHttp("login")
.auto();
```
- BaseHttpClient对象方法
wait(),wait(TimeUnit unit, long interval) 用于设置请求接口前的等待时间
saveAsk(),saveGlobal(), saveTest(),saveSuite() 用于往不同生命周期保存一个缓存,saveAsk为该请求生命周期
doHttp(BaseModel model)接口调用,入参为model,SINGLE模式时候直接传入方法入参BaseModel即可
doHttp(String modelName)接口调用,入参为modelName, MULTIPLE模式时候传入modelName即可
- Response对象方法
then(): 语法糖,无特殊意义,只用作链式调用标明
statusCode(): 用于断言接口返回code
validate(): 断言方法
eq(): 硬编码断言相等
eqByPath(): 硬编码断言相等,值取jsonpath,xpath
validatePlugin(): 硬编码断言,用于调用方法
saveGlobal(), saveTest(),saveSuite() : 结果保存不同维度方法
onFailure(BaseFailHandle failHandle): validate()断言失败后会执行的方法,所以必须在validate()方法后调用,入参为BaseFailHandle接口,需要实现该接口并且重写handle(T t)方法
onFailure(Class clazz): 同上
extract(): 用于取值
processor(BaseProcessorHandle processorHandle)
processor(Class clazz):用于该调用该接口后一些自定义处理,如订单行程需要一分钟,入参为BaseProcessorHandle接口,需要实现该接口并且重写processor(T t)方法
wait(): 接口执行完后等待时间
done(): 用于处理结束,抛出validate()异常,如没吊用extract()方法取值的话该方法为链式调用结尾必须调用
auto(): 自动解析yaml文件所有内容
auto(int httpStatusCode): 自动解析yaml文件所有内容,手动设置httpStatusCode
autoExcludeDone(): 自动解析yml文件, 但是不会自动调用done()方法结束,需要手动调用done结束,主要用于给该http请求添加更多的自定义处理
5. 配置方法使用,定义一系列配置方法,不同测试生命周期运行
@ApiBeforeMethod
@ApiBeforeClass
@ApiBeforeSuite
@ApiAfterMethod
@ApiAfterClass
@ApiAfterSuite
主要结合@DataModel, @DataFile, @DataParams 当配置方法入参使用
## 配置文件说明: src/main/resources
application-qa.yml,application-uat.yml 区分环境配置文件,最终会根据使用环境默认合并到application.yml
- application.yml
- notification节点: 配置通知类型
- retry节点: 配置用例失败重试
- application-qa.yml,application-uat.yml
- httpurl节点: 配置接口层接口类上面@HttpServer注解中baseurl代表值baseurl直接用${driverapi.url}调用即可
- redis节点: 配置redis
```
RedisService redisService = SpringContextUtil.getBean(RedisService.class);
```
- mongodb节点: 配置mongodb
```
MongoTemplate mongoTemplate = SpringContextUtil.getBean(MongoTemplate.class);
```
- datasource节点: 配置多数据源
```
MysqlServer mysqlServer = MysqlServer.create("carrier");
```
## 运行方式:
- testng.xml运行
- maven运行 : mvn clean test -P uat -Dtestng.xmlFilePath=testng.xml 执行测试用例, -P 参数后面跟着需要执行的环境,默认uat, -Dtestng.xmlFilePath 可选择执行的xml文件 默认testng.xml(支持Groups方式,详情查看pom.xml)
- 调用com.ly.core.actuator.TestNgRun运行
- 根据groups运行测试用例
- 根据类运行测试用例
- 根据类中方法运行测试用例
- 可设置运行并发
- 测试报告运行: allure serve target/allure-results
## 环境搭建:
- jdk1.8
- idea(需要装下maven插件与lombok插件)
- maven(一般来说idea会自带一个)
- allure2.13.2 (需要把allure目录加到ALLURE_HOME环境变量)
## 其他支持:
- 提供一个测试全程生命周期监听器com.ly.core.listener.BaseLifeCycleListener(不建议使用)
- 提供一个TestNg全程生命周期接口com.ly.core.support.TestNgLifeCyclePostProcessor(建议使用)
- 提供一个HTTP请求生命周期接口com.ly.core.support.HttpPostProcessor
- 提供一个给PostProcessor接口排序的Order接口
- 可设置测试用例执行失败或发生异常时,在多少个错误后跳过后续的其他测试用例
pom.xml文件中设置
```
5
```
- 可设置通过设置groups运行,但是只能选择groups与 testng.xml其中一种方式运行,需要改pom.xml文件
- 提供另外两种数据驱动方式 @DataFile与@DataParams
- 提供com.ly.core.actuator.TestNgRun 编码方式运行
- 提供har与swagger格式转换为yaml用例数据(charles导出.har文件转换为yaml格式)
```
com.ly.core.Utils.Source2Yaml
```
- redis
- mysql
- MongoDB
- 钉钉,邮件通知
- 用例失败重试
- 并发执行
- jenkins支持
## 资料
- testng文档
- allure文档