11 "github.com/stretchr/testify/assert"
12 "github.com/stretchr/testify/require"
15 var allTestsFilter = func(_, _ string) (bool, error) { return true, nil }
16 var matchMethod = flag.String("testify.m", "", "regular expression to select tests of the testify suite to run")
18 // Suite is a basic testing suite with methods for storing and
19 // retrieving the current *testing.T context.
22 require *require.Assertions
26 // T retrieves the current *testing.T context.
27 func (suite *Suite) T() *testing.T {
31 // SetT sets the current *testing.T context.
32 func (suite *Suite) SetT(t *testing.T) {
34 suite.Assertions = assert.New(t)
35 suite.require = require.New(t)
38 // Require returns a require context for suite.
39 func (suite *Suite) Require() *require.Assertions {
40 if suite.require == nil {
41 suite.require = require.New(suite.T())
46 // Assert returns an assert context for suite. Normally, you can call
47 // `suite.NoError(expected, actual)`, but for situations where the embedded
48 // methods are overridden (for example, you might want to override
49 // assert.Assertions with require.Assertions), this method is provided so you
50 // can call `suite.Assert().NoError()`.
51 func (suite *Suite) Assert() *assert.Assertions {
52 if suite.Assertions == nil {
53 suite.Assertions = assert.New(suite.T())
55 return suite.Assertions
58 // Run takes a testing suite and runs all of the tests attached
60 func Run(t *testing.T, suite TestingSuite) {
63 if setupAllSuite, ok := suite.(SetupAllSuite); ok {
64 setupAllSuite.SetupSuite()
67 if tearDownAllSuite, ok := suite.(TearDownAllSuite); ok {
68 tearDownAllSuite.TearDownSuite()
72 methodFinder := reflect.TypeOf(suite)
73 tests := []testing.InternalTest{}
74 for index := 0; index < methodFinder.NumMethod(); index++ {
75 method := methodFinder.Method(index)
76 ok, err := methodFilter(method.Name)
78 fmt.Fprintf(os.Stderr, "testify: invalid regexp for -m: %s\n", err)
82 test := testing.InternalTest{
84 F: func(t *testing.T) {
87 if setupTestSuite, ok := suite.(SetupTestSuite); ok {
88 setupTestSuite.SetupTest()
90 if beforeTestSuite, ok := suite.(BeforeTest); ok {
91 beforeTestSuite.BeforeTest(methodFinder.Elem().Name(), method.Name)
94 if afterTestSuite, ok := suite.(AfterTest); ok {
95 afterTestSuite.AfterTest(methodFinder.Elem().Name(), method.Name)
97 if tearDownTestSuite, ok := suite.(TearDownTestSuite); ok {
98 tearDownTestSuite.TearDownTest()
102 method.Func.Call([]reflect.Value{reflect.ValueOf(suite)})
105 tests = append(tests, test)
111 func runTests(t testing.TB, tests []testing.InternalTest) {
113 if !ok { // backwards compatibility with Go 1.6 and below
114 if !testing.RunTests(allTestsFilter, tests) {
120 for _, test := range tests {
121 r.Run(test.Name, test.F)
125 // Filtering method according to set regular expression
126 // specified command-line argument -m
127 func methodFilter(name string) (bool, error) {
128 if ok, _ := regexp.MatchString("^Test", name); !ok {
131 return regexp.MatchString(*matchMethod, name)
134 type runner interface {
135 Run(name string, f func(t *testing.T)) bool