Skip to content

Instantly share code, notes, and snippets.

@MatthewJamesBoyle
Last active February 18, 2026 13:06
Show Gist options
  • Select an option

  • Save MatthewJamesBoyle/2e86d9c946e69ec9d110ddd50ba30100 to your computer and use it in GitHub Desktop.

Select an option

Save MatthewJamesBoyle/2e86d9c946e69ec9d110ddd50ba30100 to your computer and use it in GitHub Desktop.
go-tests.md
name description
go-tests
Generates Go unit tests using the Expectation pattern with cmp.Diff. Use when writing, adding, or fixing Go tests, or when working with _test.go files.

Go Tests

Table-driven tests using the Expectation pattern with cmp.Diff.

Required Pattern

func TestFunctionName(t *testing.T) {
	t.Parallel()

	type Expectation struct {
		Result ResultType
		Err    string
	}

	tests := []struct {
		Name     string
		Input    InputType
		Expected Expectation
	}{
		{
			Name:  "descriptive_snake_case_name",
			Input: inputValue,
			Expected: Expectation{
				Result: expectedValue,
			},
		},
	}

	for _, tc := range tests {
		t.Run(tc.Name, func(t *testing.T) {
			t.Parallel()

			var got Expectation
			result, err := FunctionUnderTest(tc.Input)
			if err != nil {
				got.Err = err.Error()
			} else {
				got.Result = result
			}

			if diff := cmp.Diff(tc.Expected, got); diff != "" {
				t.Errorf("FunctionUnderTest() mismatch (-want +got):\n%s", diff)
			}
		})
	}
}

Rules

  1. Always use t.Parallel() at test function and subtest level
  2. Never use t.Parallel() with t.Setenv() - they panic together
  3. Single cmp.Diff assertion comparing entire Expectation struct
  4. Capture errors as strings in Expectation.Err, not with t.Fatal
  5. Use t.Context() instead of context.Background()
  6. Use t.Cleanup() for resource cleanup, not defer
  7. Use t.Helper() in helper functions
  8. Never use testify - use cmp.Diff only

cmp.Diff Options

// Ignore non-deterministic fields
cmpopts.IgnoreFields(Response{}, "CreatedAt", "UpdatedAt")

// Handle unexported fields (generated code)
cmpopts.IgnoreUnexported(db.Environment{})

// Protobuf messages
protocmp.Transform()

// Combine options
cmp.Diff(tc.Expected, got,
	protocmp.Transform(),
	cmpopts.IgnoreFields(db.Prebuild{}, "CreateTime", "Edges"),
	cmpopts.EquateEmpty(),
)

Common Patterns

For HTTP handler tests, database tests with ExistingObjects, and Setup functions, see examples.md.

Anti-Patterns

  • t.Fatal for action errors → use Expectation.Err
  • len(results) != expected → compare full results
  • context.Background() → use t.Context()
  • testify/assert → use cmp.Diff
  • Missing t.Parallel() on independent tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment