gotests is a powerful Go test generator that automatically creates table-driven tests from your source code. It analyzes function and method signatures to generate comprehensive test scaffolding, saving you time and ensuring consistency across your test suite.
- 🚀 Zero-config test generation - Works out of the box with any Go project
- 🎯 Smart test scaffolding - Generates complete table-driven test structure with proper type handling
- 🔧 Flexible filtering - Generate tests for specific functions, exported functions, or entire packages
- 📦 Auto-imports - Automatically adds required imports to test files
- 🧬 Full generics support - Works seamlessly with Go 1.18+ type parameters
- 🔄 Recursive generation - Process entire directory trees with
./...
pattern - 🎨 Custom templates - Built-in support for testify and custom test templates
- ⚡ Parallel subtests - Optional parallel test execution support
The following shows gotests
in action using the official Sublime Text 3 plugin. Plugins also exist for Emacs, also Emacs, Vim, Atom Editor, Visual Studio Code, and IntelliJ Goland.
Minimum Go version: Go 1.22
Use go install
to install and update:
$ go install github.com/cweill/gotests/gotests@latest
From the commandline, gotests
can generate Go tests for specific source files or an entire directory. By default, it prints its output to stdout
.
$ gotests [options] PATH ...
Available options:
-all generate tests for all functions and methods
-excl regexp. generate tests for functions and methods that don't
match. Takes precedence over -only, -exported, and -all
-exported generate tests for exported functions and methods. Takes
precedence over -only and -all
-i print test inputs in error messages
-named switch table tests from using slice to map (with test name for the key)
-only regexp. generate tests for functions and methods that match only.
Takes precedence over -all
-nosubtests disable subtest generation when >= Go 1.7
-parallel enable parallel subtest generation when >= Go 1.7.
-w write output to (test) files instead of stdout
-template_dir Path to a directory containing custom test code templates. Takes
precedence over -template. This can also be set via environment
variable GOTESTS_TEMPLATE_DIR
-template Specify custom test code templates, e.g. testify. This can also
be set via environment variable GOTESTS_TEMPLATE
-template_params_file read external parameters to template by json with file
-template_params read external parameters to template by json with stdin
-use_go_cmp use cmp.Equal (google/go-cmp) instead of reflect.DeepEqual
-version print version information and exit
Given a file math.go
:
package math
func Add(a, b int) int {
return a + b
}
Generate a test:
$ gotests -only Add -w math.go
This creates math_test.go
with:
func TestAdd(t *testing.T) {
type args struct {
a int
b int
}
tests := []struct {
name string
args args
want int
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Add(tt.args.a, tt.args.b); got != tt.want {
t.Errorf("Add() = %v, want %v", got, tt.want)
}
})
}
}
$ gotests -all -exported -w .
This generates tests for all exported functions in the current directory.
$ gotests -all -w ./...
This generates tests for all functions in the current directory and all subdirectories.
$ gotests -all -template testify -w calculator.go
This generates tests using the testify assertion library.
# Generate tests for all exported functions in a package
$ gotests -exported -w pkg/*.go
# Generate only tests for specific functions matching a pattern
$ gotests -only "^Process" -w handler.go
# Generate tests excluding certain functions
$ gotests -all -excl "^helper" -w utils.go
# Generate parallel subtests
$ gotests -all -parallel -w service.go
gotests
fully supports Go generics (type parameters) introduced in Go 1.18+. It automatically generates tests for generic functions and methods on generic types.
Given this generic function:
func FindFirst[T comparable](slice []T, target T) (int, error) {
for i, v := range slice {
if v == target {
return i, nil
}
}
return -1, ErrNotFound
}
Running gotests -all -w yourfile.go
generates:
func TestFindFirst(t *testing.T) {
type args struct {
slice []string
target string
}
tests := []struct {
name string
args args
want int
wantErr bool
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := FindFirst[string](tt.args.slice, tt.args.target)
if (err != nil) != tt.wantErr {
t.Errorf("FindFirst() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("FindFirst() = %v, want %v", got, tt.want)
}
})
}
}
gotests
also supports methods on generic types:
type Set[T comparable] struct {
m map[T]struct{}
}
func (s *Set[T]) Add(v T) {
if s.m == nil {
s.m = make(map[T]struct{})
}
s.m[v] = struct{}{}
}
Generates:
func TestSet_Add(t *testing.T) {
type args struct {
v string
}
tests := []struct {
name string
s *Set[string]
args args
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &Set[string]{}
s.Add(tt.args.v)
})
}
}
gotests
uses intelligent defaults for type parameter instantiation:
any
→int
comparable
→string
- Union types (
int64 | float64
) → first option (int64
) - Approximation constraints (
~int
) → underlying type (int
)
This ensures generated tests use appropriate concrete types for testing generic code.
Contributing guidelines are in CONTRIBUTING.md.
gotests
is released under the Apache 2.0 License.