Skip to content

Commit

Permalink
Use Go 1.7 subtests so suites can properly nest
Browse files Browse the repository at this point in the history
This removes dependencies on Go Testing Internals and
also enables test methods within a suite to have subtests.

Fixes #346
  • Loading branch information
bayesianmind authored and ernesto-jimenez committed May 29, 2017
1 parent b8c9b4e commit 3104bf5
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 10 deletions.
21 changes: 18 additions & 3 deletions suite/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/stretchr/testify/require"
)

var allTestsFilter = func(_, _ string) (bool, error) { return true, nil }
var matchMethod = flag.String("testify.m", "", "regular expression to select tests of the testify suite to run")

// Suite is a basic testing suite with methods for storing and
Expand Down Expand Up @@ -104,10 +105,20 @@ func Run(t *testing.T, suite TestingSuite) {
tests = append(tests, test)
}
}
runTests(t, tests)
}

func runTests(t testing.TB, tests []testing.InternalTest) {
r, ok := t.(runner)
if !ok { // backwards compatibility with Go 1.6 and below
if !testing.RunTests(allTestsFilter, tests) {
t.Fail()
}
return
}

if !testing.RunTests(func(_, _ string) (bool, error) { return true, nil },
tests) {
t.Fail()
for _, test := range tests {
r.Run(test.Name, test.F)
}
}

Expand All @@ -119,3 +130,7 @@ func methodFilter(name string) (bool, error) {
}
return regexp.MatchString(*matchMethod, name)
}

type runner interface {
Run(name string, f func(t *testing.T)) bool
}
18 changes: 11 additions & 7 deletions suite/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

// SuiteRequireTwice is intended to test the usage of suite.Require in two
Expand All @@ -19,7 +20,7 @@ type SuiteRequireTwice struct{ Suite }
// A regression would result on these tests panicking rather than failing.
func TestSuiteRequireTwice(t *testing.T) {
ok := testing.RunTests(
func(_, _ string) (bool, error) { return true, nil },
allTestsFilter,
[]testing.InternalTest{{
Name: "TestSuiteRequireTwice",
F: func(t *testing.T) {
Expand Down Expand Up @@ -267,16 +268,19 @@ func (sc *StdoutCapture) StopCapture() (string, error) {
}

func TestSuiteLogging(t *testing.T) {
testT := testing.T{}

suiteLoggingTester := new(SuiteLoggingTester)

capture := StdoutCapture{}
internalTest := testing.InternalTest{
Name: "SomeTest",
F: func(subT *testing.T) {
Run(subT, suiteLoggingTester)
},
}
capture.StartCapture()
Run(&testT, suiteLoggingTester)
testing.RunTests(allTestsFilter, []testing.InternalTest{internalTest})
output, err := capture.StopCapture()

assert.Nil(t, err, "Got an error trying to capture stdout!")
require.NoError(t, err, "Got an error trying to capture stdout and stderr!")
require.NotEmpty(t, output, "output content must not be empty")

// Failed tests' output is always printed
assert.Contains(t, output, "TESTLOGFAIL")
Expand Down

1 comment on commit 3104bf5

@yiminc-zz
Copy link
Contributor

@yiminc-zz yiminc-zz commented on 3104bf5 Jun 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change breaks the parallel tests.
I would want the TearDownSuite() to be called after all tests run completed. This change breaks that and cause TearDownSuite() to be called right after SetupSuite() and before any tests runs.
Here is sample code to repro the bug:

type MyTestSuite struct {
	suite.Suite
}
func TestMySuite(t *testing.T) {
	suite.Run(t, new(MyTestSuite))
}
func (s *MyTestSuite) SetupSuite() {
	fmt.Println("SetupSuite")
}
func (s *MyTestSuite) TearDownSuite() {
	fmt.Println("TearDownSuite")
}
func (s *MyTestSuite) SetupTest() {
	s.T().Parallel()
	fmt.Println("SetupTest")
}
func (s *MyTestSuite) TearDownTest() {
	fmt.Println("TearDownTest")
}
func (s *MyTestSuite) Test_A() {
	time.Sleep(time.Second)
}
func (s *MyTestSuite) Test_B() {
	time.Sleep(time.Second * 2)
}

The output of above tests is:
SetupSuite
TearDownSuite
SetupTest
SetupTest
TearDownTest
TearDownTest

Please sign in to comment.