golang JSON模式匹配测试插件库gomatch的使用
Golang JSON模式匹配测试插件库gomatch的使用
简介
Gomatch是一个用于测试JSON与模式匹配的Go语言库。它的主要目的是能够验证JSON,只关注给定测试用例中必需的部分,从而使测试更具表达性和更不容易出错。它可以用于单元测试和功能测试。
安装
go get github.com/jfilipczyk/gomatch
基本用法
actual := `
{
"id": 351,
"name": "John Smith",
"address": {
"city": "Boston"
}
}
`
expected := `
{
"id": "@number@",
"name": "John Smith",
"address": {
"city": "@string@"
}
}
`
// 创建默认的JSON匹配器
m := gomatch.NewDefaultJSONMatcher()
// 进行匹配
ok, err := m.Match(expected, actual)
if ok {
fmt.Printf("实际JSON匹配预期JSON")
} else {
fmt.Printf("实际JSON不匹配预期JSON: %s", err.Error())
}
可用模式
@string@
- 匹配任何字符串@number@
- 匹配任何数字@bool@
- 匹配布尔值@array@
- 匹配数组@uuid@
- 匹配UUID格式字符串@email@
- 匹配电子邮件格式字符串@wildcard@
- 通配符匹配@...@
- 无界数组或对象
无界模式
可以在数组末尾使用,以允许任何额外的数组元素:
[
"John Smith",
"Joe Doe",
"@...@"
]
也可以在对象末尾使用,以允许任何额外的键:
{
"id": 351,
"name": "John Smith",
"@...@": ""
}
Gherkin示例
Gomatch可以与GODOG等工具一起使用,目的是能够验证JSON响应,只关注给定场景中必需的部分。
Feature: 用户管理API
为了提供用户管理的GUI界面
作为前端开发人员
我需要能够创建、检索、更新和删除用户
Scenario: 获取按用户名升序排序的用户列表
Given 数据库包含以下用户:
| Username | Email |
| john.smith | john.smith@example.com |
| alvin34 | alvin34@example.com |
| mike1990 | mike.jones@example.com |
When 我发送"GET"请求到"/v1/users?sortBy=username&sortDir=asc"
Then 响应码应该是200
And 响应体应该匹配JSON:
"""
{
"items": [
{
"username": "alvin34",
"@...@": ""
},
{
"username": "john.smith",
"@...@": ""
},
{
"username": "mike1990",
"@...@": ""
}
],
"@...@": ""
}
"""
许可证
该库采用MIT许可证分发。请参阅LICENSE文件。
致谢
该库受到PHP Matcher的启发。
Logo
Go gopher由Renee French设计。Gomatch logo基于Takuya Ueda创建的gopher。根据Creative Commons 3.0 Attributions license授权。修改了Gopher的眼睛。
更多关于golang JSON模式匹配测试插件库gomatch的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang JSON模式匹配测试插件库gomatch的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang JSON模式匹配测试插件库gomatch的使用
gomatch是一个用于Go语言的JSON模式匹配库,它允许你定义JSON模式并验证JSON文档是否符合该模式。这个库在测试场景中特别有用,可以验证API响应是否符合预期的结构。
安装gomatch
go get github.com/gomatch/match
基本用法
1. 简单匹配
package main
import (
"fmt"
"encoding/json"
"github.com/gomatch/match"
)
func main() {
// 定义JSON模式
pattern := `{
"name": "string",
"age": "number",
"active": "boolean"
}`
// 要测试的JSON数据
data := `{
"name": "John Doe",
"age": 30,
"active": true
}`
// 解析模式
matcher, err := match.NewJSONMatcher(pattern)
if err != nil {
panic(err)
}
// 匹配数据
var jsonData interface{}
if err := json.Unmarshal([]byte(data), &jsonData); err != nil {
panic(err)
}
if ok, err := matcher.Match(jsonData); ok {
fmt.Println("JSON数据匹配模式")
} else {
fmt.Printf("不匹配: %v\n", err)
}
}
2. 高级模式匹配
gomatch支持更复杂的模式匹配:
package main
import (
"fmt"
"encoding/json"
"github.com/gomatch/match"
)
func main() {
// 更复杂的模式
pattern := `{
"id": "number",
"username": "string",
"email": "string?",
"roles": ["string+"],
"metadata": {
"createdAt": "string",
"updatedAt": "string?"
},
"*": "*"
}`
data := `{
"id": 123,
"username": "johndoe",
"roles": ["admin", "user"],
"metadata": {
"createdAt": "2023-01-01",
"updatedAt": "2023-01-02"
},
"extraField": "value"
}`
matcher, err := match.NewJSONMatcher(pattern)
if err != nil {
panic(err)
}
var jsonData interface{}
if err := json.Unmarshal([]byte(data), &jsonData); err != nil {
panic(err)
}
if ok, err := matcher.Match(jsonData); ok {
fmt.Println("匹配成功")
} else {
fmt.Printf("匹配失败: %v\n", err)
}
}
模式语法说明
gomatch支持以下模式语法:
-
基本类型:
"string"
- 字符串"number"
- 数字"boolean"
- 布尔值"null"
- null值"*"
- 任意类型
-
可选字段:
- 在类型后加
?
表示可选,如"string?"
- 在类型后加
-
数组:
["type"]
- 元素为指定类型的数组["type+"]
- 至少有一个元素的数组["type?"]
- 可能为空的数组
-
对象:
{"field": "type"}
- 指定字段和类型{"*": "*"}
- 允许任意额外字段
在测试中使用gomatch
在单元测试中,gomatch特别有用:
package main
import (
"testing"
"encoding/json"
"github.com/gomatch/match"
"github.com/stretchr/testify/assert"
)
func TestAPIResponse(t *testing.T) {
// 模拟API响应
apiResponse := `{
"status": "success",
"data": {
"users": [
{
"id": 1,
"name": "Alice"
},
{
"id": 2,
"name": "Bob"
}
],
"count": 2
}
}`
// 定义期望的模式
pattern := `{
"status": "string",
"data": {
"users": [{
"id": "number",
"name": "string"
}+],
"count": "number"
}
}`
matcher, err := match.NewJSONMatcher(pattern)
assert.NoError(t, err)
var responseData interface{}
err = json.Unmarshal([]byte(apiResponse), &responseData)
assert.NoError(t, err)
ok, err := matcher.Match(responseData)
assert.True(t, ok, "API响应不匹配期望的模式: %v", err)
}
自定义匹配器
gomatch还允许你创建自定义匹配器:
package main
import (
"fmt"
"github.com/gomatch/match"
"regexp"
)
type regexMatcher struct {
pattern *regexp.Regexp
}
func (m *regexMatcher) Match(value interface{}) (bool, error) {
s, ok := value.(string)
if !ok {
return false, nil
}
return m.pattern.MatchString(s), nil
}
func main() {
// 注册自定义匹配器
match.RegisterMatcher("email", func(arg string) (match.Matcher, error) {
return ®exMatcher{
pattern: regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`),
}, nil
})
// 使用自定义匹配器
pattern := `{
"name": "string",
"email": "email"
}`
data := `{
"name": "John Doe",
"email": "john@example.com"
}`
matcher, err := match.NewJSONMatcher(pattern)
if err != nil {
panic(err)
}
var jsonData interface{}
if err := json.Unmarshal([]byte(data), &jsonData); err != nil {
panic(err)
}
if ok, err := matcher.Match(jsonData); ok {
fmt.Println("匹配成功")
} else {
fmt.Printf("匹配失败: %v\n", err)
}
}
总结
gomatch是一个强大的JSON模式匹配库,特别适合在测试API响应时使用。它提供了:
- 简洁的模式定义语法
- 灵活的类型匹配
- 可选字段支持
- 数组和对象的复杂匹配
- 自定义匹配器扩展
通过使用gomatch,你可以确保你的JSON数据结构符合预期,而无需编写冗长的结构体比较代码。