Go static analyzer that reports where you forgot to call t.Helper()
.
First, install thelper
command via go get
.
$ go get github.com/ichiban/thelper/cmd/thelper
Then, run thelper
command at your package directory.
$ thelper ./...
/Users/ichiban/src/thelper/testdata/src/a/a_test.go:11:1: unmarked test helper: call t.Helper()
/Users/ichiban/src/thelper/testdata/src/a/a_test.go:25:1: unmarked test helper: call s.Helper()
First, install the package via go get
.
$ go get github.com/ichiban/thelper
Then, include thelper.Analyzer
in your checker.
package main
import (
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/multichecker"
"golang.org/x/tools/go/analysis/passes/nilfunc"
"golang.org/x/tools/go/analysis/passes/printf"
"golang.org/x/tools/go/analysis/passes/shift"
"github.com/ichiban/thelper"
)
func main() {
multichecker.Main(
// other analyzers of your choice
nilfunc.Analyzer,
printf.Analyzer,
shift.Analyzer,
thelper.Analyzer,
)
}
go test
shows FAILs with an unhelpful line number.
Let's take an example of a test with an unmarked test helper.
TestFoo(t)
fails because testChdir(t, "/this/directory/does/not/exist")
fails.
package b
import (
"os"
"testing"
)
func TestFoo(t *testing.T) {
defer testChdir(t, "/this/directory/does/not/exist")()
// ...
}
// https://speakerdeck.com/mitchellh/advanced-testing-with-go?slide=30
func testChdir(t *testing.T, dir string) func() {
old, err := os.Getwd()
if err != nil {
t.Fatalf("err: %s", err)
}
if err := os.Chdir(dir); err != nil {
t.Fatalf("err: %s", err) // b_test.go:22
}
return func() { os.Chdir(old) }
}
b_test.go:22
points to t.Fatalf("err: %s", err)
inside of testChDir()
which isn't so helpful to understand why the test failed.
$ go test
--- FAIL: TestFoo (0.00s)
b_test.go:22: err: chdir /this/directory/does/not/exist: no such file or directory
FAIL
exit status 1
FAIL github.com/ichiban/thelper/testdata/src/b 0.006s
By marking testChdir()
, we can get a meaningful line number.
package b
import (
"os"
"testing"
)
func TestFoo(t *testing.T) {
defer testChdir(t, "/this/directory/does/not/exist")() // b_test.go:9
// ...
}
// https://speakerdeck.com/mitchellh/advanced-testing-with-go?slide=30
func testChdir(t *testing.T, dir string) func() {
t.Helper()
old, err := os.Getwd()
if err != nil {
t.Fatalf("err: %s", err)
}
if err := os.Chdir(dir); err != nil {
t.Fatalf("err: %s", err)
}
return func() { os.Chdir(old) }
}
Now, b_test.go:9
points to defer testChdir(t, "/this/directory/does/not/exist")()
.
$ go test
--- FAIL: TestFoo (0.00s)
b_test.go:9: err: chdir /this/directory/does/not/exist: no such file or directory
FAIL
exit status 1
FAIL github.com/ichiban/thelper/testdata/src/b 0.006s
This project is licensed under the MIT License - see the LICENSE.md file for details
This package is based on ikawaha's idea and advices.