{"id":19865932,"url":"https://github.com/hexops/autogold","last_synced_at":"2025-05-02T05:32:06.623Z","repository":{"id":37410348,"uuid":"321579414","full_name":"hexops/autogold","owner":"hexops","description":"Automatically update your Go tests","archived":false,"fork":false,"pushed_at":"2025-02-19T05:03:16.000Z","size":131,"stargazers_count":292,"open_issues_count":10,"forks_count":17,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-05-01T04:35:57.132Z","etag":null,"topics":["go","golang","golang-package","golden","testing"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hexops.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"slimsag"}},"created_at":"2020-12-15T06:53:46.000Z","updated_at":"2025-04-26T07:16:51.000Z","dependencies_parsed_at":"2024-05-15T21:09:04.668Z","dependency_job_id":"5376d354-00ed-462e-8e3d-7b4f35b951b3","html_url":"https://github.com/hexops/autogold","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hexops%2Fautogold","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hexops%2Fautogold/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hexops%2Fautogold/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hexops%2Fautogold/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hexops","download_url":"https://codeload.github.com/hexops/autogold/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251992993,"owners_count":21677022,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","golang-package","golden","testing"],"created_at":"2024-11-12T15:24:35.111Z","updated_at":"2025-05-02T05:32:06.612Z","avatar_url":"https://github.com/hexops.png","language":"Go","readme":"# autogold - automatically update your Go tests \u003ca href=\"https://hexops.com\"\u003e\u003cimg align=\"right\" alt=\"Hexops logo\" src=\"https://raw.githubusercontent.com/hexops/media/master/readme.svg\"\u003e\u003c/img\u003e\u003c/a\u003e\n\n\u003ca href=\"https://pkg.go.dev/github.com/hexops/autogold\"\u003e\u003cimg src=\"https://pkg.go.dev/badge/badge/github.com/hexops/autogold.svg\" alt=\"Go Reference\" align=\"right\"\u003e\u003c/a\u003e\n  \n[![Go CI](https://github.com/hexops/autogold/workflows/Go%20CI/badge.svg)](https://github.com/hexops/autogold/actions) [![codecov](https://codecov.io/gh/hexops/autogold/branch/main/graph/badge.svg)](https://codecov.io/gh/hexops/autogold) [![Go Report Card](https://goreportcard.com/badge/github.com/hexops/autogold)](https://goreportcard.com/report/github.com/hexops/autogold)\n\nautogold makes `go test -update` automatically update your Go tests (golden files and Go values in e.g. `foo_test.go`).\n\n## Installation\n\n```sh\ngo get -u github.com/hexops/autogold/v2\n```\n\n## Automatic golden files\n\nWrite in a Go test:\n\n```Go\nimport \"github.com/hexops/autogold/v2\"\n...\nautogold.ExpectFile(t, got)\n```\n\n`go test -update` will now create/update a `testdata/\u003ctest name\u003e.golden` file for you automatically. If your tests change over time you can use `go test -update -clean` to also have it remove _unused_ golden files.\n\n## Automatic inline test updating\n\nIn a Go test, simply call `autogold.Expect(want).Equal(t, got)`, passing `nil` as the value you `want` initially:\n\n```Go\nfunc TestFoo(t *testing.T) {\n\t...\n\tautogold.Expect(nil).Equal(t, got)\n}\n```\n\nRun `go test -update` and autogold will automatically update the `autogold.Expect(want)` Go syntax with the actual value your test `got`. It works with complex Go structs, slices, strings, etc.\n\n## Diffs\n\nAnytime your test produces a result that is unexpected, you'll get a nice diff showing exactly what changed. It does this by [converting values at runtime directly to a formatted Go AST](https://github.com/hexops/valast), and using the same [diffing library the Go language server uses](https://github.com/hexops/gotextdiff):\n\n```\n--- FAIL: TestFoo (0.08s)\n    autogold.go:91: mismatch (-want +got):\n        --- want\n        +++ got\n        @@ -1 +1 @@\n        +\u0026example.Baz{Name: \"Jane\", Age: 31}\n```\n\n## Subtesting\n\n[Table-driven Go subtests](https://blog.golang.org/subtests) are supported nicely as you can call `.Equal(got)` later, so that `go test -update` will update your table-driven test values defined earlier for you:\n\n```Go\nfunc TestTime(t *testing.T) {\n\ttestCases := []struct {\n\t\tgmt    string\n\t\tloc    string\n\t\texpect autogold.Value // autogold: the value we expect\n\t}{\n\t\t{\"12:31\", \"Europe/Zuri\", autogold.Expect(nil)},\n\t\t{\"12:31\", \"America/New_York\", autogold.Expect(nil)},\n\t\t{\"08:08\", \"Australia/Sydney\", autogold.Expect(nil)},\n\t}\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.loc, func(t *testing.T) {\n\t\t\tloc, err := time.LoadLocation(tc.loc)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(\"could not load location\")\n\t\t\t}\n\t\t\tgmt, _ := time.Parse(\"15:04\", tc.gmt)\n\t\t\tgot := gmt.In(loc).Format(\"15:04\")\n\n\t\t\ttc.expect.Equal(t, got) // autogold: tell it the value our test produced\n\t\t})\n\t}\n}\n```\n\nIt works by finding the relevant `autogold.Expect(want)` call for you based on callstack information / matching line number in the file, and then rewrites the `nil` parameter (or any other value that was there.)\n\n## What are golden files, when should they be used?\n\nGolden files are used by the Go authors for testing [the standard library](https://golang.org/src/go/doc/doc_test.go), the [`gofmt` tool](https://github.com/golang/go/blob/master/src/cmd/gofmt/gofmt_test.go#L124-L130), etc. and are a common pattern in the Go community for snapshot testing. See also [\"Testing with golden files in Go\" - Chris Reeves](https://medium.com/soon-london/testing-with-golden-files-in-go-7fccc71c43d3)\n\n_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._\n\nIn most cases, you should prefer inline snapshots, subtest golden values, or traditional Go tests.\n\n## Command line syntax: put `-update` at the end\n\n`-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](https://github.com/fatih/color). Example:\n\n```\ngo test -count=1 -run TestSomething . -update\n```\n\n## Custom formatting\n\n[valast](https://github.com/hexops/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:\n\n- **Pass a string to autogold**: It will be formatted as a Go string for you in the resulting `.golden` file / in Go tests.\n- **Use your own formatting (JSON, etc.)**: Make your `got` value of type `autogold.Raw(\"foobar\")`, and it will be used as-is for `.golden` files (not allowed with inline tests.)\n- **Exclude unexported fields**: `autogold.ExpectFile(t, got, autogold.ExportedOnly())`\n\n## Backwards compatibility\n\n- As is the case with `gofmt`, different Go versions may produce different formattings (although rare.)\n- 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.\n- 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.)\n\n## Alternatives comparison\n\nThe following are alternatives to autogold, making note of the differences we found that let us to create autogold:\n\n- [github.com/xorcare/golden](https://pkg.go.dev/github.com/xorcare/golden)\n    - Supports `[]byte` inputs only, defers formatting to users.\n    - Does not support inline snapshots / code updating.\n- [github.com/sebdah/goldie](https://pkg.go.dev/github.com/sebdah/goldie/v2)\n    - Supports `[]byte` inputs only, provides helpers for JSON, XML, etc.\n    - Does not support inline snapshots / code updating.\n- [github.com/bradleyjkemp/cupaloy](https://pkg.go.dev/github.com/bradleyjkemp/cupaloy/v2)\n    - Works on `interface{}` inputs.\n    - [Uses inactive go-spew project](https://github.com/davecgh/go-spew/issues/128) to format Go structs.\n    - Does not support inline snapshots / code updating.\n\n## Changelog\n\n#### v2.3.0\n\nUpdated to valast v1.5.0:\n\n* Updated to valast v1.5.0: now supports [registration of custom types -\u003e AST conversions.](https://github.com/hexops/valast/commit/41f59f9d46befd6bfbb2e9e8be90d10fe2937b57)\n* Optimization making [test comparisons run faster.](https://github.com/hexops/autogold/commit/f1b7fcb6600b3022d27bcbb646fe050e92bce588)\n\n\n#### v2.2.1\n\nUpdated to valast v1.4.4:\n\n* `valast.Addr` is replaced by `valast.Ptr`, which uses Go generics and looks cleaner.\n* `time.Time` values are now supported.\n\n#### v2.2.0\n\n* If autogold is used in packages with an `-update` flag already defined, now no conflict occurs. This enables autogold to be used with other 'golden' packages without conflict.\n* Fixed an issue where `_test` packages using types from non-test packages would sometimes result in the wrong package name qualifier.\n\n#### v2.1.0\n\nAdded support for building in Bazel / working around a bug in Bazel / Go's `packages.Load` functionality. This feature can be enabled using `ENABLE_BAZEL_PACKAGES_LOAD_HACK=true`. For more details see [#40](https://github.com/hexops/autogold/pull/40) and [golang/go#57304](https://github.com/golang/go/issues/57304)\n\n#### v2.0.3\n\nFixed an issue where updating inline tests could cause a deadlock.\n\n#### v2.0.2\n\nWriting a unique name with inline tests is no longer required. Previously you must write a unique name as the first parameter to `Want` and it must have been inside a `TestFoo` function for autogold to find it:\n\n```go\nfunc TestFoo(t *testing.T) {\n\t...\n\tautogold.Want(\"unique name inside TestFoo\", want).Equal(t, nil)\n}\n```\n\nThis can be rewritten as `autogold.Expect(want).Equal(t, got)` and no unique name is required, the function call can be placed anywhere inside your Go test file as autogold will now update the invocation based on callstack information:\n\n```go\nfunc TestFoo(t *testing.T) {\n\t...\n\tautogold.Expect(want).Equal(t, nil)\n}\n```\n\nAdditionally, CLI flag behavior has been improved substantially based on experience working in very large enterprise Go codebases:\n\n* `-update` now behaves like `-update-only`, it no longer removes unused golden files which is faster in very large codebases. Instead, you may use `-update -clean` to remove unused golden files. `-update-only` is removed.\n* Previously autogold would fail tests when running `-update`, meaning you may need to run `go test -update` many times to get to your desired end-state if updating a lot of test cases. Now we match the behavior of OCaml expect tests in not failing tests by default (you can now specify `-fail-on-update`)\n* `-fail-on-update` now uses `t.FailNow()` instead of `t.Fatal()` to allow as many tests as possible to succeed when performing an update operation.\n* `autogold.Want` has been deprecated in favor of `autogold.Expect`\n* Fixed `invalid cross-device link` errors on some systems.\n\nFinally, please note the renaming of functions before and after:\n\n* Inline tests: `autogold.Want` -\u003e `autogold.Expect`\n* File tests: `autogold.Equal` -\u003e `autogold.ExpectFile`\n\n##### Automating the migration with Comby\n\nYou can automatically migrate from v1 to v2 using the following [Comby](https://comby.dev) configuration:\n\n\u003cdetails\u003e\n\u003csummary\u003eautogold.comby.toml\u003c/summary\u003e\n\n```\n# autogold.comby.toml\n[update-imports]\n\nmatch=\"\\\"github.com/hexops/autogold\\\"\"\nrewrite=\"\\\"github.com/hexops/autogold/v2\\\"\"\n\n[update-api-want]\n\nmatch=\"autogold.Want(:[desc], :[v])\"\nrewrite=\"autogold.Expect(:[v])\"\n\n[update-api-equal]\n\nmatch=\"autogold.Equal(:[v])\"\nrewrite=\"autogold.ExpectFile(:[v])\"\n```\n\nAssuming Comby is available on your system, you can run the following command to apply the changes: \n\n```\n$ go get -u github.com/hexops/autogold/v2\n$ comby -config autogold.comby.toml -matcher .go -exclude-dir vendor,node_modules -in-place\n$ go mod tidy\n$ git diff # show the changes applied by comby\n```\n\n\u003c/details\u003e\n\n#### v1.3.1\n\n* Improved Go code formatting (updated valast and gofumpt versions)\n* Added usage of `t.Helper` to improve line:column information of test failures. \n* Fixed an issue where `-update` subtest names could collide and incorrectly fail tests.\n* Fixed a data race when `-update` is used\n* Diffs are now printed with ANSII color codes\n","funding_links":["https://github.com/sponsors/slimsag"],"categories":["Go"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhexops%2Fautogold","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhexops%2Fautogold","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhexops%2Fautogold/lists"}