github.com/go-tstr/golden
go get github.com/go-tstr/golden@v0.1.0
README
golden
Golden file testing is a technique where the expected output of a test is
- generated automatically from test
- stored in a separate file (the "golden file")
- verified to never change unless explicitly regerated
During testing, the actual output is compared against the contents of the golden file. If the outputs match, the test passes; if not, the test fails. This approach is especially useful for testing complex outputs such as JSON, HTML, or other structured data, as it makes it easy to review and update expected outputs.
Overview
Package golden provides standard way to write tests with golden files.
Variables
var DefaultHandler = &FileHandler{
FileName: TestNameToFilePath,
ShouldRecreate: ParseRecreateFromEnv,
Equal: EqualWithDiff,
ProcessContent: nil,
}Functions
func Assert
func Assert(t T, data string) boolAssert checks the golden file content against the given data.
func EqualWithDiff
func EqualWithDiff(t T, expected, actual string, msgAndArgs ...interface{}) (ok bool)EqualWithDiff compares two strings and returns true if they are equal. If they are not equal, test will be marked as failed and the diff will be logged.
func NoError
func NoError(t T, err error, msg string)func ParseRecreateFromEnv
func ParseRecreateFromEnv(t T) boolParseRecreateFromEnv checks if the environment variable GOLDEN_FILES_RECREATE is set to true.
func PrettyJSON
func PrettyJSON(t T, data string) stringPrettyJSON formats the JSON string using the pretty package. This is useful for making the JSON more readable in the golden file also provides cleaner diffs when comparing JSON files.
func Request
func Request(t T, client Client, req *http.Request, expectedStatusCode int) (*http.Response, bool)Request sends the request and asserts that the response status code is equal to the expectedStatusCode. It also asserts that the response body is equal to the golden file content using EqualString. Example test function:
func TestAPI(t *testing.T) {
tests := []struct {
name string
method string
path string
body io.Reader
expectedCode int
}{
{
name: "create user",
method: "POST",
path: "/api/v1/user",
body: strings.NewReader(`{"name": "someone"}`),
expectedCode: 200,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req, err := http.NewRequest(tt.method, "http://127.0.0.1:8080"+tt.path, tt.body)
require.NoError(t, err)
golden.Request(t, http.DefaultClient, req, tt.expectedCode)
})
}
}
func TestNameToFilePath
func TestNameToFilePath(t T) stringTestNameToFilePath creates file name and path for the golden file using t.Name() with following rules: Top level: ./testdata/{testFuncName}/{testFuncName}.golden Subtest: ./testdata/{testFuncName}/{subTestName}.golden
Types
type Client
type Client interface {
Do(req *http.Request) (*http.Response, error)
}Client is an interface that allows using http.Client or any other client that implements the Do method.
type FileHandler
type FileHandler struct {
FileName func(T) string
ShouldRecreate func(T) bool
ProcessContent func(T, string) string
Equal func(t T, expected, actual string, msgAndArgs ...interface{}) (ok bool)
}func (*FileHandler) Assert
func (h *FileHandler) Assert(t T, data string) boolfunc (*FileHandler) Request
func (h *FileHandler) Request(t T, client Client, req *http.Request, expectedStatusCode int) (*http.Response, bool)type T
type T interface {
Logf(format string, args ...any)
Errorf(format string, args ...interface{})
FailNow()
Name() string
Helper()
}