golang基础断言库与原生测试结合插件库assert的使用
golang基础断言库与原生测试结合插件库assert的使用
包简介
Package assert是一个基础断言库,用于与原生Go测试结合使用。
安装
使用go get安装:
go get github.com/go-playground/assert
然后在你的代码中导入assert包:
import . "github.com/go-playground/assert/v2"
使用示例
下面是一个完整的使用示例,展示了如何在Go测试中使用assert库:
package whatever
import (
"errors"
"testing"
. "github.com/go-playground/assert/v2"
)
// 自定义错误处理断言函数
func AssertCustomErrorHandler(t testing.TB, errs map[string]string, key, expected string) {
val, ok := errs[key]
// 使用EqualSkip和NotEqualSkip作为构建自定义Assert函数的基石
EqualSkip(t, 2, ok, true)
NotEqualSkip(t, 2, val, nil)
EqualSkip(t, 2, val, expected)
}
func TestEqual(t *testing.T) {
// 测试错误断言
err := errors.New("my error")
NotEqual(t, err, nil) // 断言err不等于nil
Equal(t, err.Error(), "my error") // 断言错误消息匹配
err = nil
Equal(t, err, nil) // 断言err等于nil
// 测试panic断言
fn := func() {
panic("omg omg omg!")
}
PanicMatches(t, func() { fn() }, "omg omg omg!") // 断言函数会panic且消息匹配
PanicMatches(t, func() { panic("omg omg omg!") }, "omg omg omg!")
// 测试自定义断言函数
errs := map[string]string{}
errs["Name"] = "User Name Invalid"
errs["Email"] = "User Email Invalid"
AssertCustomErrorHandler(t, errs, "Name", "User Name Invalid")
AssertCustomErrorHandler(t, errs, "Email", "User Email Invalid")
}
主要功能说明
-
基本断言:
Equal(t, a, b)
- 断言a等于bNotEqual(t, a, b)
- 断言a不等于b
-
错误处理:
- 可以断言错误是否为nil
- 可以断言错误消息是否匹配预期
-
Panic测试:
PanicMatches(t, func(), expected)
- 断言函数会panic且panic消息匹配预期
-
自定义断言:
- 可以使用
EqualSkip
和NotEqualSkip
等基础函数构建更复杂的自定义断言函数
- 可以使用
贡献指南
欢迎提交PR贡献代码。如果你创建了有用的自定义断言函数,强烈建议你贡献它们,帮助完善这个包。
许可证
该包基于MIT许可证分发,更多细节请查看代码中的许可证文件。
更多关于golang基础断言库与原生测试结合插件库assert的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang基础断言库与原生测试结合插件库assert的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang 测试:基础断言与 assert 库使用指南
在 Go 语言中,标准库提供了基础的测试功能,但有时我们需要更强大的断言功能来简化测试代码。下面我将介绍 Go 原生测试方法和流行的第三方断言库 stretchr/testify/assert
的使用。
1. 原生测试方法
Go 标准库 testing
提供了基础的测试功能,但没有内置断言函数,通常使用 if 判断:
package main
import (
"testing"
)
func Add(a, b int) int {
return a + b
}
func TestAdd(t *testing.T) {
result := Add(2, 3)
expected := 5
// 原生测试方式
if result != expected {
t.Errorf("Add(2, 3) = %d; want %d", result, expected)
}
// 表驱动测试
tests := []struct {
a, b, expected int
}{
{1, 2, 3},
{0, 0, 0},
{-1, 1, 0},
}
for _, tt := range tests {
if got := Add(tt.a, tt.b); got != tt.expected {
t.Errorf("Add(%d, %d) = %d; want %d", tt.a, tt.b, got, tt.expected)
}
}
}
2. 使用 testify/assert 库
testify
是一个流行的测试工具包,其中 assert
子包提供了丰富的断言函数。
安装
go get github.com/stretchr/testify/assert
基本用法
package main
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestAddWithAssert(t *testing.T) {
result := Add(2, 3)
// 基本断言
assert.Equal(t, 5, result, "它们应该相等")
// 不相等断言
assert.NotEqual(t, 6, result)
// nil 断言
var nilVar *int
assert.Nil(t, nilVar)
// 非 nil 断言
notNilVar := 1
assert.NotNil(t, ¬NilVar)
// 真值断言
assert.True(t, result > 0)
// 假值断言
assert.False(t, result < 0)
// 包含断言 (适用于字符串、数组、map等)
assert.Contains(t, "Hello World", "World")
assert.Contains(t, []int{1,2,3}, 2)
// 长度断言
assert.Len(t, []int{1,2,3}, 3)
// 错误断言
err := someFunctionThatReturnsError()
assert.Error(t, err)
// 无错误断言
noErr := someFunctionThatReturnsNoError()
assert.NoError(t, noErr)
// 近似相等 (适用于浮点数)
assert.InDelta(t, 0.5, 0.1+0.4, 0.0001)
}
高级用法
func TestAdvancedAssertions(t *testing.T) {
// 正则匹配
assert.Regexp(t, `^[a-z]+\[[0-9]+\]$`, "adam[23]")
// JSON 相等
expected := `{"name":"John", "age":30}`
actual := `{"age":30, "name":"John"}`
assert.JSONEq(t, expected, actual)
// 元素匹配 (顺序无关)
expectedSlice := []int{1, 2, 3}
actualSlice := []int{3, 2, 1}
assert.ElementsMatch(t, expectedSlice, actualSlice)
// 文件存在
assert.FileExists(t, "/path/to/file")
// 目录存在
assert.DirExists(t, "/path/to/dir")
// 恐慌断言
assert.Panics(t, func() {
panic("test panic")
})
// 恐慌值断言
assert.PanicsWithValue(t, "test panic", func() {
panic("test panic")
})
}
3. 原生测试与 assert 库对比
特性 | 原生 testing 包 | testify/assert |
---|---|---|
断言语法 | 手动 if 判断 | 丰富的断言函数 |
错误信息 | 需要手动编写 | 自动生成 |
可读性 | 一般 | 优秀 |
功能丰富度 | 基础 | 全面 |
学习曲线 | 低 | 中等 |
依赖 | 无 | 需要安装 |
4. 最佳实践建议
- 小型项目:如果项目简单,原生 testing 包可能足够
- 中大型项目:推荐使用 assert 库提高测试可读性和开发效率
- 表驱动测试:结合 assert 库和表驱动测试可以获得最佳效果
- 错误信息:assert 库自动生成的错误信息通常足够详细
- 性能考虑:assert 库有轻微性能开销,但对大多数应用影响不大
// 结合表驱动测试和 assert 的示例
func TestTableDrivenWithAssert(t *testing.T) {
tests := []struct {
name string
a, b int
expected int
}{
{"positive numbers", 2, 3, 5},
{"zeros", 0, 0, 0},
{"negative numbers", -1, -2, -3},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.expected, Add(tt.a, tt.b))
})
}
}
通过使用 assert 库,你可以编写更简洁、更易读的测试代码,同时获得更详细的失败信息,这在调试复杂测试时特别有用。