Commit 9b3bb3cd authored by xie.qin's avatar xie.qin

Java SDK supported.

parent a81cfc26
......@@ -3,14 +3,14 @@ English, please click [here](./HELP.md)
# 一款实用的API和SDK自动化测试框架
## 1. API自动化测试
```
```text
微服务时代,API的主要实现方式有 REST 和 RPC 两种。不同的接口形式,理所当然需要对应不同的测试方法。
```
### 1.1 REST API的自动化测试
#### 1.1.1 验证所有发布的 API 是否都能工作(冒烟测试)
##### 测试方法
```
```text
1. 根据微服务提供的 OPEN API 文件,得到其对外提供的所有 REST API 列表(包括路径、方法、请求消息体结构和接收消息体结构等)
2. 构造请求消息体时:
- 对于简单数据类型(如:integer, number, string, boolean),赋值为此数据类型在此 OPEN API 文件中定义的最大边界值。
......@@ -23,24 +23,24 @@ English, please click [here](./HELP.md)
- 复合数据类型 array,需要验证响应消息中是否包含复合类型 object ?是,则需要验证 key 和数据类型;否则仅需要验证数据类型是否匹配期望。
```
##### 用例参考
```
```html
- [点击此链接](/src/test/resources/features/sanitytest/backend.feature)
- ![结果截图](/gallery/sanity_test.png)
```
##### 优点
```
```text
- 无需测试人员手动编写测试脚本,测试框架全自动完成 OpenAPI 分析及 REST 消息的发送和结果验证。
- 根据不同微服务的自我定义,自动适配其支持的协议类型(如,http, https, http2等)进行消息的发送和接收。
- 执行速度快,436个 API,请求和验证可以在40秒内完成。
```
##### 局限性
```
```text
- 未考虑实际的业务需求;仅限于最基本的可行性验证。
- 返回失败的请求需要人工二次校验其准确性(如果事先把测试数据准备好,则可规避此问题,但需要付出更多的人力)。
```
#### 1.1.2 编写符合实际业务需求的 API 测试用例(功能测试)
##### 测试方法
```
```html
1. 准备json格式的测试数据,包括:
- 发送请求实时数据
- 接收响应实时数据 [格式参考](./src/test/resources/testdatacollection/v2.2.0/runtime/user_management/UserController.json)
......@@ -54,22 +54,22 @@ English, please click [here](./HELP.md)
- 否则打印错误断言,测试退出并标记为失败。
```
##### 用例参考
```
```html
- [点击此链接](/src/test/resources/features/apitest/restful/user_management/user_register.feature)
```
##### 优点
```
```text
- 用例编写简单,核心测试脚本仅数行。
- 消息的发送、接收以及结果验证对用例编写人员透明。测试用例编写人员需要关心的只是产品业务需求。
- 测试数据与功能需求关联,支持复用。不同测试脚本(用例)可使用相同测试数据。
```
##### 局限性
```
```text
- 更多需要讨论的是 API 测试本身的局限性,和本测试框架无关。
```
#### 1.1.3 构造微服务 mock server,根据不同的请求返回不同的响应指定结果 (集成测试)
##### 测试方法
```
```text
1. 准备json格式的请求响应数据;
2. 不同于 1.1.1 和 1.1.2 部分,mock server将无法集成到一个具体的测试用例中,它应该被部署为一个真实服务供客户端服务(在开发中的测试服务对象)调用;
3. 启动命令:java -jar auto-test-1.0.0-SNAPSHOT.jar --mvcmock.response.path=<> --server.ssl.enabled=<>
......@@ -85,26 +85,38 @@ English, please click [here](./HELP.md)
N/A
```
##### 优点
```
- 测试数据支持动态修改,无需重启服务。
- 返回结果支持参数化,即可以根据请求路径中的参数,动态替换返回结果中对应的参数的值。
- 适配客户端http/https请求模式并响应;HTTP协议支持HTTP1.X和HTTP2, HTTP2同时支持h2和h2c。
```text
1. 测试数据支持动态修改,无需重启服务。
2. 返回结果支持参数化,即可以根据请求路径中的参数,动态替换返回结果中对应的参数的值。
3. 适配客户端http/https请求模式并响应;HTTP协议支持HTTP1.X和HTTP2, HTTP2同时支持h2和h2c。
- 如何在本机生成证书?使用命令: keytool -genkey -alias netty-reactor -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
- 相关参数应根据在application.properties内的定义进行修改
- curl命令验证例子: curl -H "Content-Type:application/json" -X POST -d '{"user_id": "123", "coin":100, "success":1, "msg":"OK!" }' -v --http2-prior-knowledge http://172.22.17.74:8080/userservice/fedFromOrg/87654321
```
### 1.2 RPC API的自动化测试
```
```text
RPC形式的API,又以 gRPC 和 json-RPC 两种实现方式居多。
```
#### 1.2.1 [json-RPC](https://www.jsonrpc.org/specification) API的自动化测试
```text
从 json-RPC 的规范我们可以知道,相比较于 REST ,jsonRPC 消息有如下几个特点:
- 净荷消息由 HTTP1.1 承载;
- 请求方法仅有 POST 一种;
- 请求消息头(Header)中 Content-Type 必须是 application/json;
- 请求消息体(Request Body)中必须包含 json-RPC 的关键字属性:
- jsonrpc = "2.0"
- id = 2
- method = [rpc method]
由此可见,json-RPC API的测试方法,和 REST API 的测试方法基本相同。
```
#### 1.2.2 [gRPC](https://grpc.io/) API的自动化测试
##### 测试方法
```
```html
1. 获取 gRPC 接口定义的 [proto](https://developers.google.com/protocol-buffers/docs/proto3)文件,存放在对应测试版本的测试数据文件夹下([参考存放路径](/src/test/resources/testdatacollection/chain33/))。
- 根据实际情况判断(如,存在重名类等)是否需要在 proto 文件中指定输出的 java 类名(option java_outer_classname = "RpcProto";)
- 需要生成service类(option java_generic_services = true;)
- 根据实际情况判断(如,存在重名类等)是否需要在 proto 文件中指定输出的 java 类名(option java_outer_classname = "RpcProto";)
- 需要生成service类(option java_generic_services = true;)
2. 通过 gradle 插件命令生成java class。可携带参数chainVer,表示proto文件版本。
- gradlew generateProto -DchainVer=v1.6.6
3. 编写 gRPC 客户端请求数据文件([参考链接](/src/test/resources/testdatacollection/v2.2.0/runtime/OpsInChain/sendTransaction.json))
......@@ -113,16 +125,18 @@ RPC形式的API,又以 gRPC 和 json-RPC 两种实现方式居多。
- 编写 gRPC 服务端响应数据验证代码(主要是和 proto 文件中定义的 service.returns 进行结果比对)。
```
##### 用例参考
```
```html
- [点击此链接](/src/test/resources/features/apitest/grpc/accountManager.feature)
```
##### 优点
```
```text
- N/A
```
##### 有待提高
```
```text
- 对于语法不完整的 proto 文件,无法实现自动化验证;
- 相对 RESTful 接口自动化测试用例来说,RPC接口自动化测试用例需要更多的代码编写量。
```
#### 1.2.3 适用于 json-RPC API 的 mock server [参考1.1.3]
#### 1.2.4 适用于 gRPC API 的 mock server
\ No newline at end of file
......@@ -39,11 +39,19 @@ dependencies {
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
implementation 'io.qameta.allure:allure-okhttp3:2.14.0'
implementation 'com.github.briandilley.jsonrpc4j:jsonrpc4j:1.6'
//implementation 'com.google.protobuf:protobuf-java:3.17.3'
implementation 'com.google.protobuf:protobuf-java-util:3.17.3'
implementation 'com.google.protobuf:protobuf-java:3.10.0'
implementation 'com.google.protobuf:protobuf-java-util:3.10.0'
implementation 'io.grpc:grpc-netty:1.39.0'
implementation 'net.devh:grpc-client-spring-boot-starter:2.12.0.RELEASE' exclude group: 'io.grpc', module: 'grpc-netty-shaded'
implementation 'com.alibaba:fastjson:1.2.47'
implementation 'org.bitcoinj:bitcoinj-core:0.14.7'
implementation 'org.slf4j:slf4j-log4j12:1.7.30'
implementation 'org.bouncycastle:bcprov-jdk15on:1.67'
implementation 'net.vrallev.ecc:ecc-25519-java:1.0.3'
implementation 'io.grpc:grpc-all:1.39.0'
implementation 'com.google.guava:guava:29.0-jre'
compileOnly 'org.projectlombok:lombok:1.18.20'
testCompileOnly 'org.projectlombok:lombok:1.18.20'
runtimeOnly 'mysql:mysql-connector-java'
......@@ -59,6 +67,9 @@ dependencies {
testImplementation 'io.rest-assured:spring-mock-mvc:4.4.0'
testCompile 'io.qameta.allure:allure-cucumber6-jvm:2.14.0'
compile files(fileTree(dir: "libs", include: ['*.jar']))
testCompile files(fileTree(dir: "libs", include: ['*.jar']))
}
test {
......
......@@ -12,10 +12,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import java.io.File;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
@Slf4j
public class GrpcRequestVerification {
@Autowired
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment