Skip to content

[testify-expert] Improve Test Quality: pkg/actionpins/actionpins_internal_test.go #48705

Description

@github-actions

Current State

  • File: pkg/actionpins/actionpins_internal_test.go (869 lines, 27 top-level Test* funcs, many with t.Run subtests)
  • Source pair: pkg/actionpins/actionpins.go (595 lines, 27 functions)
  • Uses github.com/stretchr/testify/{assert,require} (66 assert.*, 25 require.* calls) and testutil.CaptureStderr for stderr assertions.

Strengths

  • Good require vs assert discipline: require used for prerequisite/fatal checks (e.g. require.NotEmpty, require.True), assert for value checks.
  • Strong table-driven coverage for TestFormatPinnedActionWithResolution_ConsistentVersionComment, TestFindCompatiblePin_SemverFallback, TestApplyActionPinMapping, TestApplyContainerPinMapping.
  • Descriptive failure messages passed to nearly every assertion.
  • Nil-safety and dedup-notification behavior explicitly tested (TestRecordPinResolutionFailure_NilSafety, dedup subtests in mapping tests).

Prioritized Improvements

1. Missing/high-value tests

  • TestGetContainerPin_DefaultMCPImagesArePinned (lines 403–416) iterates over images with a plain for loop instead of t.Run(image, ...). A failure on one image aborts remaining assertions and reports poorly. Convert to subtests, matching the pattern already used in TestGetContainerPin_MCPGatewayVersionsArePinned.
  • No test exercises getActionPins() caching behavior itself (singleton/lazy-load via sync.Once or similar) — only its side effect (cachedContainerPins) is probed indirectly in TestGetContainerPin_MCPGatewayVersionsArePinned. Add a direct test asserting repeated calls to getActionPins() return equal/identical data (cache correctness), e.g. assert.Same/assert.Equal on two invocations.
  • TestResolveActionPinFromHardcodedPins_StrictModeNoFallback has only one scenario. Add a companion case where StrictMode: true with an exact version match still resolves (ok == true), so the "no fallback, but exact match still works" branch is verified — otherwise this branch of resolveActionPinFromHardcodedPins is not directly asserted from this test.
Before/after: subtest conversion for default MCP images

Before:

for _, image := range images {
    pin, ok := GetContainerPin(image)
    require.True(t, ok, "Expected embedded container pin for %s", image)
    assert.Equal(t, image, pin.Image, "Expected image name to match key")
    ...
}

After:

for _, image := range images {
    t.Run(image, func(t *testing.T) {
        pin, ok := GetContainerPin(image)
        require.True(t, ok, "Expected embedded container pin for %s", image)
        assert.Equal(t, image, pin.Image, "Expected image name to match key")
        ...
    })
}

2. Testify assertion upgrades

  • TestFormatPinnedActionReference_PanicsWhenSHAIsEmpty and TestLoadActionPinsData_PanicsWhenEntrySHAIsEmpty use assert.Panics but never assert on the panic value/message. Use assert.PanicsWithValue (if the panic value is a known string/error) so a future refactor that changes the panic type without preserving the message doesn't silently pass.
  • TestInitWarnings_InitializesAndPreservesMap subtest "preserves existing warnings map" loops with a plain for warning := range existing { assert.True(...) } — replace with assert.Subset or a direct assert.Equal(t, existing-derived-map, ctx.Warnings) to get a single clear diff on failure instead of one assertion per key silently repeating the same message.

3. Table-driven refactors

  • TestResolveExactHardcodedPin_BySHA, _ByVersion, _NoMatch, _VersionTakesPrecedenceOverSHA (lines 491–528) are four separate top-level test functions covering the same function (resolveExactHardcodedPin) with near-identical structure (build one-pin slice → call → assert ok/Contains). Consolidate into one table-driven TestResolveExactHardcodedPin with a name/pins/repo/version/isSHA/wantOK/wantContains struct, consistent with the style used elsewhere in the file (e.g. TestFindCompatiblePin_SemverFallback). Reduces ~40 lines of duplication and makes it easy to add new precedence-edge-case rows later.

4. Organization/readability

  • Helper type countingResolver (lines 418–425) is defined mid-file, between two unrelated test functions. Move it near the top of the file (after imports) or into a _test_helpers.go-style section so readers scanning top-to-bottom aren't interrupted mid-flow.
  • Consider grouping the four resolveExactHardcodedPin tests and the two resolveNonStrictHardcodedPin tests under a shared comment banner (e.g. // --- resolveExactHardcodedPin ---) to mirror the clear separation already present around ApplyActionPinMapping/ApplyContainerPinMapping.

Acceptance Checklist

  • Convert TestGetContainerPin_DefaultMCPImagesArePinned to use t.Run per image
  • Add cache-correctness test for getActionPins()
  • Add strict-mode exact-match case to TestResolveActionPinFromHardcodedPins_StrictModeNoFallback
  • Use assert.PanicsWithValue (or equivalent) in the two panic tests
  • Consolidate resolveExactHardcodedPin tests into one table-driven test
  • Move countingResolver helper near imports
  • make test-unit passes with no regressions

Generated by 🧪 Daily Testify Uber Super Expert · sonnet50 · 34 AIC · ⌖ 8.5 AIC · ⊞ 6.9K ·

  • expires on Jul 30, 2026, 10:28 AM UTC-08:00

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions