Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

suite: fix SetupSubTest and TearDownSubTest execution order #1471

19 changes: 10 additions & 9 deletions suite/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,20 @@ func failOnPanic(t *testing.T, r interface{}) {
func (suite *Suite) Run(name string, subtest func()) bool {
oldT := suite.T()

if setupSubTest, ok := suite.s.(SetupSubTest); ok {
setupSubTest.SetupSubTest()
}
return oldT.Run(name, func(t *testing.T) {
suite.SetT(t)
dolmen marked this conversation as resolved.
Show resolved Hide resolved
defer suite.SetT(oldT)

defer recoverAndFailOnPanic(t)

if setupSubTest, ok := suite.s.(SetupSubTest); ok {
setupSubTest.SetupSubTest()
}

defer func() {
suite.SetT(oldT)
if tearDownSubTest, ok := suite.s.(TearDownSubTest); ok {
tearDownSubTest.TearDownSubTest()
defer tearDownSubTest.TearDownSubTest()
}
}()

return oldT.Run(name, func(t *testing.T) {
suite.SetT(t)
subtest()
})
}
Expand Down
75 changes: 74 additions & 1 deletion suite/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ type SuiteTester struct {
SetupSubTestRunCount int
TearDownSubTestRunCount int

SetupSubTestNames []string
TearDownSubTestNames []string

SuiteNameBefore []string
TestNameBefore []string

Expand Down Expand Up @@ -258,10 +261,12 @@ func (suite *SuiteTester) TestSubtest() {
}

func (suite *SuiteTester) TearDownSubTest() {
suite.TearDownSubTestNames = append(suite.TearDownSubTestNames, suite.T().Name())
suite.TearDownSubTestRunCount++
}

func (suite *SuiteTester) SetupSubTest() {
suite.SetupSubTestNames = append(suite.SetupSubTestNames, suite.T().Name())
suite.SetupSubTestRunCount++
}

Expand Down Expand Up @@ -319,6 +324,12 @@ func TestRunSuite(t *testing.T) {
assert.Contains(t, suiteTester.TestNameBefore, "TestSkip")
assert.Contains(t, suiteTester.TestNameBefore, "TestSubtest")

assert.Contains(t, suiteTester.SetupSubTestNames, "TestRunSuite/TestSubtest/first")
assert.Contains(t, suiteTester.SetupSubTestNames, "TestRunSuite/TestSubtest/second")

assert.Contains(t, suiteTester.TearDownSubTestNames, "TestRunSuite/TestSubtest/first")
assert.Contains(t, suiteTester.TearDownSubTestNames, "TestRunSuite/TestSubtest/second")

for _, suiteName := range suiteTester.SuiteNameAfter {
assert.Equal(t, "SuiteTester", suiteName)
}
Expand Down Expand Up @@ -481,7 +492,7 @@ func (s *CallOrderSuite) SetupSuite() {

func (s *CallOrderSuite) TearDownSuite() {
s.call("TearDownSuite")
assert.Equal(s.T(), "SetupSuite;SetupTest;Test A;TearDownTest;SetupTest;Test B;TearDownTest;TearDownSuite", strings.Join(s.callOrder, ";"))
assert.Equal(s.T(), "SetupSuite;SetupTest;Test A;SetupSubTest;SubTest A1;TearDownSubTest;SetupSubTest;SubTest A2;TearDownSubTest;TearDownTest;SetupTest;Test B;SetupSubTest;SubTest B1;TearDownSubTest;SetupSubTest;SubTest B2;TearDownSubTest;TearDownTest;TearDownSuite", strings.Join(s.callOrder, ";"))
}
func (s *CallOrderSuite) SetupTest() {
s.call("SetupTest")
Expand All @@ -491,12 +502,32 @@ func (s *CallOrderSuite) TearDownTest() {
s.call("TearDownTest")
}

func (s *CallOrderSuite) SetupSubTest() {
s.call("SetupSubTest")
}

func (s *CallOrderSuite) TearDownSubTest() {
s.call("TearDownSubTest")
}

func (s *CallOrderSuite) Test_A() {
s.call("Test A")
s.Run("SubTest A1", func() {
s.call("SubTest A1")
})
s.Run("SubTest A2", func() {
s.call("SubTest A2")
})
}

func (s *CallOrderSuite) Test_B() {
s.call("Test B")
s.Run("SubTest B1", func() {
s.call("SubTest B1")
})
s.Run("SubTest B2", func() {
s.call("SubTest B2")
})
}

type suiteWithStats struct {
Expand Down Expand Up @@ -617,3 +648,45 @@ func (s *FailfastSuite) Test_B_Passes() {
s.call("Test B Passes")
s.Require().True(true)
}

type subtestPanicSuite struct {
Suite
inTearDownSuite bool
inTearDownTest bool
inTearDownSubTest bool
}

func (s *subtestPanicSuite) TearDownSuite() {
s.inTearDownSuite = true
}

func (s *subtestPanicSuite) TearDownTest() {
s.inTearDownTest = true
}

func (s *subtestPanicSuite) TearDownSubTest() {
s.inTearDownSubTest = true
}

func (s *subtestPanicSuite) TestSubtestPanic() {
s.Run("subtest", func() {
panic("panic")
})
}

func TestSubtestPanic(t *testing.T) {
suite := new(subtestPanicSuite)
ok := testing.RunTests(
allTestsFilter,
[]testing.InternalTest{{
Name: "TestSubtestPanic",
F: func(t *testing.T) {
Run(t, suite)
},
}},
)
assert.False(t, ok)
assert.True(t, suite.inTearDownSubTest)
assert.True(t, suite.inTearDownTest)
assert.True(t, suite.inTearDownSuite)
}