Skip to content

[testify-expert] Improve Test Quality: pkg/workflow/args_field_test.go #38423

@github-actions

Description

@github-actions

Overview

The test file pkg/workflow/args_field_test.go has been selected by the Testify Uber Super Expert. It tests getGitHubCustomArgs, getPlaywrightCustomArgs, and parser.ExtractMCPConfigurations but does not import testify — relying entirely on raw Go if/t.Errorf patterns. This issue provides specific, actionable improvements.

Current State

  • Test File: pkg/workflow/args_field_test.go
  • Source File: pkg/workflow/args.go
  • Test Functions: 1 (TestArgsField) with 5 t.Run() subtests
  • Lines of Code: 224
  • Testify Imported: ❌ None

Strengths ✅

  1. Uses t.Run() for all subtests with descriptive names
  2. Covers both []any and []string arg variants
  3. Tests nil/default return values
🎯 Areas for Improvement

1. No Testify Assertions — Add require and assert

// ❌ CURRENT (throughout the file)
if len(result) != 2 {
    t.Errorf("Expected 2 args, got %d", len(result))
}
if err != nil {
    t.Fatalf("Error parsing with args field: %v", err)
}
if len(configs) == 0 {
    t.Fatal("No configs returned")
}

// ✅ IMPROVED
require.NoError(t, err, "parsing args field should succeed")
require.NotEmpty(t, configs, "parser should return at least one MCP config")
assert.Len(t, result, 2, "should return exactly 2 custom args")
assert.Equal(t, []string{"--verbose", "--debug"}, result)
assert.Nil(t, result, "no args field should return nil")

Also add the imports:

import (
    "testing"
    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/require"
)

2. Replace Manual for-Loop Contains Checks

// ❌ CURRENT — 12 lines per containment check
foundVerbose := false
for _, arg := range configs[0].Args {
    if arg == "--verbose" { foundVerbose = true }
}
if !foundVerbose {
    t.Errorf("Expected --verbose in args, got: %v", configs[0].Args)
}

// ✅ IMPROVED — 1 line
assert.Contains(t, configs[0].Args, "--verbose", "custom flag should be appended")
assert.Contains(t, strings.Join(configs[0].Args, " "), "ghcr.io/github/github-mcp-server:",
    "Docker image should be present")

3. Refactor Duplicate Patterns to Table-Driven Tests

The GitHub and Playwright unit subtests follow the same three-case pattern ([]any / []string / nil). Extract each into a dedicated table-driven test:

func TestGetGitHubCustomArgs(t *testing.T) {
    tests := []struct {
        name     string
        input    map[string]any
        expected []string
    }{
        {"args as []any", map[string]any{"args": []any{"--verbose", "--debug"}}, []string{"--verbose", "--debug"}},
        {"args as []string", map[string]any{"args": []string{"--flag"}}, []string{"--flag"}},
        {"no args field returns nil", map[string]any{}, nil},
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            assert.Equal(t, tt.expected, getGitHubCustomArgs(tt.input))
        })
    }
}

4. Add Missing Tests for extractCustomArgs and writeArgsToYAML

Both functions in args.go lack direct unit tests.

func TestExtractCustomArgs(t *testing.T) {
    tests := []struct {
        name     string
        input    map[string]any
        expected []string
    }{
        {"no key returns nil", map[string]any{}, nil},
        {"[]any values", map[string]any{"args": []any{"a", "b"}}, []string{"a", "b"}},
        {"[]string values", map[string]any{"args": []string{"a"}}, []string{"a"}},
        {"[]any skips non-strings", map[string]any{"args": []any{"a", 42, "b"}}, []string{"a", "b"}},
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            assert.Equal(t, tt.expected, extractCustomArgs(tt.input))
        })
    }
}

func TestWriteArgsToYAML(t *testing.T) {
    tests := []struct {
        name     string
        args     []string
        indent   string
        expected string
    }{
        {"nil args produces no output", nil, "  ", ""},
        {"single arg", []string{"--verbose"}, "  ", ",\n  \"--verbose\""},
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            var sb strings.Builder
            writeArgsToYAML(&sb, tt.args, tt.indent)
            assert.Equal(t, tt.expected, sb.String())
        })
    }
}

5. Add Assertion Messages

Add the optional message parameter to every assert / require call so failures explain context immediately.

📋 Implementation Guidelines

Priority Order

  1. High: Add testify imports; replace all t.Fatal/t.Errorf with require/assert
  2. High: Replace for-loop contains checks with assert.Contains
  3. Medium: Refactor duplicate patterns to table-driven tests
  4. Medium: Add tests for extractCustomArgs and writeArgsToYAML
  5. Low: Add assertion messages

Best Practices from scratchpad/testing.md

  • require.* for setup steps (stops test on failure)
  • assert.* for validations (continues checking)
  • ✅ Table-driven tests with t.Run() and descriptive names

Commands

go test -v ./pkg/workflow/... -run TestArgsField
make test-unit
make lint

Acceptance Criteria

  • assert and require imported from testify
  • All t.Fatal/t.Errorf raw checks replaced with testify assertions
  • Manual for-loop contains checks replaced with assert.Contains
  • Duplicate unit patterns refactored to table-driven tests
  • New tests added for extractCustomArgs and writeArgsToYAML
  • All assertions include helpful messages
  • make test-unit passes
  • make lint passes

Priority: Medium | Effort: Small | Expected Impact: Consistent style, better failure messages, increased coverage of args.go

Files Involved: pkg/workflow/args_field_test.go, pkg/workflow/args.go

References:

Generated by 🧪 Daily Testify Uber Super Expert · ⌖ 20.3 AIC · ⊞ 21.6K ·

  • expires on Jun 12, 2026, 10:51 AM UTC-08:00

Metadata

Metadata

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