golang JSON模式匹配测试插件库gomatch的使用

Golang JSON模式匹配测试插件库gomatch的使用

简介

Gomatch是一个用于测试JSON与模式匹配的Go语言库。它的主要目的是能够验证JSON,只关注给定测试用例中必需的部分,从而使测试更具表达性和更不容易出错。它可以用于单元测试和功能测试。

Gomatch Logo

安装

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

1 回复

更多关于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支持以下模式语法:

  1. 基本类型:

    • "string" - 字符串
    • "number" - 数字
    • "boolean" - 布尔值
    • "null" - null值
    • "*" - 任意类型
  2. 可选字段:

    • 在类型后加?表示可选,如"string?"
  3. 数组:

    • ["type"] - 元素为指定类型的数组
    • ["type+"] - 至少有一个元素的数组
    • ["type?"] - 可能为空的数组
  4. 对象:

    • {"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 &regexMatcher{
			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响应时使用。它提供了:

  1. 简洁的模式定义语法
  2. 灵活的类型匹配
  3. 可选字段支持
  4. 数组和对象的复杂匹配
  5. 自定义匹配器扩展

通过使用gomatch,你可以确保你的JSON数据结构符合预期,而无需编写冗长的结构体比较代码。

回到顶部