Skip to content

Commit 3d99dec

Browse files
committed
Add support for extra filtering and -testify.r
1 parent 11522a0 commit 3d99dec

File tree

2 files changed

+192
-11
lines changed

2 files changed

+192
-11
lines changed

suite/suite.go

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717

1818
var allTestsFilter = func(_, _ string) (bool, error) { return true, nil }
1919
var matchMethod = flag.String("testify.m", "", "regular expression to select tests of the testify suite to run")
20+
var repeatItem = flag.Uint("testify.r", 1, "used to repeat each test multiple times without rerunning Setup/TearDownSuite")
2021

2122
// Suite is a basic testing suite with methods for storing and
2223
// retrieving the current *testing.T context.
@@ -119,6 +120,12 @@ func (suite *Suite) Run(name string, subtest func()) bool {
119120
// Run takes a testing suite and runs all of the tests attached
120121
// to it.
121122
func Run(t *testing.T, suite TestingSuite) {
123+
RunWithSkip(t, suite, func(_, _ string) bool { return false })
124+
}
125+
126+
// RunWithSkip takes a testing suite and a skip function allowing
127+
// for extra filtering on tests to be run
128+
func RunWithSkip(t *testing.T, suite TestingSuite, skip func(string, string) bool) {
122129
defer recoverAndFailOnPanic(t)
123130

124131
suite.SetT(t)
@@ -148,16 +155,8 @@ func Run(t *testing.T, suite TestingSuite) {
148155
continue
149156
}
150157

151-
if !suiteSetupDone {
152-
if stats != nil {
153-
stats.Start = time.Now()
154-
}
155-
156-
if setupAllSuite, ok := suite.(SetupAllSuite); ok {
157-
setupAllSuite.SetupSuite()
158-
}
159-
160-
suiteSetupDone = true
158+
if skip(suiteName, method.Name) {
159+
continue
161160
}
162161

163162
test := testing.InternalTest{
@@ -202,8 +201,24 @@ func Run(t *testing.T, suite TestingSuite) {
202201
method.Func.Call([]reflect.Value{reflect.ValueOf(suite)})
203202
},
204203
}
205-
tests = append(tests, test)
204+
205+
for i := uint(0); i < *repeatItem; i++ {
206+
tests = append(tests, test)
207+
}
208+
}
209+
210+
if len(tests) > 0 {
211+
if stats != nil {
212+
stats.Start = time.Now()
213+
}
214+
215+
if setupAllSuite, ok := suite.(SetupAllSuite); ok {
216+
setupAllSuite.SetupSuite()
217+
}
218+
219+
suiteSetupDone = true
206220
}
221+
207222
if suiteSetupDone {
208223
defer func() {
209224
if tearDownAllSuite, ok := suite.(TearDownAllSuite); ok {

suite/suite_test.go

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,3 +746,169 @@ func TestUnInitializedSuites(t *testing.T) {
746746
})
747747
})
748748
}
749+
750+
var register = map[string]bool{"SuiteTesterTestTwo": true}
751+
752+
func skip(suiteName, testName string) bool {
753+
return register[suiteName+testName]
754+
}
755+
756+
// TestRunSuiteWithSkip will be run by the 'go test' command, so within it, we
757+
// can run our suite using the Run(*testing.T, TestingSuite) function.
758+
func TestRunSuiteWithSkip(t *testing.T) {
759+
suiteTester := new(SuiteTester)
760+
RunWithSkip(t, suiteTester, skip)
761+
762+
// Normally, the test would end here. The following are simply
763+
// some assertions to ensure that the Run function is working as
764+
// intended - they are not part of the example.
765+
766+
// The suite was only run once, so the SetupSuite and TearDownSuite
767+
// methods should have each been run only once.
768+
assert.Equal(t, 1, suiteTester.SetupSuiteRunCount)
769+
assert.Equal(t, 1, suiteTester.TearDownSuiteRunCount)
770+
771+
assert.Len(t, suiteTester.SuiteNameAfter, 3)
772+
assert.Len(t, suiteTester.SuiteNameBefore, 3)
773+
assert.Len(t, suiteTester.TestNameAfter, 3)
774+
assert.Len(t, suiteTester.TestNameBefore, 3)
775+
776+
assert.Contains(t, suiteTester.TestNameAfter, "TestOne")
777+
assert.NotContains(t, suiteTester.TestNameAfter, "TestTwo")
778+
assert.Contains(t, suiteTester.TestNameAfter, "TestSkip")
779+
assert.Contains(t, suiteTester.TestNameAfter, "TestSubtest")
780+
781+
assert.Contains(t, suiteTester.TestNameBefore, "TestOne")
782+
assert.NotContains(t, suiteTester.TestNameBefore, "TestTwo")
783+
assert.Contains(t, suiteTester.TestNameBefore, "TestSkip")
784+
assert.Contains(t, suiteTester.TestNameBefore, "TestSubtest")
785+
786+
assert.Contains(t, suiteTester.SetupSubTestNames, "TestRunSuiteWithSkip/TestSubtest/first")
787+
assert.Contains(t, suiteTester.SetupSubTestNames, "TestRunSuiteWithSkip/TestSubtest/second")
788+
789+
assert.Contains(t, suiteTester.TearDownSubTestNames, "TestRunSuiteWithSkip/TestSubtest/first")
790+
assert.Contains(t, suiteTester.TearDownSubTestNames, "TestRunSuiteWithSkip/TestSubtest/second")
791+
792+
for _, suiteName := range suiteTester.SuiteNameAfter {
793+
assert.Equal(t, "SuiteTester", suiteName)
794+
}
795+
796+
for _, suiteName := range suiteTester.SuiteNameBefore {
797+
assert.Equal(t, "SuiteTester", suiteName)
798+
}
799+
800+
for _, when := range suiteTester.TimeAfter {
801+
assert.False(t, when.IsZero())
802+
}
803+
804+
for _, when := range suiteTester.TimeBefore {
805+
assert.False(t, when.IsZero())
806+
}
807+
808+
// There are four test methods (TestOne, TestTwo, TestSkip, and TestSubtest), so
809+
// the SetupTest and TearDownTest methods (which should be run once for
810+
// each test) should have been run four times.
811+
assert.Equal(t, 3, suiteTester.SetupTestRunCount)
812+
assert.Equal(t, 3, suiteTester.TearDownTestRunCount)
813+
814+
// Each test should have been run once.
815+
assert.Equal(t, 1, suiteTester.TestOneRunCount)
816+
assert.Equal(t, 0, suiteTester.TestTwoRunCount)
817+
assert.Equal(t, 1, suiteTester.TestSubtestRunCount)
818+
819+
assert.Equal(t, 2, suiteTester.TearDownSubTestRunCount)
820+
assert.Equal(t, 2, suiteTester.SetupSubTestRunCount)
821+
822+
// Methods that don't match the test method identifier shouldn't
823+
// have been run at all.
824+
assert.Equal(t, 0, suiteTester.NonTestMethodRunCount)
825+
826+
suiteSkipTester := new(SuiteSkipTester)
827+
Run(t, suiteSkipTester)
828+
829+
// The suite was only run once, so the SetupSuite and TearDownSuite
830+
// methods should have each been run only once, even though SetupSuite
831+
// called Skip()
832+
assert.Equal(t, 1, suiteSkipTester.SetupSuiteRunCount)
833+
assert.Equal(t, 1, suiteSkipTester.TearDownSuiteRunCount)
834+
835+
}
836+
837+
// TestRunSuiteWithSkip will be run by the 'go test' command, so within it, we
838+
// can run our suite using the Run(*testing.T, TestingSuite) function.
839+
func TestRunSuiteWithSkipAll(t *testing.T) {
840+
suiteTester := new(SuiteTester)
841+
RunWithSkip(t, suiteTester, func(_, _ string) bool { return true })
842+
843+
// Normally, the test would end here. The following are simply
844+
// some assertions to ensure that the Run function is working as
845+
// intended - they are not part of the example.
846+
847+
// The suite was only run once, so the SetupSuite and TearDownSuite
848+
// methods should have each been run only once.
849+
assert.Equal(t, 0, suiteTester.SetupSuiteRunCount)
850+
assert.Equal(t, 0, suiteTester.TearDownSuiteRunCount)
851+
852+
assert.Len(t, suiteTester.SuiteNameAfter, 0)
853+
assert.Len(t, suiteTester.SuiteNameBefore, 0)
854+
assert.Len(t, suiteTester.TestNameAfter, 0)
855+
assert.Len(t, suiteTester.TestNameBefore, 0)
856+
857+
assert.NotContains(t, suiteTester.TestNameAfter, "TestOne")
858+
assert.NotContains(t, suiteTester.TestNameAfter, "TestTwo")
859+
assert.NotContains(t, suiteTester.TestNameAfter, "TestSkip")
860+
assert.NotContains(t, suiteTester.TestNameAfter, "TestSubtest")
861+
862+
assert.NotContains(t, suiteTester.TestNameBefore, "TestOne")
863+
assert.NotContains(t, suiteTester.TestNameBefore, "TestTwo")
864+
assert.NotContains(t, suiteTester.TestNameBefore, "TestSkip")
865+
assert.NotContains(t, suiteTester.TestNameBefore, "TestSubtest")
866+
867+
assert.NotContains(t, suiteTester.SetupSubTestNames, "TestRunSuiteWithSkipAll/TestSubtest/first")
868+
assert.NotContains(t, suiteTester.SetupSubTestNames, "TestRunSuiteWithSkipAll/TestSubtest/second")
869+
870+
assert.NotContains(t, suiteTester.TearDownSubTestNames, "TestRunSuiteWithSkipAll/TestSubtest/first")
871+
assert.NotContains(t, suiteTester.TearDownSubTestNames, "TestRunSuiteWithSkipAll/TestSubtest/second")
872+
873+
for _, suiteName := range suiteTester.SuiteNameAfter {
874+
assert.Equal(t, "SuiteTester", suiteName)
875+
}
876+
877+
for _, suiteName := range suiteTester.SuiteNameBefore {
878+
assert.Equal(t, "SuiteTester", suiteName)
879+
}
880+
881+
for _, when := range suiteTester.TimeAfter {
882+
assert.False(t, when.IsZero())
883+
}
884+
885+
for _, when := range suiteTester.TimeBefore {
886+
assert.False(t, when.IsZero())
887+
}
888+
889+
// There are four test methods (TestOne, TestTwo, TestSkip, and TestSubtest), so
890+
// the SetupTest and TearDownTest methods (which should be run once for
891+
// each test) should have been run four times.
892+
assert.Equal(t, 0, suiteTester.SetupTestRunCount)
893+
assert.Equal(t, 0, suiteTester.TearDownTestRunCount)
894+
895+
// Each test should have been run once.
896+
assert.Equal(t, 0, suiteTester.TestOneRunCount)
897+
assert.Equal(t, 0, suiteTester.TestTwoRunCount)
898+
assert.Equal(t, 0, suiteTester.TestSubtestRunCount)
899+
900+
assert.Equal(t, 0, suiteTester.TearDownSubTestRunCount)
901+
assert.Equal(t, 0, suiteTester.SetupSubTestRunCount)
902+
903+
// Methods that don't match the test method identifier shouldn't
904+
// have been run at all.
905+
assert.Equal(t, 0, suiteTester.NonTestMethodRunCount)
906+
907+
suiteSkipTester := new(SuiteSkipTester)
908+
Run(t, suiteSkipTester)
909+
910+
// All tests were skipped via skip function, so Setup/TearDownSuite should not run
911+
assert.Equal(t, 0, suiteSkipTester.SetupSuiteRunCount)
912+
assert.Equal(t, 0, suiteSkipTester.TearDownSuiteRunCount)
913+
914+
}

0 commit comments

Comments
 (0)