stretchr/testify

GitHub: stretchr/testify

这是一个为 Go 语言开发提供断言、模拟对象和测试套件功能的工具包,旨在简化测试代码编写并提高可读性。

Stars: 25927 | Forks: 1699

# Testify - 汝当编写测试 [![构建状态](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/619dcb4727064010.svg)](https://github.com/stretchr/testify/actions/workflows/main.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/stretchr/testify)](https://goreportcard.com/report/github.com/stretchr/testify) [![PkgGoDev](https://pkg.go.dev/badge/github.com/stretchr/testify)](https://pkg.go.dev/github.com/stretchr/testify) Go 代码(golang)包集合,提供了许多工具来证明你的代码会按预期运行。 功能包括: * [简单的断言](#assert-package) * [模拟](#mock-package) * [测试套件接口和函数](#suite-package) 开始使用: * 使用 [一行代码](#installation) 安装 testify,或者 [用另一行代码更新它](#staying-up-to-date) * 有关在 Go 中编写测试代码的介绍,请参阅 https://go.dev/doc/code#Testing * 查看 API 文档 https://pkg.go.dev/github.com/stretchr/testify * 使用 [testifylint](https://github.com/Antonboom/testifylint)(通过 [golangci-lint](https://golangci-lint.run/))来避免常见错误 * 关于[测试驱动开发 (TDD)](https://en.wikipedia.org/wiki/Test-driven_development)的一点介绍 ## [`assert`](https://pkg.go.dev/github.com/stretchr/testify/assert "API documentation") 包 `assert` 包提供了一些有用的方法,允许你在 Go 中编写更好的测试代码。 * 打印友好、易读的失败描述 * 允许编写可读性很强的代码 * 可以选择为每个断言添加注释信息 查看实际效果: ``` package yours import ( "testing" "github.com/stretchr/testify/assert" ) func TestSomething(t *testing.T) { // assert equality assert.Equal(t, 123, 123, "they should be equal") // assert inequality assert.NotEqual(t, 123, 456, "they should not be equal") // assert for nil (good for errors) assert.Nil(t, object) // assert for not nil (good when you expect something) if assert.NotNil(t, object) { // now we know that object isn't nil, we are safe to make // further assertions without causing any errors assert.Equal(t, "Something", object.Value) } } ``` * 每个 assert 函数都将 `testing.T` 对象作为第一个参数。这就是它通过标准的 `go test` 功能输出错误的方式。 * 每个 assert 函数返回一个布尔值,指示断言是否成功,如果你想在特定条件下继续进行更多断言,这很有用。 如果你要进行多次断言,请使用以下方法: ``` package yours import ( "testing" "github.com/stretchr/testify/assert" ) func TestSomething(t *testing.T) { assert := assert.New(t) // assert equality assert.Equal(123, 123, "they should be equal") // assert inequality assert.NotEqual(123, 456, "they should not be equal") // assert for nil (good for errors) assert.Nil(object) // assert for not nil (good when you expect something) if assert.NotNil(object) { // now we know that object isn't nil, we are safe to make // further assertions without causing any errors assert.Equal("Something", object.Value) } } ``` ## [`require`](https://pkg.go.dev/github.com/stretchr/testify/require "API documentation") 包 `require` 包提供与 `assert` 包相同的全局函数,但它们不返回布尔结果,而是终止当前测试。 这些函数必须在运行测试或基准函数的 goroutine 中调用,而不是在测试期间创建的其他 goroutine 中调用。 否则可能会发生竞态条件。 有关详细信息,请参阅 [t.FailNow](https://pkg.go.dev/testing#T.FailNow)。 ## [`mock`](https://pkg.go.dev/github.com/stretchr/testify/mock "API documentation") 包 `mock` 包提供了一种机制,可以轻松编写模拟对象,在编写测试代码时可以用它们代替真实对象。 一个示例测试函数测试一段依赖于外部对象 `testObj` 的代码,可以设置预期(testify)并断言它们确实发生了: ``` package yours import ( "testing" "github.com/stretchr/testify/mock" ) /* Test objects */ // MyMockedObject is a mocked object that implements an interface // that describes an object that the code I am testing relies on. type MyMockedObject struct { mock.Mock } // DoSomething is a method on MyMockedObject that implements some interface // and just records the activity, and returns what the Mock object tells it to. // // In the real object, this method would do something useful, but since this // is a mocked object - we're just going to stub it out. // // NOTE: This method is not being tested here, code that uses this object is. func (m *MyMockedObject) DoSomething(number int) (bool, error) { args := m.Called(number) return args.Bool(0), args.Error(1) } /* Actual test functions */ // TestSomething is an example of how to use our test object to // make assertions about some target code we are testing. func TestSomething(t *testing.T) { // create an instance of our test object testObj := new(MyMockedObject) // set up expectations testObj.On("DoSomething", 123).Return(true, nil) // call the code we are testing targetFuncThatDoesSomethingWithObj(testObj) // assert that the expectations were met testObj.AssertExpectations(t) } // TestSomethingWithPlaceholder is a second example of how to use our test object to // make assertions about some target code we are testing. // This time using a placeholder. Placeholders might be used when the // data being passed in is normally dynamically generated and cannot be // predicted beforehand (eg. containing hashes that are time sensitive) func TestSomethingWithPlaceholder(t *testing.T) { // create an instance of our test object testObj := new(MyMockedObject) // set up expectations with a placeholder in the argument list testObj.On("DoSomething", mock.Anything).Return(true, nil) // call the code we are testing targetFuncThatDoesSomethingWithObj(testObj) // assert that the expectations were met testObj.AssertExpectations(t) } // TestSomethingElse2 is a third example that shows how you can use // the Unset method to cleanup handlers and then add new ones. func TestSomethingElse2(t *testing.T) { // create an instance of our test object testObj := new(MyMockedObject) // set up expectations with a placeholder in the argument list mockCall := testObj.On("DoSomething", mock.Anything).Return(true, nil) // call the code we are testing targetFuncThatDoesSomethingWithObj(testObj) // assert that the expectations were met testObj.AssertExpectations(t) // remove the handler now so we can add another one that takes precedence mockCall.Unset() // return false now instead of true testObj.On("DoSomething", mock.Anything).Return(false, nil) testObj.AssertExpectations(t) } ``` 有关如何编写模拟代码的更多信息,请查看 [`mock` 包的 API 文档](https://pkg.go.dev/github.com/stretchr/testify/mock)。 你也可以使用 [mockery 工具](https://vektra.github.io/mockery/latest/) 针对接口自动生成模拟代码,从而使使用模拟变得更加快捷。 ## [`suite`](https://pkg.go.dev/github.com/stretchr/testify/suite "API documentation") 包 `suite` 包提供了你可能从更常见的面向对象语言中熟悉的功能。使用它,你可以将测试套件构建为一个结构体,在结构体上构建 setup/teardown 方法和测试方法,并像往常一样使用 'go test' 运行它们。 下面的示例展示了一个套件: ``` // Basic imports import ( "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" ) // Define the suite, and absorb the built-in basic suite // functionality from testify - including a T() method which // returns the current testing context type ExampleTestSuite struct { suite.Suite VariableThatShouldStartAtFive int } // Make sure that VariableThatShouldStartAtFive is set to five // before each test func (suite *ExampleTestSuite) SetupTest() { suite.VariableThatShouldStartAtFive = 5 } // All methods that begin with "Test" are run as tests within a // suite. func (suite *ExampleTestSuite) TestExample() { assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive) } // In order for 'go test' to run this suite, we need to create // a normal test function and pass our suite to suite.Run func TestExampleTestSuite(t *testing.T) { suite.Run(t, new(ExampleTestSuite)) } ``` 要查看使用 suite 包提供的所有功能的更完整示例,请查看我们的 [示例测试套件](https://github.com/stretchr/testify/blob/master/suite/suite_test.go) 有关编写套件的更多信息,请查看 [`suite` 包的 API 文档](https://pkg.go.dev/github.com/stretchr/testify/suite)。 `Suite` 对象具有断言方法: ``` // Basic imports import ( "testing" "github.com/stretchr/testify/suite" ) // Define the suite, and absorb the built-in basic suite // functionality from testify - including assertion methods. type ExampleTestSuite struct { suite.Suite VariableThatShouldStartAtFive int } // Make sure that VariableThatShouldStartAtFive is set to five // before each test func (suite *ExampleTestSuite) SetupTest() { suite.VariableThatShouldStartAtFive = 5 } // All methods that begin with "Test" are run as tests within a // suite. func (suite *ExampleTestSuite) TestExample() { suite.Equal(suite.VariableThatShouldStartAtFive, 5) } // In order for 'go test' to run this suite, we need to create // a normal test function and pass our suite to suite.Run func TestExampleTestSuite(t *testing.T) { suite.Run(t, new(ExampleTestSuite)) } ``` # 安装 要安装 Testify,请使用 `go get`: ``` go get github.com/stretchr/testify ``` 这将使以下包可用: ``` github.com/stretchr/testify/assert github.com/stretchr/testify/require github.com/stretchr/testify/mock github.com/stretchr/testify/suite github.com/stretchr/testify/http (deprecated) ``` 使用此模板将 `testify/assert` 包导入到你的代码中: ``` package yours import ( "testing" "github.com/stretchr/testify/assert" ) func TestSomething(t *testing.T) { assert.True(t, true, "True is true!") } ``` # 保持最新 要将 Testify 更新到最新版本,请使用 `go get -u github.com/stretchr/testify`。 # 支持的 Go 版本 我们目前支持从 1.19 开始最新的主要 Go 版本。 # 许可证 本项目根据 MIT 许可证的条款获得许可。
标签:assert, DNS解析, EVTX分析, Golang, Go语言, mock, Mock框架, suite, TDD, 单元测试, 安全编程, 开源项目, 断言库, 日志审计, 测试套件, 测试工具, 测试辅助, 测试驱动开发, 程序破解, 软件开发