thelper

module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Dec 30, 2020 License: MIT

README

thelper

CI Go Report Card Coverage MIT License

thelper detects golang test helpers without t.Helper() call. Also, it checks the consistency of test helpers and has similar checks for benchmarks. Read futher to learn more.

Why?

Why I need to add t.Helper() into my helpers functions?

With this call go test prints correct lines of code for failed tests. Otherwise, printed lines will be inside helpers functions.

Compare (https://goplay.space/#I_pAJ-vWcRq):

func TestBad(t *testing.T) {
	testBad(t)
}

func testBad(t *testing.T) {
	t.Fatal("unhelpful line") // <--- output point this line
}

func TestGood(t *testing.T) {
	testGood(t) // <--- output point this line
}

func testGood(t *testing.T) {
	t.Helper()
	t.Fatal("clear output")
}
Why t.Helper() should begin my test helper function?

Why not? If you place it as the first call you unlikely add some assertion before.

Why I need to name *testing.T as t? Why it should be the first?

It adds more consistency into your code. When common variables have the same name and placed into the same position it simpler to understand and read.

Note that it is not a strong restriction to be the first. It can be the second to be compatible with context.Context param linting.

Installation

go get github.com/kulti/thelper/cmd/thelper

Usage

golangci-lint

golangci-lint supports thelper, so you can enable this linter and use it.

Shell

Check everything:

thelper ./...
Enable only required checks

If you run via golangci-lint look at .golangci.example.yml for an example of the configuration.

Otherwise you can run thelper with --checks command line argument. E.g. the following command checks that *testing.T is the first param and *testing.B has name b:

thelper --checks=t_first,b_name ./...
Available checks
  • t_begin - t.Helper() should begin helper function.
  • t_name - *testing.T should have name t.
  • t_first - *testing.T should be the first param of helper function.

The same for benchmarks:

  • b_begin - b.Helper() should begin helper function.
  • b_name - *testing.B should have name b.
  • b_first - *testing.B should be the first param of helper function.

Examples

Without t.Helper()
func TestSmth(t *testing.T) {
	checkSmth(t)
}

// Bad
func checkSmth(t *testing.T) {
	t.Fatal("check failed")
}

// Good
func checkSmth(t *testing.T) {
	t.Helper()
	t.Fatal("check failed")
}
With invalid name
// Bad
func checkSmth(tt *testing.T) {
    // ...
}

// Good
func checkSmth(t *testing.T) {
    // ...
}
With t as not the first param
// Bad
func checkSmth(doneCh <-chan struct{}, t *testing.T) {
    // ...
}

// Good
func checkSmth(t *testing.T, doneCh <-chan struct{}) {
    // ...
}

Directories

Path Synopsis
cmd
thelper command
pkg
scripts
generator command

Jump to

Keyboard shortcuts

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