thelper

package module
v0.0.0-...-8394b99 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 22, 2019 License: MIT Imports: 6 Imported by: 0

README

thelper

Go static analyzer that reports where you forgot to call t.Helper().

As a command

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()

As an analysis.Analyzer

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,
	)
}

What happens if I don't call t.Helper()?

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

License

This project is licensed under the MIT License - see the LICENSE.md file for details

Acknowledgments

This package is based on ikawaha's idea and advices.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Analyzer = &analysis.Analyzer{
	Name:     "thelper",
	Doc:      `report unmarked test helpers`,
	Requires: []*analysis.Analyzer{inspect.Analyzer},
	Run:      run,
}

Analyzer reports unmarked test helpers.

Functions

This section is empty.

Types

This section is empty.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL