Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions suite/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package suite

type runOptions struct {
testFilter func(testName string) (bool, error)
}

// RunOption sets optional run parameter to specific value.
type RunOption func(*runOptions)

// WithTestFilter replaces default filter function which passed via -m flag to custom function.
func WithTestFilter(testFilter func(testName string) (bool, error)) RunOption {
return func(opts *runOptions) {
opts.testFilter = testFilter
}
}

// WithIgnoreMatch ignores -m flag.
func WithIgnoreMatch() RunOption {
return func(opts *runOptions) {
opts.testFilter = func(testName string) (bool, error) {
return true, nil
}
}
}
30 changes: 18 additions & 12 deletions suite/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

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")
var matchTestRegex = regexp.MustCompile("^Test")

// Suite is a basic testing suite with methods for storing and
// retrieving the current *testing.T context.
Expand Down Expand Up @@ -80,13 +81,23 @@ func (suite *Suite) Run(name string, subtest func()) bool {

// Run takes a testing suite and runs all of the tests attached
// to it.
func Run(t *testing.T, suite TestingSuite) {
func Run(t *testing.T, suite TestingSuite, opts ...RunOption) {
defer failOnPanic(t)

suite.SetT(t)

var suiteSetupDone bool

var runOpts = &runOptions{
testFilter: func(testName string) (bool, error) {
return regexp.MatchString(*matchMethod, testName)
},
}

for _, opt := range opts {
opt(runOpts)
}

var stats *SuiteInformation
if _, ok := suite.(WithStats); ok {
stats = newSuiteInformation()
Expand All @@ -99,9 +110,13 @@ func Run(t *testing.T, suite TestingSuite) {
for i := 0; i < methodFinder.NumMethod(); i++ {
method := methodFinder.Method(i)

ok, err := methodFilter(method.Name)
if !matchTestRegex.MatchString(method.Name) {
continue
}

ok, err := runOpts.testFilter(method.Name)
if err != nil {
fmt.Fprintf(os.Stderr, "testify: invalid regexp for -m: %s\n", err)
fmt.Fprintf(os.Stderr, "testify: an error during apply filter: %v", err.Error())
os.Exit(1)
}

Expand Down Expand Up @@ -176,15 +191,6 @@ func Run(t *testing.T, suite TestingSuite) {
runTests(t, tests)
}

// Filtering method according to set regular expression
// specified command-line argument -m
func methodFilter(name string) (bool, error) {
if ok, _ := regexp.MatchString("^Test", name); !ok {
return false, nil
}
return regexp.MatchString(*matchMethod, name)
}

func runTests(t testing.TB, tests []testing.InternalTest) {
if len(tests) == 0 {
t.Log("warning: no tests to run")
Expand Down
30 changes: 30 additions & 0 deletions suite/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -587,3 +587,33 @@ func (s *FailfastSuite) Test_B_Passes() {
s.call("Test B Passes")
s.Require().True(true)
}

type childSuite struct {
Suite
done bool
}

func (s *childSuite) TestChild() {
s.done = true
}

type parentSuite struct {
Suite
}

func (p *parentSuite) Test1() {
var child = new(childSuite)
Run(p.T(), child, WithIgnoreMatch())
p.Require().True(child.done)
}

func (p *parentSuite) Test2() {
p.Require().FailNow("this test should be ingored due to passed -testify.m flag")
}

func TestSuiteRunsSuite(t *testing.T) {
matchMethod = new(string)
*matchMethod = "Test1"
var s parentSuite
Run(t, &s)
}