postman实现按流程测试
之前虽然一直有用postman,但是一直只停留在最基本的单个请求的构造与发送上,直到实习后才发现原来postman能做的远不止单个请求的发送,collection也远不止是把相关的请求放到一起那么简单。在一个collection集合下的所有请求都可以按照一个流程来执行,并共享一个变量的命名空间,而结合 pre-request 和 Tests 两个tab下的脚本(postman内置了一个node运行环境),我们可以实现取出response中的参数并将其设置为集合变量或是全局变量,指定下一个请求,或者通过js构造并发送请求,以及对response中的值进行断言测试…… 关于这方面的介绍可以查看 postman的对应文档, 且脚本编写框的右侧也提供了不少的SNIPPETS。在我们写好了collection之后,还可以将其导出到一个json文件中,可以用于导入到其他的postman中进行测试或者是用于下文的actions自动测试。
另外,在测试断言时用到的语法可以参考 BDD Style
The BDD styles are expect and should. Both use the same chainable language to construct assertions, but they differ in the way an assertion is initially constructed. Check out the Style Guide for a comparison.
集合actions实现自动化测试
Newman is a command-line Collection Runner for Postman.
在action中我们需要用到Newman这个工具。
为了能让测试顺利进行,在action中我们还需要做几件事情:
- 构建二进制程序
- 通过docker启动一个数据库
- 使用程序或者是sql文件初始化数据库填充测试数据
- 使用newman按照导出的测试集合进行测试
其中,mysql和newman都已经有现成的action了,填上参数即可使用,这里贴一下我们最终采用的一个workflow文件,删除了特定部分,但是也足以用作参考。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
| name: ci-api-test
on:
pull_request:
permissions:
contents: read
# Optional: allow read access to pull request. Use with `only-new-issues` option.
# pull-requests: read
jobs:
golangci:
name: API Test
runs-on: ubuntu-latest
env:
GOPRIVATE: github.com/example
GH_ACCESS_TOKEN: ${{ secrets.GH_ACCESS_TOKEN }}
steps:
- uses: actions/checkout@v2
- uses: mirromutth/mysql-action@v1.1
with:
# host port: 3800 # Optional, default value is 3306. The port of host
# container port: 3307 # Optional, default value is 3306. The port of container
character set server: "utf8mb4" # Optional, default value is 'utf8mb4'. The '--character-set-server' option for mysqld
collation server: "utf8mb4_general_ci" # Optional, default value is 'utf8mb4_general_ci'. The '--collation-server' option for mysqld
mysql version: "5.7" # Optional, default value is "latest". The version of the MySQL
mysql database: "database" # Optional, default value is "test". The specified database which will be create
mysql root password: "dbpassword" # Required if "mysql user" is empty, default is empty. The root superuser password
# mysql user: 'developer' # Required if "mysql root password" is empty, default is empty. The superuser for the specified database. Can use secrets, too
# mysql password: ${{ secrets.DatabasePassword }} # Required if "mysql user" exists. The password for the "mysql user"
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.17
# 构件中用到了私有库,所以需要制定token
- name: Set token
run: git config --global url.https://$GH_ACCESS_TOKEN@github.com/.insteadOf https://github.com/
- name: Generate doc
run: go generate -x
- name: Init Mysql
run: go run main.go initMigrateMysql --config configs/config.ci.yaml
- name: Start service
run: go run main.go serve --config configs/config.ci.yaml &
# 使用前文导出的collection进行测试
- name: Newman API Test
uses: matt-ball/newman-action@v1.0.4
with:
collection: .postman/API.postman_collection.json
envVar: '[{ "key": "host", "value": "localhost:9000" }, { "key": "scheme", "value": "http" }]'
|
之后,在每次有人提交pr的时候,action便会被触发,完成构建->初始化->api测试的流程,如果出现了破坏性的改动,测试也能及时告诉我们,不至于合并进主干后再回退,甚至是发布后还要热修复。
不过新增了自动化api测试后,也需要我们每个人在开发一个新的api时都要及时加上我们新增的api对应的测试。不过最简单的测试,只需要像下面这样:
1
2
3
4
| pm.test("Check status ok", () => {
let jsonData = pm.response.json()
pm.expect(jsonData.code).to.eql(0,`${JSON.stringify(jsonData)}`)
})
|
查看响应对象里面的code是否为0(我们规定-1时代表异常)即可。当然,一个完备的测试还应该包含更多的情况,比如错误的请求也应得到合适的处理,而非返回一个500错误。