Skip to content

Commit 6f4aef8

Browse files
authored
doc: add release note of v0.0.18 (#555)
Co-authored-by: rick <[email protected]>
1 parent 28a32a0 commit 6f4aef8

File tree

11 files changed

+125
-26
lines changed

11 files changed

+125
-26
lines changed

.github/release-drafter.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ change-template: '* $TITLE (#$NUMBER) @$AUTHOR'
5252
template: |
5353
## What’s Changed
5454
55-
[中文 ChangeLog](https://linuxsuren.github.io/api-testing/release-note-v$NEXT_PATCH_VERSION)
55+
[中文 ChangeLog](https://linuxsuren.github.io/api-testing/latest/releases/release-note-v$NEXT_PATCH_VERSION)
5656
5757
$CHANGES
5858
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: "版本"
2+
title: "版本发布"
33
weight: 90
44
description: 本节内容包含 API Testing 的版本概述。
55
---
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
+++
2+
title = "v0.0.18"
3+
+++
4+
5+
`atest` 发布 `v0.0.18`
6+
7+
`atest` 是致力于帮助开发者持续保持高质量 API 的开源接口工具。
8+
9+
你可以在命令行终端或者容器中启动:
10+
11+
```shell
12+
docker run -p 8080:8080 ghcr.io/linuxsuren/api-testing:v0.0.18
13+
```
14+
15+
## 亮点
16+
17+
* 在开源之夏 2024 中 `atest` 增加了基于 MySQL 的测试用例历史的支持
18+
* HTTP API Mock 功能的支持
19+
20+
在系统和平台的开发过程中,我们通常会采用前后端分离的开发模式。在后端API尚未开发完成、稳定化,并且未部署到公共集成测试环境之前,前端开发者往往需要通过硬编码数据来推进页面开发。待后端开发完成后,会进入所谓的“联调”阶段,这时可能会遇到以下问题:
21+
22+
* 前端可能需要调整数据结构、页面布局和逻辑,并重新进行测试
23+
* 在实际查看页面后,可能会发现后端的数据结构和API的请求与响应需要调整
24+
25+
在最坏的情况下,前后端的联调可能会耗费远超预期的时间。为了更有效地解决这一问题,`atest` 提供了HTTP API Mock功能。
26+
27+
在设计评审阶段,我们可以根据API设计提供相应的Mock服务配置,从而快速模拟后端API的响应数据。例如:
28+
29+
```yaml
30+
objects:
31+
- name: users
32+
sample: |
33+
{
34+
"name": "LinuxSuRen",
35+
"age": 18
36+
"gender": "male"
37+
}
38+
proxies:
39+
- path: /api/v1/projects/{projectID}
40+
target: http://localhost:8080
41+
```
42+
43+
把上面的内容放到 `mock.yaml` 文件中,然后使用 `atest mock --prefix /api/v1 --port 6060 mock.yaml` 命令即可启动一个 HTTP Mock 服务。
44+
45+
此时,Mock 服务就会把**代理**模块指定的 API 转发到已有服务的的接口上,并同时提供了 `users` 对象的增删查改(CRUD)的标准 API。你可以用 `atest` 或者 `curl` 命令来调用这些 API。
46+
47+
```shell
48+
curl -X POST -d '{"name": "Rick"}' http://localhost:6060/api/v1/users
49+
curl -X GET http://localhost:6060/api/v1/users
50+
curl -X PUT -d '{"name": "Rick", "age": 20}' http://localhost:6060/api/v1/users/Rick
51+
curl -X GET http://localhost:6060/api/v1/users/Rick
52+
curl -X DELETE http://localhost:6060/api/v1/users/Rick
53+
```
54+
55+
非常期待 `atest` 可以帮助更多的项目持续提升、保持 API 稳定性。
56+
57+
## 🚀 主要的新功能
58+
59+
* Mock 功能的增强,包含对象、原始、代理三种模式 (#552) @LinuxSuRen
60+
* 支持重命名测试用例、测试集 (#550) @LinuxSuRen
61+
* 支持给定频率下重复执行测试用例 (#548) @LinuxSuRen
62+
* 下载插件文件时显示进度信息 (#544) @LinuxSuRen
63+
* 支持生成随机图片并上传 (#541) @LinuxSuRen
64+
* 支持上传嵌入式文件(基于 base64 编码) (#538) @LinuxSuRen
65+
* 支持导入其他 atest 实例的用例数据 (#539) @LinuxSuRen
66+
* UI 上显示响应体的大小 (#536) @LinuxSuRen
67+
* 增加基于 MySQL 位存储的测试用例执行历史记录 (#524) @SamYSF
68+
* 支持设置插件下载的“前缀”信息 (#532) @SamYSF
69+
* 优化存储插件管理界面 (#518) @LinuxSuRen
70+
* 在 UI 上增加快捷键支持 (#510) @LinuxSuRen
71+
* 重构 API 风格为 restFul (#497) @LinuxSuRen
72+
* 增加 Mock 配置的 JSON schema (#499) @LinuxSuRen
73+
* 增加了对 JSON 兼容性的响应格式的支持 (#496) @LinuxSuRen
74+
75+
## 🐛 缺陷修复
76+
77+
* 修复测试用例重复时被覆盖的问题 (#531) @LinuxSuRen
78+
79+
## 致谢
80+
81+
本次版本发布,包含了以下 3 位 contributor 的努力:
82+
83+
* [@LinuxSuRen](https://github.com/LinuxSuRen)
84+
* [@SamYSF](https://github.com/SamYSF)
85+
* [@yuluo-yx](https://github.com/yuluo-yx)
86+
87+
## 相关数据
88+
89+
下面是 `atest` 截止到 `v0.0.18` 的部分数据:
90+
91+
* watch 9
92+
* fork 50
93+
* star 249 (+40)
94+
* contributor 25 (+1)
95+
* 二进制文件下载量 6.3k (+3.2k)
96+
* 部分镜像 6.4k (+0.9k)
97+
* 单元测试覆盖率 76% (+2%)
98+
99+
想了解完整信息的话,请访问 https://github.com/LinuxSuRen/api-testing/releases/tag/v0.0.18

docs/site/hugo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,10 @@ enable = true
257257
url = "/latest"
258258

259259
# i18n for Chinese
260+
[[languages.zh.menu.main]]
261+
name = "版本发布"
262+
weight = -80
263+
url = "/releases"
260264
[[languages.zh.menu.main]]
261265
name = "贡献"
262266
weight = -98

pkg/mock/in_memory.go

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -199,27 +199,6 @@ func (s *inMemoryServer) startObject(obj Object) {
199199

200200
s.data[obj.Name] = append(s.data[obj.Name], objData)
201201

202-
_, _ = w.Write(data)
203-
} else {
204-
memLogger.Info("failed to read from body", "error", err)
205-
}
206-
case http.MethodPut:
207-
if data, err := io.ReadAll(req.Body); err == nil {
208-
objData := map[string]interface{}{}
209-
210-
jsonErr := json.Unmarshal(data, &objData)
211-
if jsonErr != nil {
212-
memLogger.Info(jsonErr.Error())
213-
return
214-
}
215-
216-
for i, item := range s.data[obj.Name] {
217-
if objData["name"] == item["name"] {
218-
s.data[obj.Name][i] = objData
219-
break
220-
}
221-
}
222-
223202
_, _ = w.Write(data)
224203
} else {
225204
memLogger.Info("failed to read from body", "error", err)
@@ -230,7 +209,7 @@ func (s *inMemoryServer) startObject(obj Object) {
230209
})
231210

232211
// handle a single object
233-
s.mux.HandleFunc(fmt.Sprintf("/%s/{name:[a-z]+}", obj.Name), func(w http.ResponseWriter, req *http.Request) {
212+
s.mux.HandleFunc(fmt.Sprintf("/%s/{name}", obj.Name), func(w http.ResponseWriter, req *http.Request) {
234213
w.Header().Set(util.ContentType, util.JSON)
235214
objects := s.data[obj.Name]
236215
if objects != nil {
@@ -253,6 +232,23 @@ func (s *inMemoryServer) startObject(obj Object) {
253232
switch method {
254233
case http.MethodGet:
255234
writeResponse(w, data, nil)
235+
case http.MethodPut:
236+
objData := map[string]interface{}{}
237+
if data, err := io.ReadAll(req.Body); err == nil {
238+
239+
jsonErr := json.Unmarshal(data, &objData)
240+
if jsonErr != nil {
241+
memLogger.Info(jsonErr.Error())
242+
return
243+
}
244+
for i, item := range s.data[obj.Name] {
245+
if item["name"] == name {
246+
s.data[obj.Name][i] = objData
247+
break
248+
}
249+
}
250+
_, _ = w.Write(data)
251+
}
256252
case http.MethodDelete:
257253
for i, item := range s.data[obj.Name] {
258254
if item["name"] == name {

0 commit comments

Comments
 (0)