Go 语言的 `testify` 测试框架是一个功能强大的工具,它扩展了 Go 的原生 `testing` 包,提供了更多的测试支持,如断言(assertions)、表驱动测试(table-driven tests)、模拟(mocking)等。以下是 `testify` 的使用指南:
### 安装
如果你的项目使用 Go Modules,可以通过以下命令安装 `testify`:
```sh
go get github.com/stretchr/testify
```
### 断言(Assertions)
`testify` 提供了多种断言函数,用于验证测试用例中的条件是否为真。以下是一些常用的断言函数:
- `assert.Equal(t, expected, actual, message)`:检查期望值与实际值是否相等。
- `assert.NotEqual(t, expected, actual, message)`:检查期望值与实际值是否不相等。
- `assert.Nil(t, object, message)`:检查对象是否为 `nil`。
- `assert.NotNil(t, object, message)`:检查对象是否不为 `nil`。
### 表驱动测试
表驱动测试是一种将多个测试用例整合到一个测试函数中的方法。你可以定义一个结构体切片,其中每个元素都包含测试的输入和期望的输出。然后在测试函数中遍历这个切片,对每个用例进行测试。
### 模拟(Mocking)
`testify` 允许你创建模拟对象来代替实际的对象,这样你就可以在不触发实际行为的情况下测试代码。这在测试需要与外部系统交互的代码时非常有用。
### 测试套件(Suite)
`testify` 的 `suite` 包提供了一种方法,允许你为测试套件设置和清理环境。你可以定义一个测试套件,其中包含多个测试用例,并且在每个测试用例之前和之后执行一些共同的代码。
### 使用示例
以下是使用 `testify` 的一个简单示例:
```go
package mypackage
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestMyFunction(t *testing.T) {
result := MyFunction(2)
assert.Equal(t, result, 4, "MyFunction should return 4 when called with 2")
}
func TestMyOtherFunction(t *testing.T) {
var myObject *MyType = nil
assert.Nil(t, myObject, "myObject should be nil")
}
func TestTableDriven(t *testing.T) {
assert := assert.New(t)
tests := []struct {
input int
expected int
}{
{2, 4},
{-1, 1},
{0, 2},
}
for _, test := range tests {
assert.Equal(MyFunction(test.input), test.expected)
}
}
```
### 运行测试
使用 `go test` 命令运行测试:
```sh
go test
```
如果你想要更详细的输出,可以加上 `-v` 标志:
```sh
go test -v
```
`testify` 是一个非常灵活和强大的测试框架,可以帮助你编写更可靠和可读的测试代码。通过上述的使用指南,你可以开始在你的 Go 项目中使用 `testify` 了。
我的测试用例
https://gitee.com/ichub/gonats.git
package gomsg
import (
"fmt"
"gitee.com/ichub/goconfig/common/base/baseutils/fileutils"
"gitee.com/ichub/goconfig/common/ichublog"
"gitee.com/ichub/godi/di/difactroy"
pageesdto "gitee.com/ichub/gomini/mini/general/query/pagees"
"gitee.com/ichub/gonats/gomini/gonats/goconsts"
"gitee.com/ichub/gonats/gomini/goutil"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/suite"
"sync"
"testing"
"time"
)
type TestGonatsMsgSuite struct {
suite.Suite
DiFactroy *difactroy.DiFactroy
rootdir string
}
func (self *TestGonatsMsgSuite) SetupTest() {
logrus.Info("difactry...")
ichublog.InitLogrus()
self.rootdir = fileutils.FindRootDir()
self.DiFactroy = difactroy.NewDiFactroy()
}
func TestGonatsMsgSuites(t *testing.T) {
suite.Run(t, new(TestGonatsMsgSuite))
}
func (self *TestGonatsMsgSuite) Test001_EqQueryMsg() {
var msg = FindBeanGonatsMsg()
msg.Body = self.makeReq()
msg.Domain = goconsts.DomainCms
msg.Topic = goconsts.Topic_DOMAIN_GENEAL_SyncES_CMS
msg.Action = goconsts.ES_ACTION_QUERY
goutil.Info(msg)
}
func (self *TestGonatsMsgSuite) Test002_GoMsgSimple() {
var msg = FindBeanGonatsMsg()
goutil.Info(msg) //goutil.Info(msg.Header)
}
func (self *TestGonatsMsgSuite) makeReq() *pageesdto.PageesRequest {
var esRequest = pageesdto.New()
esRequest.PageSize = 3
esRequest.IndexName = "ichub_sys_dept"
esRequest.Source = "dept_id,dept_name" //esRequest.EsTerm("dept_name", "kl")
return esRequest
}
func (self *TestGonatsMsgSuite) Test003_EsQueryResult() {
esQueryResult, err := self.makeReq().EsQueryResult()
if err != nil {
goutil.Error(err)
}
goutil.Info(esQueryResult.ToPrettyString(), self.makeReq())
}
// 指定结构体structName生成注册与注入代码
func (self *TestGonatsMsgSuite) Test006_MakeDiStru() {
self.DiFactroy.Rootdir = fileutils.FindRootDirGoMod()
self.DiFactroy.MakeDiStru("EventFrame")
}
// 生成所有, 继承baseentity的结果: 已经有不再生成!
func (self *TestGonatsMsgSuite) Test007_MakeDiAll() {
self.DiFactroy.MakeDiAll()
}
func (self *TestGonatsMsgSuite) Test008_MakeDiForce() {
self.DiFactroy.MakeDiAllForce(true)
}
func (self *TestGonatsMsgSuite) worker(id int, wg *sync.WaitGroup) {
defer wg.Done() // 通知主goroutine这个协程已经完成
fmt.Printf("Worker %d starting\n", id)
time.Sleep(time.Second) // 模拟工作
fmt.Printf("Worker %d done\n", id)
}
func (self *TestGonatsMsgSuite) Test009_cocurrent() {
var wg sync.WaitGroup
for i := 1; i <= 5; i++ {
wg.Add(1) // 增加WaitGroup的计数
go self.worker(i, &wg)
}
wg.Wait() // 等待所有协程完成
goutil.Info("All workers completed")
}
测试结果
DEBUG[2024-05-55 10:22:44]D:/go-ichub/go/gonats/gomini/goutil/go_log_init.go:49 gitee.com/ichub/gonats/gomini/goutil.InjectGoLog() inject
2024-05-05 10:22:44.436 [INFO] {
"header": {
"domain": "cms",
"topic": "GeneralEsSync.CMS",
"action": "query",
"msg_id": "c07d6d1c5a3a4c1595984222d1b8f109",
"seq_id": 7,
"object_id": "1714875764336106300",
"object_type": "GeneralEsSync.BIZ",
"msg_req": true
},
"body": {
"page_size": 3,
"current": 1,
"order_by": null,
"fields": null,
"index_name": "ichub_sys_dept",
"Source": "dept_id,dept_name"
}
}
--- PASS: TestGonatsMsgSuites/Test001_EqQueryMsg (0.10s)
PASS