Gild up your tests
Gon-gild-on is a lightweight, flexible library for golden file testing in Go. It provides a clean, composable API for creating, reading, rendering, and validating golden files, with powerful template and diffing capabilities.
Golden files (or "snapshot testing") is a testing technique where the expected output of a test is stored in a file. During tests, the actual output is compared against the stored "golden" output. This approach is particularly useful for:
- Testing complex data structures with large outputs
- Validating text output, JSON responses, or any structured data
- Reducing boilerplate in tests that verify output hasn't changed
When to Use Golden Files?
- Expected output is large or complex
- Output has a stable structure but variable content
- Visual comparison of differences is helpful
- Changes to output should be explicitly acknowledged by updating the golden files
- Flexible Data Handling: Support for arbitrary Go values, JSON, and extensible data types
- Template Support: Use Go's
text/templatein your golden files with powerful template functions - Smart Diffs & Updates: Automatically update golden files while preserving templates
- Multiple Formatters: Format output as JSON, Go structs (via go-spew), and more
- Embeddable: Works with both regular files and
embed.FS - Extensible: Easily integrate with your existing testing workflow
go get github.com/Serjick/gon-gild-onpackage main
import (
"encoding/json"
"reflect"
"testing"
"github.com/Serjick/gon-gild-on/golden"
)
const fixture = `{
"name": "John",
"count": 42
}
`
func TestExample(t *testing.T) {
// Create a new FS for handling golden files
fs := golden.NewFS()
// Your test data
got := fixture
// Render golden file with actual data
want, err := fs.RenderFile(t, json.RawMessage(got))
if err != nil {
t.FailNow()
}
// Assert golden file and test data are equal
if !reflect.DeepEqual([]byte(got), want) {
t.FailNow()
}
// _, self, _, _ := runtime.Caller(0)
// fmt.Println(os.ReadFile(filepath.Dir(self) + "/testdata/golden/TestExample/golden.tmpl"))
// Output:
// {
// "name": "John",
// "count": 42
// }
// <nil>
}Run your tests with the -update flag to automatically update golden files:
go test -update ./...or use WithForceUpdate option.
This will update the golden files with the actual test data while template syntax may be preserved.
// Use current working directory
source := golden.NewSourceCwd()
fs := golden.NewFS(golden.WithFSSource(source))type Fmt func(string, ...any) string
func(f Fmt) Bytes(data any) ([]byte, error) {
return []byte(f("%#v", data)), nil
}
// Use a stdlib fmt formatter
formatter := Fmt(fmt.Sprintf)
fs := golden.NewFS(golden.WithFSFormatter(formatter))// Put golden files in a specific subdirectory
locator := golden.NewLocatorSubDir("api")
fs := golden.NewFS(golden.WithFSLocator(locator))// Create JSON data directly
jsonData := json.RawMessage(`{"key": "value"}`)
want, err := fs.RenderFile(t, jsonData)Golden comes with several extension packages:
gildedk8sapimachinery: Integration with Kubernetes apimachinery for JSON patchesgildedsergigodiff: Smart template diffing using sergi/go-diffgildedspew: Pretty-printing Go values using davecgh/go-spewgildedtestify: Template functions for assertions using stretchr/testify
import "github.com/Serjick/gon-gild-on/golden/gildedspew"
fs := golden.NewFS(golden.WithFSFormatter(gildedspew.NewFormatter()))import "github.com/Serjick/gon-gild-on/golden/gildedk8sapimachinery"
before := []byte(`{"key": "old"}`)
after := []byte(`{"key": "new", "added": true}`)
data := gildedk8sapimachinery.NewDataJSONMergePatch(before, after)import "github.com/Serjick/gon-gild-on/golden/gildedtestify"
fs := golden.NewFS(ogolden.WithFSTmplFuncFactory(gildedtestify.NewTmplFuncFactory()))With this you can use assertions in your templates:
"uuid": "{{ testifyUUID .Actual.uuid }}",
"timestamp": "{{ testifyTimeRFC3339Nano .Actual.timestamp }}"
"created_at": "{{ testifyTimeInTestcaseRange .Actual.created_at }}"
import "github.com/Serjick/gon-gild-on/golden/gildedsergigodiff"
fs := golden.NewFS(
golden.WithFSPreSaveHook(gildedsergigodiff.NewTextTemplateDiffMatchPatchPreSaveHook()),
)This preserves template expressions when updating golden files.
See the Go Reference for complete API documentation.
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License.