[repository-quality] Repository Quality Improvement Report - Integration Test Binary-Path Duplication & Brittleness (2026-09-22) #62655
Closed
Replies: 1 comment
|
This discussion has been marked as outdated by Repository Quality Improvement Agent. A newer discussion is available at Discussion #62961. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
🎯 Repository Quality Improvement Report - Integration Test Binary-Path Duplication & Brittleness
Analysis Date: 2026-09-22
Focus Area: Integration Test Binary-Path Duplication & Brittleness (custom)
Strategy Type: Custom
Custom Area: Yes — the repo already has a canonical
GetBinaryPath()/logAndValidateBinaryPath()helper inpkg/cli/mcp_helpers.gofor production code, but 32+ integration tests across 8 files independently re-implement a hardcoded"../../gh-aw"lookup-and-skip pattern instead of using a shared test helper. This is a concrete, previously unexamined maintainability/brittleness gap distinct from the last 10 runs (which covered linter CI gating, WASM docs, release tooling, nolint suppressions, and slash-command triggers).Executive Summary
Ten
pkg/cliintegration test files (mcp_server_tools_test.go,mcp_server_compile_test.go,mcp_server_json_integration_test.go,mcp_server_operations_test.go,status_command_test.go,mcp_server_error_codes_test.go,mcp_server_fix_test.go,mcp_server_inspect_test.go,mcp_server_stdio_integration_test.go,mcp_server_add_test.go) contain 32 near-identical copies of a three-line block that hardcodes the built binary's relative path as"../../gh-aw"(or"../../gh-aw.exe"on Windows), checksos.Stat, and callst.Skip("Skipping test: gh-aw binary not found. Run 'make build' first.")if missing. This pattern is duplicated 32 times across roughly 3,300 lines of test code.The duplication creates three concrete risks: (1) the relative path
../../gh-awsilently breaks if any of these test files are ever moved to a subpackage, since Go resolves relative paths from the test binary's working directory, not from the source file location; (2) any future change to the binary output name/location (e.g., MakefileBINARY_NAMEor a build-tag-specific output path) requires 32 manual edits with no compiler-enforced consistency; (3) tests silently no-op (pass green) rather than fail loudly when the binary is absent, which can mask genuinely broken integration coverage in CI if themake buildstep is ever skipped or reordered ahead ofgo test -tags integration.Recommended fix: introduce a single
testutil.RequireGhAwBinary(t *testing.T) string(or equivalentpkg/cli-local helper) that centralizes path resolution (honoringruntime.GOOSfor.exe), and replace all 32 call sites with a one-line call. This reduces duplicated logic by roughly 90 lines, removes the risk of path drift, and gives a single point of control for future binary-location changes.Full Analysis Report
Focus Area: Integration Test Binary-Path Duplication & Brittleness
Current State Assessment
The
pkg/clipackage already has a canonical, well-documented helper for binary path resolution used in production code (GetBinaryPath()andlogAndValidateBinaryPath()inpkg/cli/mcp_helpers.go), which resolves the currently-running executable viaos.Executable()+filepath.EvalSymlinks(). However, this helper is not reused by tests that need to invoke a freshly builtgh-awbinary as a subprocess (e.g., for MCP server stdio integration checks). Instead, each test file reinvents binary discovery with a hardcoded relative path.Metrics Collected:
"../../gh-aw"binary pathGetBinaryPath)pkg/testutil)t.Skip(...)calls repo-wide.exevariant handled consistentlymcp_server_json_integration_test.go)Findings
Strengths
GetBinaryPath()abstraction inpkg/cli/mcp_helpers.gothat could be extended or mirrored for test use with minimal effort.pkg/testutilalready exists as the natural home for a shared cross-file test helper (currently holds onlytempdir.go).Areas for Improvement
pkg/cli/mcp_server_compile_test.goalone has 8 copies at lines 20-23, 168-171, 271-274, 374-377, 485-488, 572-575, 693-696, plus one commented-out copy at 107-110). Any Makefile change toBINARY_NAMEor build output location requires 32 manual edits with no single source of truth.pkg/cli/mcp_server_json_integration_test.go(line 607-613) special-casesruntime.GOOS == "windows"to check for a.exesuffix. The other 9 files assume a Unix-style binary name unconditionally, meaning Windows CI runs of those suites (status_command_test.go,mcp_server_tools_test.go,mcp_server_operations_test.go,mcp_server_error_codes_test.go,mcp_server_fix_test.go,mcp_server_inspect_test.go) will silently skip every test on Windows rather than looking forgh-aw.exe.pkg/cli/mcp_server_compile_test.golines 107-110, adding noise without value.Detailed Analysis
The pattern in question (representative example from
pkg/cli/mcp_server_tools_test.go:17-21):is repeated verbatim (with only the enclosing function name differing) 32 times. A single shared helper such as:
would collapse each 3-4 line block into a single
binaryPath := testutil.RequireGhAwBinary(t)call, uniformly fix the Windows.exegap, and centralize any future path changes.🤖 Tasks for Copilot Agent
NOTE TO PLANNER AGENT: Split the following tasks into individual work items.
Improvement Tasks
Task 1: Add a shared
RequireGhAwBinarytest helper topkg/testutilPriority: High
Estimated Effort: Small
Focus Area: Integration Test Binary-Path Duplication
Description: Create a new file
pkg/testutil/binary.gowith aRequireGhAwBinary(t *testing.T) stringfunction that resolves the builtgh-awbinary's relative path (honoringruntime.GOOSfor the.exesuffix on Windows), callst.Skipf(...)with the standard message if the binary is absent, and returns the resolved path for use inexec.Command(...). Add a small table-driven unit test inpkg/testutil/binary_test.gocovering the exists/not-exists cases (create a temp file to simulate the "exists" branch; skip is inherently hard to assert directly, so assert on the returned path format and the non-skip branch).Acceptance Criteria:
pkg/testutil/binary.goexportsRequireGhAwBinary(t *testing.T) stringruntime.GOOS == "windows"to append.exet.Helper()so failure/skip lines point at the callergo test ./pkg/testutil/...)Code Region:
pkg/testutil/(new file)Task 2: Migrate
pkg/cli/mcp_server_compile_test.goandmcp_server_json_integration_test.goto the shared helperPriority: High
Estimated Effort: Medium
Focus Area: Integration Test Binary-Path Duplication
Description: Replace all 8 duplicated skip blocks in
pkg/cli/mcp_server_compile_test.go(lines ~20-23, 168-171, 271-274, 374-377, 485-488, 572-575, 693-696) and all 7 inpkg/cli/mcp_server_json_integration_test.go(including the Windows-specific block at line 607-613) with calls totestutil.RequireGhAwBinary(t). Also remove the stale commented-out duplicate block at lines 107-110 ofmcp_server_compile_test.go.Acceptance Criteria:
mcp_server_compile_test.goreplaced withbinaryPath := testutil.RequireGhAwBinary(t)mcp_server_json_integration_test.go(including the.exevariant) replacedgo build -tags integration ./pkg/cli/...compiles cleanlygo vet ./pkg/cli/...passesCode Region:
pkg/cli/mcp_server_compile_test.go,pkg/cli/mcp_server_json_integration_test.goIn pkg/cli/mcp_server_compile_test.go and pkg/cli/mcp_server_json_integration_test.go, replace every occurrence of the pattern: // Skip if the binary doesn't exist binaryPath := "../../gh-aw" if _, err := os.Stat(binaryPath); os.IsNotExist(err) { t.Skip("Skipping test: gh-aw binary not found. Run 'make build' first.") } (and the .exe variant in mcp_server_json_integration_test.go around line 607-613) with: binaryPath := testutil.RequireGhAwBinary(t) Import "github.com/github/gh-aw/pkg/testutil" as needed. Remove the now-unused os import if no longer referenced elsewhere in the file, and remove the stale commented-out duplicate block near line 107-110 in mcp_server_compile_test.go. Run `go build -tags integration ./pkg/cli/...` and `go vet ./pkg/cli/...` to confirm correctness, then `make fmt`.Task 3: Migrate remaining MCP server test files to the shared helper
Priority: Medium
Estimated Effort: Medium
Focus Area: Integration Test Binary-Path Duplication
Description: Apply the same
testutil.RequireGhAwBinary(t)migration to the remaining files:pkg/cli/mcp_server_tools_test.go(5 occurrences),pkg/cli/mcp_server_operations_test.go(4),pkg/cli/status_command_test.go(3),pkg/cli/mcp_server_error_codes_test.go(2),pkg/cli/mcp_server_fix_test.go(2),pkg/cli/mcp_server_inspect_test.go(2). This also fixes the Windows.exeblind spot for these six files, since the shared helper handlesruntime.GOOScorrectly.Acceptance Criteria:
go build -tags integration ./pkg/cli/...compiles cleanlymake build && go test -tags integration -run 'TestMCPServer|TestStatus' ./pkg/cli/...passes locally (binary present)Code Region:
pkg/cli/mcp_server_tools_test.go,pkg/cli/mcp_server_operations_test.go,pkg/cli/status_command_test.go,pkg/cli/mcp_server_error_codes_test.go,pkg/cli/mcp_server_fix_test.go,pkg/cli/mcp_server_inspect_test.goIn pkg/cli/mcp_server_tools_test.go, pkg/cli/mcp_server_operations_test.go, pkg/cli/status_command_test.go, pkg/cli/mcp_server_error_codes_test.go, pkg/cli/mcp_server_fix_test.go, and pkg/cli/mcp_server_inspect_test.go, replace every occurrence of: // Skip if the binary doesn't exist binaryPath := "../../gh-aw" if _, err := os.Stat(binaryPath); os.IsNotExist(err) { t.Skip("Skipping test: gh-aw binary not found. Run 'make build' first.") } with: binaryPath := testutil.RequireGhAwBinary(t) Add the "github.com/github/gh-aw/pkg/testutil" import to each file and remove the os import if it becomes unused. Verify with `go build -tags integration ./pkg/cli/...` and, if a locally built binary is available via `make build`, run `go test -tags integration -run 'TestMCPServer|TestStatus' ./pkg/cli/...`. Finish with `make fmt`.Task 4: Document the binary-discovery convention for integration tests
Priority: Low
Estimated Effort: Small
Focus Area: Documentation / Testing
Description: Add a short section to the developer-facing testing documentation (e.g.,
docs/src/content/docs/testing guide or a relevant.github/skills/developer/SKILL.mdreference) explaining that integration tests requiring the builtgh-awbinary must usetestutil.RequireGhAwBinary(t)rather than hardcoding relative paths, so the convention is discoverable for future test authors and does not regress.Acceptance Criteria:
testutil.RequireGhAwBinary(t)usage is added to the appropriate developer docs locationmake recompilefor workflow docs or the docs site build) still passesCode Region:
docs/src/content/docs/(developer/testing guide) or.github/skills/developer/SKILL.md📊 Historical Context
Previous Focus Areas
🎯 Recommendations
Immediate Actions (This Week)
testutil.RequireGhAwBinary(t)helper (Task 1) — Priority: Highmcp_server_compile_test.goandmcp_server_json_integration_test.go(Task 2) — Priority: HighShort-term Actions (This Month)
Long-term Actions (This Quarter)
pkg/lintersanalyzer) that flags hardcoded"../../gh-aw"string literals in test files to prevent regression — Priority: Low📈 Success Metrics
testutil.RequireGhAwBinary).exe-aware test files: 1 of 10 → 10 of 10Next Steps
Generated by Repository Quality Improvement Agent
Next analysis: 2026-09-23 — Focus area selected by diversity algorithm
All reactions