golang轻量级通用测试断言插件库be的使用
Golang轻量级通用测试断言插件库be的使用
简介
Be是一个Go语言的简约测试辅助库,灵感来源于Mat Ryer和Alex Edwards的工作。
特性
- 使用泛型实现简单易读的测试断言
- 内置常见情况的辅助函数,如
be.NilErr
和be.In
- 默认快速失败,但可通过
be.Relaxed(t)
轻松切换到宽松模式 - 提供testfile子包用于测试golden文件
- 无依赖:仅使用标准库
示例用法
基本相等性测试
// 测试两个不相等的字符串
be.Equal(t, "hello", "world") // 会失败
// t.Fatal("want: hello; got: world")
// 测试两个相等的字符串
be.Equal(t, "goodbye", "goodbye") // 通过
// 测试整数相等性
be.Equal(t, 200, resp.StatusCode)
be.Equal(t, tc.wantPtr, gotPtr)
// 测试不相等
be.Unequal(t, "hello", "world") // 通过
be.Unequal(t, "goodbye", "goodbye") // 会失败
// t.Fatal("got: goodbye")
切片相等性测试
s := []int{1, 2, 3}
be.AllEqual(t, []int{1, 2, 3}, s) // 通过
be.AllEqual(t, []int{3, 2, 1}, s) // 会失败
// t.Fatal("want: [3 2 1]; got: [1 2 3]")
错误处理
var err error
be.NilErr(t, err) // 通过
be.Nonzero(t, err) // 会失败
// t.Fatal("got: <nil>")
err = errors.New("(O_o)")
be.NilErr(t, err) // 会失败
// t.Fatal("got: (O_o)")
be.Nonzero(t, err) // 通过
子字符串检查
be.In(t, "world", "hello, world") // 通过
be.In(t, "World", "hello, world") // 会失败
// t.Fatal("World" not in "hello, world")
be.NotIn(t, "\x01", []byte("\a\b\x00\r\t")) // 通过
be.NotIn(t, "\x00", []byte("\a\b\x00\r\t")) // 会失败
// t.Fatal("\x00" in "\a\b\x00\r\t")
其他测试
be.True(t, o.IsValid())
be.True(t, len(pages) >= 20)
使用golden文件测试
// 为每个.txt文件启动一个子测试
testfile.Run(t, "testdata/*.txt", func(t *testing.T, path string) {
// 读取文件
input := testfile.Read(t, path)
// 进行一些转换
type myStruct struct{ Whatever string }
got := myStruct{strings.ToUpper(input)}
// 检查结构体是否与.json文件等效
wantFile := strings.TrimSuffix(path, ".txt") + ".json"
testfile.EqualJSON(t, wantFile, got)
// 如果不等效,
// 会将结构体输出到名为testdata/-failed-test-name.json的文件
})
设计理念
测试通常不应该失败。当它们失败时,失败应该是可重复的。因此,花大量时间编写好的测试消息是没有意义的。Be包的设计目的是简单地快速且安静地使测试失败,如果条件未满足,则引用失败测试的行号。
大多数测试只需要简单的相等性测试,由be.Equal
(用于可比较类型)、be.AllEqual
(用于可比较类型的切片)和be.DeepEqual
(依赖于reflect.DeepEqual
)处理。另一个常见的测试是字符串或字节切片应该包含或不包含某些子字符串,由be.In
和be.NotIn
处理。
更多关于golang轻量级通用测试断言插件库be的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang轻量级通用测试断言插件库be的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang轻量级测试断言库 be 使用指南
be 是一个轻量级的 Go 测试断言库,提供了简洁的 API 和友好的错误输出。下面我将详细介绍 be 的使用方法。
安装
go get github.com/smartystreets/assertions
基本用法
import (
"testing"
"github.com/smartystreets/assertions"
. "github.com/smartystreets/assertions"
)
func TestSomething(t *testing.T) {
a := assertions.New(t)
// 基本断言
a.So(1, ShouldEqual, 1)
a.So(1, ShouldNotEqual, 2)
// 布尔断言
a.So(true, ShouldBeTrue)
a.So(false, ShouldBeFalse)
// nil 检查
var nilPointer *int
a.So(nilPointer, ShouldBeNil)
// 类型检查
a.So("hello", ShouldHaveSameTypeAs, "")
// 集合检查
a.So([]int{1, 2, 3}, ShouldContain, 2)
a.So([]int{1, 2, 3}, ShouldNotContain, 4)
// 长度检查
a.So("hello", ShouldHaveLength, 5)
// 字符串匹配
a.So("hello world", ShouldStartWith, "hello")
a.So("hello world", ShouldEndWith, "world")
a.So("hello world", ShouldContainSubstring, "lo wo")
// 数值比较
a.So(10, ShouldBeGreaterThan, 5)
a.So(5, ShouldBeLessThan, 10)
a.So(10, ShouldBeBetween, 5, 15)
a.So(10, ShouldNotBeBetween, 11, 15)
// 时间比较
now := time.Now()
later := now.Add(time.Hour)
a.So(now, ShouldHappenBefore, later)
a.So(later, ShouldHappenAfter, now)
// 错误检查
err := fmt.Errorf("something went wrong")
a.So(err, ShouldNotBeNil)
// panic 检查
a.So(func() { panic("oops") }, ShouldPanic)
a.So(func() {}, ShouldNotPanic)
}
高级特性
自定义消息
a.So(1, ShouldEqual, 2, "expected 1 to equal 2")
组合断言
a.So("hello", ShouldNotBeEmpty, ShouldStartWith, "h", ShouldEndWith, "o")
JSON 断言
jsonStr := `{"name":"John","age":30}`
a.So(jsonStr, ShouldContainJSONKey, "name")
a.So(jsonStr, ShouldNotContainJSONKey, "address")
a.So(jsonStr, ShouldEqualJSON, `{"age":30,"name":"John"}`) // 顺序无关
文件系统断言
a.So("/path/to/file", ShouldBeAnExistingFile)
a.So("/path/to/dir", ShouldBeADirectory)
与标准 testing 包的对比
相比标准库的 testing
包,be 提供了:
- 更丰富的断言方法
- 更友好的错误输出
- 更简洁的语法
- 支持链式调用
- 更好的可读性
性能考虑
be 是一个轻量级库,对测试性能影响极小。但如果你在性能敏感的测试场景中,可以考虑:
- 避免在断言中做复杂的计算
- 对于性能测试,直接使用标准库的
testing.B
基准测试
最佳实践
- 为每个测试文件创建一个断言实例
- 使用有意义的断言消息
- 组合相关断言以提高可读性
- 避免过度断言 - 只测试你真正关心的内容
be 是一个简单但功能强大的断言库,可以帮助你编写更清晰、更易维护的测试代码。它的设计哲学是保持简单和直观,同时提供足够的灵活性来处理大多数测试场景。