Add sub-tests to Suite (#1246)

Co-authored-by: Vadym Tishchenko <v.tishchenko@evopay.com.ua>
pull/1266/head^2
Vadym Tishchenko 2022-11-02 13:46:59 +02:00 committed by GitHub
parent b747d7c5f8
commit 1333b5d3bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 9 deletions

View File

@ -7,6 +7,7 @@ import "testing"
type TestingSuite interface { type TestingSuite interface {
T() *testing.T T() *testing.T
SetT(*testing.T) SetT(*testing.T)
SetS(suite TestingSuite)
} }
// SetupAllSuite has a SetupSuite method, which will run before the // SetupAllSuite has a SetupSuite method, which will run before the
@ -51,3 +52,15 @@ type AfterTest interface {
type WithStats interface { type WithStats interface {
HandleStats(suiteName string, stats *SuiteInformation) HandleStats(suiteName string, stats *SuiteInformation)
} }
// SetupSubTest has a SetupSubTest method, which will run before each
// subtest in the suite.
type SetupSubTest interface {
SetupSubTest()
}
// TearDownSubTest has a TearDownSubTest method, which will run after
// each subtest in the suite have been run.
type TearDownSubTest interface {
TearDownSubTest()
}

View File

@ -22,9 +22,13 @@ var matchMethod = flag.String("testify.m", "", "regular expression to select tes
// retrieving the current *testing.T context. // retrieving the current *testing.T context.
type Suite struct { type Suite struct {
*assert.Assertions *assert.Assertions
mu sync.RWMutex mu sync.RWMutex
require *require.Assertions require *require.Assertions
t *testing.T t *testing.T
// Parent suite to have access to the implemented methods of parent struct
s TestingSuite
} }
// T retrieves the current *testing.T context. // T retrieves the current *testing.T context.
@ -43,6 +47,12 @@ func (suite *Suite) SetT(t *testing.T) {
suite.require = require.New(t) suite.require = require.New(t)
} }
// SetS needs to set the current test suite as parent
// to get access to the parent methods
func (suite *Suite) SetS(s TestingSuite) {
suite.s = s
}
// Require returns a require context for suite. // Require returns a require context for suite.
func (suite *Suite) Require() *require.Assertions { func (suite *Suite) Require() *require.Assertions {
suite.mu.Lock() suite.mu.Lock()
@ -85,7 +95,18 @@ func failOnPanic(t *testing.T, r interface{}) {
// Provides compatibility with go test pkg -run TestSuite/TestName/SubTestName. // Provides compatibility with go test pkg -run TestSuite/TestName/SubTestName.
func (suite *Suite) Run(name string, subtest func()) bool { func (suite *Suite) Run(name string, subtest func()) bool {
oldT := suite.T() oldT := suite.T()
defer suite.SetT(oldT)
if setupSubTest, ok := suite.s.(SetupSubTest); ok {
setupSubTest.SetupSubTest()
}
defer func() {
suite.SetT(oldT)
if tearDownSubTest, ok := suite.s.(TearDownSubTest); ok {
tearDownSubTest.TearDownSubTest()
}
}()
return oldT.Run(name, func(t *testing.T) { return oldT.Run(name, func(t *testing.T) {
suite.SetT(t) suite.SetT(t)
subtest() subtest()
@ -98,6 +119,7 @@ func Run(t *testing.T, suite TestingSuite) {
defer recoverAndFailOnPanic(t) defer recoverAndFailOnPanic(t)
suite.SetT(t) suite.SetT(t)
suite.SetS(suite)
var suiteSetupDone bool var suiteSetupDone bool

View File

@ -151,14 +151,16 @@ type SuiteTester struct {
Suite Suite
// Keep counts of how many times each method is run. // Keep counts of how many times each method is run.
SetupSuiteRunCount int SetupSuiteRunCount int
TearDownSuiteRunCount int TearDownSuiteRunCount int
SetupTestRunCount int SetupTestRunCount int
TearDownTestRunCount int TearDownTestRunCount int
TestOneRunCount int TestOneRunCount int
TestTwoRunCount int TestTwoRunCount int
TestSubtestRunCount int TestSubtestRunCount int
NonTestMethodRunCount int NonTestMethodRunCount int
SetupSubTestRunCount int
TearDownSubTestRunCount int
SuiteNameBefore []string SuiteNameBefore []string
TestNameBefore []string TestNameBefore []string
@ -255,6 +257,14 @@ func (suite *SuiteTester) TestSubtest() {
} }
} }
func (suite *SuiteTester) TearDownSubTest() {
suite.TearDownSubTestRunCount++
}
func (suite *SuiteTester) SetupSubTest() {
suite.SetupSubTestRunCount++
}
type SuiteSkipTester struct { type SuiteSkipTester struct {
// Include our basic suite logic. // Include our basic suite logic.
Suite Suite
@ -336,6 +346,9 @@ func TestRunSuite(t *testing.T) {
assert.Equal(t, suiteTester.TestTwoRunCount, 1) assert.Equal(t, suiteTester.TestTwoRunCount, 1)
assert.Equal(t, suiteTester.TestSubtestRunCount, 1) assert.Equal(t, suiteTester.TestSubtestRunCount, 1)
assert.Equal(t, suiteTester.TearDownSubTestRunCount, 2)
assert.Equal(t, suiteTester.SetupSubTestRunCount, 2)
// Methods that don't match the test method identifier shouldn't // Methods that don't match the test method identifier shouldn't
// have been run at all. // have been run at all.
assert.Equal(t, suiteTester.NonTestMethodRunCount, 0) assert.Equal(t, suiteTester.NonTestMethodRunCount, 0)