autogold makes go test -update
automatically update your Go tests (golden files and Go values in e.g. foo_test.go
).
~5m introduction available on YouTube:
"It's 2021: you shouldn't have to update Go tests manually"
Write in a Go test:
import "github.com/hexops/autogold"
...
autogold.Equal(t, got)
go test -update
will now create/update a testdata/<test name>.golden
file for you automatically.
Write in a Go test:
want := autogold.Want("my_test", nil)
want.Equal(t, got)
go test -update
will automatically update the autogold.Want("my_test", ...)
call with the Go syntax for whatever value your test got
(complex Go struct, slices, strings, etc.)
Anytime your test produces a result that is unexpected, you'll get very nice diffs showing exactly what changed. It does this by converting values at runtime directly to a formatted Go AST, and using the same diffing library the Go language server uses:
--- FAIL: TestEqual (0.08s)
autogold.go:91: mismatch (-want +got):
--- want
+++ got
@@ -1 +1 @@
+&example.Baz{Name: "Jane", Age: 31}
Use table-driven Go subtests? autogold.Want
and go test -update
will automatically find and replace the nil
values for you:
func TestTime(t *testing.T) {
testCases := []struct {
gmt string
loc string
want autogold.Value
}{
{"12:31", "Europe/Zuri", autogold.Want("Europe", nil)},
{"12:31", "America/New_York", autogold.Want("America", nil)},
{"08:08", "Australia/Sydney", autogold.Want("Australia", nil)},
}
for _, tc := range testCases {
t.Run(tc.want.Name(), func(t *testing.T) {
loc, err := time.LoadLocation(tc.loc)
if err != nil {
t.Fatal("could not load location")
}
gmt, _ := time.Parse("15:04", tc.gmt)
got := gmt.In(loc).Format("15:04")
tc.want.Equal(t, got)
})
}
}
It works by finding the relevant autogold.Want("<unique name>", ...)
call below the named TestTime
function, and then replacing the nil
parameter (or anything that was there.)
Golden files are used by the Go authors for testing the standard library, the gofmt
tool, etc. and are a common pattern in the Go community for snapshot testing. See also "Testing with golden files in Go" - Chris Reeves
Golden files make the most sense when you'd otherwise have to write a complex multi-line string or large Go structure inline in your test, making it hard to read.
In most cases, you should prefer inline snapshots, subtest golden values, or traditional Go tests.
-update
should go at the end of your go test
command, otherwise for some reason stdout will be considered a terminal and color will be turned on for libraries like fatih/color. Example:
go test -count=1 -run TestSomething . -update
valast is used to produce Go syntax at runtime for the Go value you provide. If the default output is not to your liking, you have options:
- Pass a string to autogold: It will be formatted as a Go string for you in the resulting
.golden
file / in Go tests. - Use your own formatting (JSON, etc.): Make your
got
value of typeautogold.Raw("foobar")
, and it will be used as-is for.golden
files (not allowed with inline tests.) - Exclude unexported fields:
autogold.Equal(t, got, autogold.ExportedOnly())
- As is the case with
gofmt
, different Go versions may produce different formattings (although rare.) - Minor versions of autogold (e.g.
v1.0
,v1.1
) may alter the formatting of.golden
files, although we will be mindful of such changes. - Major versions of autogold (e.g.
v1
,v2
) will be used for any major changes in output that would be difficult to review (we expect this will be rare in practice.)
The following are alternatives to autogold, making note of the differences we found that let us to create autogold:
- github.com/xorcare/golden
- Supports
[]byte
inputs only, defers formatting to users. - Does not support inline snapshots / code updating.
- Supports
- github.com/sebdah/goldie
- Supports
[]byte
inputs only, provides helpers for JSON, XML, etc. - Does not support inline snapshots / code updating.
- Supports
- github.com/bradleyjkemp/cupaloy
- Works on
interface{}
inputs. - Uses inactive go-spew project to format Go structs.
- Does not support inline snapshots / code updating.
- Works on