🎯 Areas for Improvement
1. No Testify Assertions — The Biggest Gap
The file has zero testify usage. Every other test file in pkg/workflow/ uses testify (e.g., compiler_test.go imports assert and require). All assertions in resolve_test.go use raw t.Fatal/t.Errorf/t.Error calls.
Current (anti-pattern):
// Setup error – should stop the test
err := os.MkdirAll(workflowsDir, 0755)
if err != nil {
t.Fatal(err)
}
// Validation – doesn't stop on failure
result, err := ResolveWorkflowName(tt.workflowInput)
if tt.expectError {
if err == nil {
t.Errorf("Expected error for workflow input %q, but got none", tt.workflowInput)
}
} else {
if err != nil {
t.Errorf("Unexpected error for workflow input %q: %v", tt.workflowInput, err)
}
if result != tt.expectedWorkflowName {
t.Errorf("Expected workflow name %q, got %q", tt.expectedWorkflowName, result)
}
}
Improved (testify):
// Setup error – require stops the test immediately
require.NoError(t, os.MkdirAll(workflowsDir, 0755), "should create workflows directory")
// Validation – assert continues checking
result, err := ResolveWorkflowName(tt.workflowInput)
if tt.expectError {
require.Error(t, err, "should return error for %q", tt.workflowInput)
} else {
require.NoError(t, err, "should not return error for %q", tt.workflowInput)
assert.Equal(t, tt.expectedWorkflowName, result, "workflow name should match")
}
This affects every test function in the file (all 10).
2. Custom contains / findSubstring Helpers That Reinvent strings.Contains
Lines 422–437 define two helper functions:
// contains checks if a string contains a substring
func contains(s, substr string) bool {
return len(s) >= len(substr) && (s == substr || len(substr) == 0 ||
(len(s) > len(substr) && s[len(s)-len(substr):] == substr) ||
(len(s) > len(substr) && s[:len(substr)] == substr) ||
(len(s) > len(substr) && findSubstring(s, substr)))
}
func findSubstring(s, substr string) bool {
for i := 0; i <= len(s)-len(substr); i++ {
if s[i:i+len(substr)] == substr {
return true
}
}
return false
}
This is a verbose reimplementation of strings.Contains. The contains function also has a logical flaw: if the substring appears only in the middle (not at start or end), the first three branches fail and it falls through to findSubstring, which saves it — but the overall complexity is unnecessary.
Improved:
// ❌ Remove both helper functions entirely.
// Replace usages like:
if err != nil && !contains(err.Error(), "Run 'gh aw compile'") {
t.Errorf("Expected error to mention compilation, got: %v", err)
}
// With testify assert.Contains:
require.Error(t, err, "should return error for missing lock file")
assert.Contains(t, err.Error(), "gh aw compile", "error should suggest running compile")
3. Duplicated Setup Code Across Error-Path Tests
TestResolveWorkflowName_MissingLockFile, TestResolveWorkflowName_InvalidYAML, and TestResolveWorkflowName_MissingNameField all share identical setup boilerplate:
tempDir := testutil.TempDir(t, "test-*")
workflowsDir := filepath.Join(tempDir, constants.GetWorkflowDir())
err := os.MkdirAll(workflowsDir, 0755)
if err != nil {
t.Fatal(err)
}
// ...create files...
t.Chdir(tempDir)
Improved — extract a helper:
// setupWorkflowDir creates a temp dir with the workflows subdirectory and changes into it.
// Returns the workflows directory path.
func setupWorkflowDir(t *testing.T) string {
t.Helper()
tempDir := testutil.TempDir(t, "test-*")
workflowsDir := filepath.Join(tempDir, constants.GetWorkflowDir())
require.NoError(t, os.MkdirAll(workflowsDir, 0755), "should create workflows directory")
t.Chdir(tempDir)
return workflowsDir
}
This reduces ~8 lines of boilerplate per test to a single call, improving readability and consistency.
4. TestResolveWorkflowName_ExistingAgenticWorkflow Uses Manual os.Chdir + Defer
This test manually calls os.Chdir and defers a restore:
err = os.Chdir(projectRoot)
if err != nil {
t.Skipf("Cannot change to project root: %v", err)
}
defer func() {
if err := os.Chdir(currentDir); err != nil {
t.Errorf("Failed to restore working directory: %v", err)
}
}()
All other tests in this file use t.Chdir(...) (Go 1.24+), which automatically restores the working directory after the test. This is both cleaner and safer.
Improved:
t.Chdir(projectRoot) // t.Chdir auto-restores; no defer needed
5. Missing Assertion Messages Throughout
Most assertions lack descriptive messages, making failures hard to diagnose:
// ❌ No message — what went wrong?
if result != tt.expectedWorkflowName {
t.Errorf("Expected workflow name %q, got %q", tt.expectedWorkflowName, result)
}
// ✅ With testify and message
assert.Equal(t, tt.expectedWorkflowName, result,
"TestResolveWorkflowName[%s]: workflow name should match", tt.name)
6. TestGetAllWorkflows Uses Manual Map for Verification
workflowMap := make(map[string]string)
for _, wf := range workflows {
workflowMap[wf.WorkflowID] = wf.DisplayName
}
for workflowID, expectedDisplayName := range testWorkflows {
actualDisplayName, exists := workflowMap[workflowID]
if !exists {
t.Errorf("Expected workflow ID %q not found in results", workflowID)
} else if actualDisplayName != expectedDisplayName { ...}
}
Improved with require.Len and assert.Contains:
require.Len(t, workflows, len(testWorkflows), "should return correct number of workflows")
// Build map once with require
workflowMap := make(map[string]string, len(workflows))
for _, wf := range workflows {
workflowMap[wf.WorkflowID] = wf.DisplayName
}
for id, expectedName := range testWorkflows {
assert.Equal(t, expectedName, workflowMap[id],
"workflow %q should have correct display name", id)
}
Overview
The test file
pkg/workflow/resolve_test.gohas been selected for quality improvement by the Testify Uber Super Expert. This file contains 10 test functions across 706 lines and tests the workflow resolution/lookup functionality (resolve.go). While it has good table-driven tests and broad coverage, it doesn't usetestifyat all — relying entirely on manualif/t.Fatal/t.Errorfpatterns — and contains duplicated setup code and a custom substring helper that reinventsstrings.Contains.Current State
pkg/workflow/resolve_test.gopkg/workflow/resolve.gotestify/assertortestify/requireTest Quality Analysis
Strengths ✅
TestNormalizeWorkflowName,TestResolveWorkflowName,TestFindWorkflowName,TestGetWorkflowLockFileName, andTestShouldSkipFirewallWorkflowt.Chdirfor clean directory management in most tests🎯 Areas for Improvement
1. No Testify Assertions — The Biggest Gap
The file has zero testify usage. Every other test file in
pkg/workflow/usestestify(e.g.,compiler_test.goimportsassertandrequire). All assertions inresolve_test.gouse rawt.Fatal/t.Errorf/t.Errorcalls.Current (anti-pattern):
Improved (testify):
This affects every test function in the file (all 10).
2. Custom
contains/findSubstringHelpers That Reinventstrings.ContainsLines 422–437 define two helper functions:
This is a verbose reimplementation of
strings.Contains. Thecontainsfunction also has a logical flaw: if the substring appears only in the middle (not at start or end), the first three branches fail and it falls through tofindSubstring, which saves it — but the overall complexity is unnecessary.Improved:
3. Duplicated Setup Code Across Error-Path Tests
TestResolveWorkflowName_MissingLockFile,TestResolveWorkflowName_InvalidYAML, andTestResolveWorkflowName_MissingNameFieldall share identical setup boilerplate:Improved — extract a helper:
This reduces ~8 lines of boilerplate per test to a single call, improving readability and consistency.
4.
TestResolveWorkflowName_ExistingAgenticWorkflowUses Manualos.Chdir+ DeferThis test manually calls
os.Chdirand defers a restore:All other tests in this file use
t.Chdir(...)(Go 1.24+), which automatically restores the working directory after the test. This is both cleaner and safer.Improved:
5. Missing Assertion Messages Throughout
Most assertions lack descriptive messages, making failures hard to diagnose:
6.
TestGetAllWorkflowsUses Manual Map for VerificationImproved with
require.Lenandassert.Contains:📋 Implementation Guidelines
Priority Order
testify/assertandtestify/requireimports; replace allt.Fatal/t.Errorf/t.Errorwith testify equivalentscontains/findSubstringhelpers; useassert.Contains/strings.ContainssetupWorkflowDirhelper to eliminate duplicated setup boilerplateos.Chdir+ defer inTestResolveWorkflowName_ExistingAgenticWorkflowwitht.ChdirRequired Import Change
Best Practices from
scratchpad/testing.mdrequire.*for critical setup (stops test on failure)assert.*for test validations (continues checking)t.Run()and descriptive namesTesting Commands
Acceptance Criteria
testify/assertandtestify/requireimported and used throughoutt.Fatal(err)replaced withrequire.NoError(t, err, "...")if err == nil { t.Errorf("Expected error...") }replaced withrequire.Error(t, err, "...")if result != expected { t.Errorf(...) }replaced withassert.Equal(t, expected, result, "...")containsandfindSubstringhelpers removed; replaced withstrings.Contains/assert.ContainssetupWorkflowDirhelper extracted to eliminate duplicated boilerplateTestResolveWorkflowName_ExistingAgenticWorkflowusest.Chdirinstead ofos.Chdir+ defergo test -v ./pkg/workflow/ -run "TestNormalizeWorkflowName|TestResolveWorkflowName|TestFindWorkflowName|TestGetAllWorkflows|TestGetWorkflowLockFileName|TestShouldSkipFirewallWorkflow"scratchpad/testing.mdAdditional Context
scratchpad/testing.mdfor comprehensive testing patternspkg/workflow/compiler_test.go— usesassertandrequirethroughoutPriority: Medium
Effort: Small — mechanical replacement of assertion style across ~706 lines
Expected Impact: Consistent assertion style, clearer failure messages, less duplicated boilerplate, removal of buggy/unnecessary custom helpers
Files Involved:
pkg/workflow/resolve_test.gopkg/workflow/resolve.go