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.Run: validate Test* methods signature #1512

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions suite/suite.go
Expand Up @@ -184,6 +184,11 @@ func Run(t *testing.T, suite TestingSuite) {
failOnPanic(t, r)
}()

if method.Type.NumIn() > 1 || method.Type.NumOut() > 0 {
msg := fmt.Sprintf("testify: suite method '%s' shouldn't have any arguments or returning values\n", method.Name)
panic(msg)
Copy link
Author

@Barugoo Barugoo Nov 30, 2023

Choose a reason for hiding this comment

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

Not sure about using panic here tho, seems appropriate to me, but i will appreciate if you take a look @dolmen

Copy link

@wvell wvell Nov 30, 2023

Choose a reason for hiding this comment

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

Isn't it better to use t.Error(msg)? Then you can directly see the TestMethod violating the contract. I find panic always quite hard to read.

Copy link
Author

@Barugoo Barugoo Nov 30, 2023

Choose a reason for hiding this comment

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

@wvell the motivation to add panic here instead of t.Error is the source of this condition. I.e. It is not the tested code returning unexpected result, but rather the programmer who messed up the signature of the Test* method itself. In that case panic is more fitting IMHO

Copy link

Choose a reason for hiding this comment

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

Yeah fair point, I just hate reading panics.

Thanks for putting in the work.

Copy link
Collaborator

@dolmen dolmen Mar 6, 2024

Choose a reason for hiding this comment

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

While I'm a strong advocate of panic to catch programmer's mistake, I think a panic is not appropriate in this case as the stack trace will not be useful to the user.

Instead Run is being called with *testing.T, so let's just use t.Fatal (or t.Fatalf) to report the issue.

However, the main problem with this implementation is that this check must be done much much earlier, line 151, just after the successful call to methodFilter.

}

if setupTestSuite, ok := suite.(SetupTestSuite); ok {
setupTestSuite.SetupTest()
}
Expand Down
41 changes: 41 additions & 0 deletions suite/suite_test.go
Expand Up @@ -402,6 +402,47 @@ func TestSkippingSuiteSetup(t *testing.T) {
assert.False(t, suiteTester.toreDown)
}

// This suite has no Test... methods. It's setup and teardown must be skipped.
type SuiteInvalidTestSignatureTester struct {
Suite

executedTestCount int

setUp bool
toreDown bool
}

func (s *SuiteInvalidTestSignatureTester) SetupSuite() {
s.setUp = true
}

func (s *SuiteInvalidTestSignatureTester) TestInvalidSignature(somearg string) interface{} {
s.executedTestCount++
return nil
}

func (s *SuiteInvalidTestSignatureTester) TearDownSuite() {
s.toreDown = true
}

func TestSuiteInvalidTestSignature(t *testing.T) {
suiteTester := new(SuiteInvalidTestSignatureTester)

ok := testing.RunTests(allTestsFilter, []testing.InternalTest{
{
Name: "invalid signature",
F: func(t *testing.T) {
Run(t, suiteTester)
},
},
})

require.False(t, ok)
assert.Zero(t, suiteTester.executedTestCount)
assert.True(t, suiteTester.setUp)
assert.True(t, suiteTester.toreDown)
}

func TestSuiteGetters(t *testing.T) {
suite := new(SuiteTester)
suite.SetT(t)
Expand Down