go-tstr / golden

github.com/go-tstr/golden

pkg.go.dev source
go get github.com/go-tstr/golden@v0.0.1

README

Go Reference codecov main

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) bool

Assert checks the golden file content against the given data.

func EqualWithDiff

func EqualWithDiff(t T, expected, actual string, msgAndArgs ...interface{}) (ok bool)

func NoError

func NoError(t T, err error, msg string)

func ParseRecreateFromEnv

func ParseRecreateFromEnv(t T) bool

ParseRecreateFromEnv checks if the environment variable GOLDEN_FILES_RECREATE is set to true.

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) string

TestNameToFilePath 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) bool

func (*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()
}