Skip to content

[go-fan] Go Module Review: stretchr/testify #4007

@github-actions

Description

@github-actions

🐹 Go Fan Report: stretchr/testify

Module Overview

testify is Go's most widely adopted testing toolkit, providing expressive assertion helpers (assert/require), mock object generation, and test suite support. It wraps testing.T with 80+ assertion functions that generate rich, readable failure messages.

Current Usage in gh-aw-mcpg

The project makes excellent use of testify throughout:

  • Files: 130+ test files (virtually every test file in the codebase)
  • Import Count: ~260 total imports (assert + require combined)
  • Version: v1.11.1 (current latest ✅)
  • Key APIs Used: Equal, NoError, Error, Contains, Len, ElementsMatch, JSONEq, Empty, True/False, LessOrEqual
  • Bound asserters (assert.New(t)) used in 25+ files — great pattern!
  • mock / suite packages: not used

Research Findings

testify v1.11.1 is the current stable release. The codebase is already on it. Key features that are well-leveraged:

  • assert.ElementsMatch for order-independent slice comparisons ✅
  • assert.JSONEq for semantic JSON comparisons ✅
  • require.Len for length checks with fatal stop ✅
  • Bound asserters for multi-assertion blocks ✅

Recent Updates (v1.10–v1.11)

  • assert.LessOrEqual, assert.GreaterOrEqual, assert.Less, assert.Greater — numeric comparison assertions
  • assert.InDelta, assert.InEpsilon — float comparisons with tolerance
  • Improved failure message formatting

Best Practices from Maintainers

  • Use require for critical path checks where the test can't meaningfully continue
  • Use assert for independent checks where multiple failures should surface
  • Prefer specific assertions (e.g., NoError, Contains, Len) over True with boolean expressions

Improvement Opportunities

🏃 Quick Wins

1. require.Nil(t, err)require.NoError(t, err) (5 instances)

In internal/config/rules/rules_test.go (lines 77, 141, 298, 902, 1042):

// Before
require.Nil(t, err, "Unexpected validation error")

// After — produces: "Received unexpected error: <err details>"
require.NoError(t, err, "Unexpected validation error")

require.NoError is semantically clearer for error values and gives a better failure message.

2. assert.Equal(t, true/false, x)assert.True/False(t, x) (4 instances)

  • internal/config/fetch_and_fix_schema_test.go:248assert.Equal(t, true, gpMap["additionalProperties"], ...)
  • internal/proxy/proxy_test.go:685assert.Equal(t, false, m["incomplete_results"])
  • internal/mcp/tool_result_test.go:270assert.Equal(t, true, args["active"])
  • internal/mcp/unmarshal_params_test.go:156assert.Equal(t, true, target["bool_val"])
// Before
assert.Equal(t, true, gpMap["additionalProperties"], "guard-policies.additionalProperties should be true")

// After
assert.True(t, gpMap["additionalProperties"].(bool), "guard-policies.additionalProperties should be true")

✨ Feature Opportunities

3. assert.True(t, strings.Contains(...))assert.Contains(t, str, substr) (~10 instances)

Found in: rest_backend_caller_tool_test.go:577, labels_test.go:593,619, call_backend_tool_test.go:485-486, expand_raw_json_test.go:569, config_test.go:1092, large_payload_test.go:701

// Before — failure says: "Should be true"
assert.True(t, strings.Contains(text, "Bug report"), "response text should contain the issue title")

// After — failure says: `"...some long text..."` should contain "Bug report"
assert.Contains(t, text, "Bug report", "response text should contain the issue title")

Much better diagnostics: the full string is shown in the failure, pinpointing exactly what was missing.

4. assert.True(t, len(x) <= N)assert.LessOrEqual(t, len(x), N) (2 instances)

In internal/middleware/jqschema_integration_test.go lines 198, 207:

// Before — failure says: "Should be true"
assert.True(t, len(previewInContent) <= 503, "Preview in Content should be truncated")

// After — failure says: "expected 512 to be <= 503"
assert.LessOrEqual(t, len(previewInContent), 503, "Preview in Content should be truncated")

📐 Best Practice Alignment

5. Re-evaluate enabling testifylint in golangci-lint

testifylint is currently disabled in .golangci.yml with a note about "requiring extensive test refactoring." However, the actual scope of violations found in this review is ~20 instances across the whole codebase — quite manageable. Once the quick wins above are fixed, enabling testifylint would prevent regressions and automatically catch future anti-patterns.

# .golangci.yml — consider re-enabling after fixes
linters:
  disable:
    - testifylint  # Remove this line after cleanup

6. Consider testify/mock for hand-rolled mock structs

internal/launcher and similar packages use hand-written mock implementations. testify/mock provides:

  • Automatic call tracking (AssertCalled, AssertNumberOfCalls)
  • Argument matching (MatchedBy, AnythingOfType)
  • Return value injection

This could reduce maintenance burden, especially as the mock implementations grow.

Recommendations (Prioritized)

  1. High value, low effort — Fix the 5× require.Nil(t, err)require.NoError in rules_test.go
  2. High value, low effort — Replace assert.True(t, strings.Contains(...)) with assert.Contains (~10 instances)
  3. Medium value, low effort — Fix assert.Equal(t, true/false, ...)assert.True/False (4 instances)
  4. Medium value, low effort — Fix assert.True(t, len(x) <= N)assert.LessOrEqual (2 instances)
  5. Medium value, medium effort — Re-enable testifylint after completing the above

Next Steps

  • Fix require.Nil(t, err)require.NoError in internal/config/rules/rules_test.go
  • Replace assert.True(t, strings.Contains(...)) with assert.Contains in all affected files
  • Fix assert.Equal(t, true/false, ...) patterns
  • Fix assert.True(t, len(x) <= N) patterns
  • Re-enable testifylint in .golangci.yml

Generated by Go Fan 🐹
Module summary saved to: /home/runner/.copilot/session-state/.../files/testify.md (specs/mods dir pending creation)
Run: §24553760576

Note

🔒 Integrity filter blocked 12 items

The following items were blocked because they don't meet the GitHub integrity level.

To allow these resources, lower min-integrity in your GitHub frontmatter:

tools:
  github:
    min-integrity: approved  # merged | approved | unapproved | none

Generated by Go Fan · ● 1.8M ·

  • expires on Apr 24, 2026, 7:52 AM UTC

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions