1Testify - Thou Shalt Write Tests
2================================
3
4ℹ️ We are working on testify v2 and would love to hear what you'd like to see in it, have your say here: https://cutt.ly/testify
5
6[](https://github.com/stretchr/testify/actions/workflows/main.yml) [](https://goreportcard.com/report/github.com/stretchr/testify) [](https://pkg.go.dev/github.com/stretchr/testify)
7
8Go code (golang) set of packages that provide many tools for testifying that your code will behave as you intend.
9
10Features include:
11
12 * [Easy assertions](#assert-package)
13 * [Mocking](#mock-package)
14 * [Testing suite interfaces and functions](#suite-package)
15
16Get started:
17
18 * Install testify with [one line of code](#installation), or [update it with another](#staying-up-to-date)
19 * For an introduction to writing test code in Go, see https://go.dev/doc/code#Testing
20 * Check out the API Documentation https://pkg.go.dev/github.com/stretchr/testify
21 * A little about [Test-Driven Development (TDD)](https://en.wikipedia.org/wiki/Test-driven_development)
22
23
24
25[`assert`](https://pkg.go.dev/github.com/stretchr/testify/assert "API documentation") package
26-------------------------------------------------------------------------------------------
27
28The `assert` package provides some helpful methods that allow you to write better test code in Go.
29
30 * Prints friendly, easy to read failure descriptions
31 * Allows for very readable code
32 * Optionally annotate each assertion with a message
33
34See it in action:
35
36```go
37package yours
38
39import (
40 "testing"
41 "github.com/stretchr/testify/assert"
42)
43
44func TestSomething(t *testing.T) {
45
46 // assert equality
47 assert.Equal(t, 123, 123, "they should be equal")
48
49 // assert inequality
50 assert.NotEqual(t, 123, 456, "they should not be equal")
51
52 // assert for nil (good for errors)
53 assert.Nil(t, object)
54
55 // assert for not nil (good when you expect something)
56 if assert.NotNil(t, object) {
57
58 // now we know that object isn't nil, we are safe to make
59 // further assertions without causing any errors
60 assert.Equal(t, "Something", object.Value)
61
62 }
63
64}
65```
66
67 * Every assert func takes the `testing.T` object as the first argument. This is how it writes the errors out through the normal `go test` capabilities.
68 * Every assert func returns a bool indicating whether the assertion was successful or not, this is useful for if you want to go on making further assertions under certain conditions.
69
70if you assert many times, use the below:
71
72```go
73package yours
74
75import (
76 "testing"
77 "github.com/stretchr/testify/assert"
78)
79
80func TestSomething(t *testing.T) {
81 assert := assert.New(t)
82
83 // assert equality
84 assert.Equal(123, 123, "they should be equal")
85
86 // assert inequality
87 assert.NotEqual(123, 456, "they should not be equal")
88
89 // assert for nil (good for errors)
90 assert.Nil(object)
91
92 // assert for not nil (good when you expect something)
93 if assert.NotNil(object) {
94
95 // now we know that object isn't nil, we are safe to make
96 // further assertions without causing any errors
97 assert.Equal("Something", object.Value)
98 }
99}
100```
101
102[`require`](https://pkg.go.dev/github.com/stretchr/testify/require "API documentation") package
103---------------------------------------------------------------------------------------------
104
105The `require` package provides same global functions as the `assert` package, but instead of returning a boolean result they terminate current test.
106These functions must be called from the goroutine running the test or benchmark function, not from other goroutines created during the test.
107Otherwise race conditions may occur.
108
109See [t.FailNow](https://pkg.go.dev/testing#T.FailNow) for details.
110
111[`mock`](https://pkg.go.dev/github.com/stretchr/testify/mock "API documentation") package
112----------------------------------------------------------------------------------------
113
114The `mock` package provides a mechanism for easily writing mock objects that can be used in place of real objects when writing test code.
115
116An example test function that tests a piece of code that relies on an external object `testObj`, can set up expectations (testify) and assert that they indeed happened:
117
118```go
119package yours
120
121import (
122 "testing"
123 "github.com/stretchr/testify/mock"
124)
125
126/*
127 Test objects
128*/
129
130// MyMockedObject is a mocked object that implements an interface
131// that describes an object that the code I am testing relies on.
132type MyMockedObject struct{
133 mock.Mock
134}
135
136// DoSomething is a method on MyMockedObject that implements some interface
137// and just records the activity, and returns what the Mock object tells it to.
138//
139// In the real object, this method would do something useful, but since this
140// is a mocked object - we're just going to stub it out.
141//
142// NOTE: This method is not being tested here, code that uses this object is.
143func (m *MyMockedObject) DoSomething(number int) (bool, error) {
144
145 args := m.Called(number)
146 return args.Bool(0), args.Error(1)
147
148}
149
150/*
151 Actual test functions
152*/
153
154// TestSomething is an example of how to use our test object to
155// make assertions about some target code we are testing.
156func TestSomething(t *testing.T) {
157
158 // create an instance of our test object
159 testObj := new(MyMockedObject)
160
161 // set up expectations
162 testObj.On("DoSomething", 123).Return(true, nil)
163
164 // call the code we are testing
165 targetFuncThatDoesSomethingWithObj(testObj)
166
167 // assert that the expectations were met
168 testObj.AssertExpectations(t)
169
170
171}
172
173// TestSomethingWithPlaceholder is a second example of how to use our test object to
174// make assertions about some target code we are testing.
175// This time using a placeholder. Placeholders might be used when the
176// data being passed in is normally dynamically generated and cannot be
177// predicted beforehand (eg. containing hashes that are time sensitive)
178func TestSomethingWithPlaceholder(t *testing.T) {
179
180 // create an instance of our test object
181 testObj := new(MyMockedObject)
182
183 // set up expectations with a placeholder in the argument list
184 testObj.On("DoSomething", mock.Anything).Return(true, nil)
185
186 // call the code we are testing
187 targetFuncThatDoesSomethingWithObj(testObj)
188
189 // assert that the expectations were met
190 testObj.AssertExpectations(t)
191
192
193}
194
195// TestSomethingElse2 is a third example that shows how you can use
196// the Unset method to cleanup handlers and then add new ones.
197func TestSomethingElse2(t *testing.T) {
198
199 // create an instance of our test object
200 testObj := new(MyMockedObject)
201
202 // set up expectations with a placeholder in the argument list
203 mockCall := testObj.On("DoSomething", mock.Anything).Return(true, nil)
204
205 // call the code we are testing
206 targetFuncThatDoesSomethingWithObj(testObj)
207
208 // assert that the expectations were met
209 testObj.AssertExpectations(t)
210
211 // remove the handler now so we can add another one that takes precedence
212 mockCall.Unset()
213
214 // return false now instead of true
215 testObj.On("DoSomething", mock.Anything).Return(false, nil)
216
217 testObj.AssertExpectations(t)
218}
219```
220
221For more information on how to write mock code, check out the [API documentation for the `mock` package](https://pkg.go.dev/github.com/stretchr/testify/mock).
222
223You can use the [mockery tool](https://vektra.github.io/mockery/latest/) to autogenerate the mock code against an interface as well, making using mocks much quicker.
224
225[`suite`](https://pkg.go.dev/github.com/stretchr/testify/suite "API documentation") package
226-----------------------------------------------------------------------------------------
227
228The `suite` package provides functionality that you might be used to from more common object-oriented languages. With it, you can build a testing suite as a struct, build setup/teardown methods and testing methods on your struct, and run them with 'go test' as per normal.
229
230An example suite is shown below:
231
232```go
233// Basic imports
234import (
235 "testing"
236 "github.com/stretchr/testify/assert"
237 "github.com/stretchr/testify/suite"
238)
239
240// Define the suite, and absorb the built-in basic suite
241// functionality from testify - including a T() method which
242// returns the current testing context
243type ExampleTestSuite struct {
244 suite.Suite
245 VariableThatShouldStartAtFive int
246}
247
248// Make sure that VariableThatShouldStartAtFive is set to five
249// before each test
250func (suite *ExampleTestSuite) SetupTest() {
251 suite.VariableThatShouldStartAtFive = 5
252}
253
254// All methods that begin with "Test" are run as tests within a
255// suite.
256func (suite *ExampleTestSuite) TestExample() {
257 assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive)
258}
259
260// In order for 'go test' to run this suite, we need to create
261// a normal test function and pass our suite to suite.Run
262func TestExampleTestSuite(t *testing.T) {
263 suite.Run(t, new(ExampleTestSuite))
264}
265```
266
267For a more complete example, using all of the functionality provided by the suite package, look at our [example testing suite](https://github.com/stretchr/testify/blob/master/suite/suite_test.go)
268
269For more information on writing suites, check out the [API documentation for the `suite` package](https://pkg.go.dev/github.com/stretchr/testify/suite).
270
271`Suite` object has assertion methods:
272
273```go
274// Basic imports
275import (
276 "testing"
277 "github.com/stretchr/testify/suite"
278)
279
280// Define the suite, and absorb the built-in basic suite
281// functionality from testify - including assertion methods.
282type ExampleTestSuite struct {
283 suite.Suite
284 VariableThatShouldStartAtFive int
285}
286
287// Make sure that VariableThatShouldStartAtFive is set to five
288// before each test
289func (suite *ExampleTestSuite) SetupTest() {
290 suite.VariableThatShouldStartAtFive = 5
291}
292
293// All methods that begin with "Test" are run as tests within a
294// suite.
295func (suite *ExampleTestSuite) TestExample() {
296 suite.Equal(suite.VariableThatShouldStartAtFive, 5)
297}
298
299// In order for 'go test' to run this suite, we need to create
300// a normal test function and pass our suite to suite.Run
301func TestExampleTestSuite(t *testing.T) {
302 suite.Run(t, new(ExampleTestSuite))
303}
304```
305
306------
307
308Installation
309============
310
311To install Testify, use `go get`:
312
313 go get github.com/stretchr/testify
314
315This will then make the following packages available to you:
316
317 github.com/stretchr/testify/assert
318 github.com/stretchr/testify/require
319 github.com/stretchr/testify/mock
320 github.com/stretchr/testify/suite
321 github.com/stretchr/testify/http (deprecated)
322
323Import the `testify/assert` package into your code using this template:
324
325```go
326package yours
327
328import (
329 "testing"
330 "github.com/stretchr/testify/assert"
331)
332
333func TestSomething(t *testing.T) {
334
335 assert.True(t, true, "True is true!")
336
337}
338```
339
340------
341
342Staying up to date
343==================
344
345To update Testify to the latest version, use `go get -u github.com/stretchr/testify`.
346
347------
348
349Supported go versions
350==================
351
352We currently support the most recent major Go versions from 1.19 onward.
353
354------
355
356Contributing
357============
358
359Please feel free to submit issues, fork the repository and send pull requests!
360
361When submitting an issue, we ask that you please include a complete test function that demonstrates the issue. Extra credit for those using Testify to write the test code that demonstrates it.
362
363Code generation is used. [Look for `Code generated with`](https://github.com/search?q=repo%3Astretchr%2Ftestify%20%22Code%20generated%20with%22&type=code) at the top of some files. Run `go generate ./...` to update generated files.
364
365We also chat on the [Gophers Slack](https://gophers.slack.com) group in the `#testify` and `#testify-dev` channels.
366
367------
368
369License
370=======
371
372This project is licensed under the terms of the MIT license.
View as plain text