Help us shape the future of Go! Take the 2026 Go Developer Survey

testcomments

command module
v0.0.6 Latest Latest
Warning

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

Go to latest
Published: Aug 28, 2026 License: Apache-2.0 Imports: 2 Imported by: 0

README

Test Comments Lint

CI version

Go Lint that follows standards described in TestComments.

⬇️ Getting Started

Run it as a standalone linter

To install it, run:

go install github.com/manuelarte/testcomments@latest

And then use it with

testcomments [-equality-comparison.reflect=true|false] [-equality-comparison.equal=true|false]
[-got-before-want=true|false] [-identify-function=true|false]
[-table-driven-format.type=map|slice] [-table-driven-format.inlined=true|false] ./...

Parameters:

  • equality-comparison.reflect: true|false (default true) Checks reflect.DeepEqual can be replaced by newer cmp.Equal.
  • equality-comparison.equal: true|false (default true) Checks helper test functions to compare two structs that can be replaced by either cmp.Equal or cmp.Diff.
  • got-before-want: true|false (default true) Check that the failure message outputs the actual value that the function returned before printing the value that was expected.
  • identify-function: true|false (default true) Check that the failure messages in t.Errorf contains the function name.
  • table-driven-format.type: map|slice (default ``) Check that the table-driven tests are either Map or Slice, empty to leave it as it is.
  • table-driven-format.inlined: true|false (default false) Check that the table-driven tests are inlined in the for loop.
Run it as a module plugin in golangci-lint

You can integrate this linter with golangci-lint by using the module plugin.

Example of a custom-gcl.yml file that includes this linter:

version: v2.12.2
plugins:
  - module: "github.com/manuelarte/testcomments"
    import: "github.com/manuelarte/testcomments/plugin"
    version: v0.0.3

🚀 Features

Equality Comparison
Reflect

This linter detects the expression:

if !reflect.DeepEqual(got, want) {
	t.Errorf("MyFunction got %v, want %v", got, want)
}

And lint that the newer cmp.Equal or cmp.Diff should be used. For more use cases and examples, check equality-comparison.

[!NOTE] Suggested Fix can't be supported since it could potentially imply adding go-cmp dependency and reflect.DeepEqual can't be directly replaced by cmp.Equal or cmp.Diff.

Equal

This linter detects helper functions like:

func areEqual(a, b MyStruct) bool {
 return a.Name && b.Name && a.Surname == b.Surname
}

And propose to use cmp.Equal or cmp.Diff.

Got before Want

Test outputs should output the actual value that the function returned before printing the value that was expected. So prefer failure messages like YourFunc(%v) = %v, want %v over want: %v, got: %v.

[!NOTE] Suggested Fix can't be supported since it would imply changing the original failure message.

Identify The Function

In most tests, failure messages should include the name of the function that failed, even though it seems obvious from the name of the test function.

Prefer:

t.Errorf("YourFunc(%v) = %v, want %v", in, got, want)

and not:

t.Errorf("got %v, want %v", got, want)

[!NOTE] Suggested Fix may be supported.

Table-Driven Test Format

Feature that checks consistency when declaring your table-driven tests. The options are:

Map non-inlined
tests := map[string]struct {
	in int
	out int
} {
	"test1": {
		in: 1,
		out: 1,
	},
}
for name, test := range tests {
	t.Run(name, func(t *testing.T) {
		got := abs(test.in)
		if got != test.out {
			t.Errorf("abs(%d) = %d, want %d", test.in, got, test.out)
		}
	})
}
Map inlined
for name, test := range map[string]struct {
	in int
	out int
} {
	"test1": {
		in: 1,
		out: 1,
	},
} {
	t.Run(name, func(t *testing.T) {
		got := abs(test.in)
		if got != test.out {
			t.Errorf("abs(%d) = %d, want %d", test.in, got, test.out)
		}
	})
}
Slice non-inlined
tests := []struct {
	name string
	in int
	out int
} {
	{
		name: "test1",
		in: 1,
		out: 1,
	},
}
for _, test := range tests {
	t.Run(test.name, func(t *testing.T) {
		got := abs(test.in)
		if got != test.out {
			t.Errorf("abs(%d) = %d, want %d", test.in, got, test.out)
		}
	})
}
Slice inlined
for _, test := range []struct {
	name string
	in int
	out int
} {
	{
		name: "test1",
		in: 1,
		out: 1,
	},
} {
	t.Run(test.name, func(t *testing.T) {
		got := abs(test.in)
		if got != test.out {
			t.Errorf("abs(%d) = %d, want %d", test.in, got, test.out)
		}
	})
}

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
Package analyzer contains the analyzer with the business logic of this linter.
Package analyzer contains the analyzer with the business logic of this linter.
Package plugin add supports to adding this analyzer as a golangci-lint plugin.
Package plugin add supports to adding this analyzer as a golangci-lint plugin.

Jump to

Keyboard shortcuts

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