gopher

End-to-End Testing Guide

Version: v1.0.0
Last Updated: October 15, 2025

Complete guide to Gopher’s end-to-end testing suite.


🎯 Overview

E2E tests verify that the entire Gopher application works correctly by:


πŸš€ Quick Start

Run E2E Tests Locally:

# Build and run E2E tests
make test-e2e

# Run all tests (unit + e2e)
make test-all

# Run with verbose output
go test ./test -run TestE2E -v

Run on Specific Platform:

# Tests run on your current OS/architecture automatically
# For cross-platform testing, use GitHub Actions test-matrix

πŸ“‹ Test Coverage

TestE2E_FullWorkflow - Complete User Journey

Tests all core commands:

Command What It Tests
gopher version Version display works
gopher help Help text displays
gopher list Lists installed versions
gopher system Shows system Go info
gopher current Shows active version
gopher list-remote Remote version listing
gopher list-remote --filter Version filtering
gopher --json list JSON output format
gopher env list Environment configuration
gopher alias list Alias listing (empty state)

Tests: 10 scenarios
Time: ~2s
Platform: All (Linux, macOS, Windows)


TestE2E_AliasWorkflow - Alias System

Tests alias management:

Command What It Tests
gopher alias Alias help display
gopher alias list List aliases (empty/populated)
gopher alias suggest Alias name suggestions

Tests: 3 scenarios
Time: ~0.25s
Platform: All


TestE2E_ErrorHandling - Error Cases

Tests error handling:

Scenario What It Tests
Invalid command Unknown command handling
Invalid version Version validation
Missing arguments Argument validation
Reserved names Name reservation

Tests: 4 scenarios
Time: ~0.16s
Platform: All


πŸ”§ Test Architecture

How It Works:

// 1. Build real gopher binary
buildGopher(t)

// 2. Get binary path (handles .exe on Windows)
gopherPath := getGopherPath(t)

// 3. Set up isolated environment
tmpDir := t.TempDir()
os.Setenv("GOPHER_CONFIG", filepath.Join(tmpDir, "config.json"))

// 4. Run actual commands
output := runGopher(t, gopherPath, "version")

// 5. Verify output
if !strings.Contains(output, "gopher") {
    t.Error("Unexpected output")
}

Isolation:


πŸ“Š Test Matrix (CI)

Platforms Tested:

OS Go Versions Architecture Total
Ubuntu 1.20, 1.21, 1.22, 1.23 amd64 4 tests
macOS 1.21, 1.22, 1.23 amd64, arm64 3 tests
Windows 1.21, 1.22, 1.23 amd64 3 tests
Total Β  Β  10 combinations

CI Runtime: ~20 minutes (parallel)


🎯 What E2E Tests Cover

βœ… Covered:

❌ Not Covered (Too Slow/Large for E2E):

Note: These are covered by integration tests and manual testing


πŸ” Running Tests

All Tests:

# Unit + E2E
make test-all

# Just unit tests
make test

# Just E2E tests
make test-e2e

Specific E2E Test:

# Run specific test
go test ./test -run TestE2E_FullWorkflow -v

# Run specific subtest
go test ./test -run TestE2E_FullWorkflow/version -v

Skip E2E Tests:

# Short mode skips E2E tests
go test -short ./test

# They're slow, so short mode is useful for quick iteration

πŸ“ Adding New E2E Tests

1. Create Test Function:

func TestE2E_MyNewFeature(t *testing.T) {
    if testing.Short() {
        t.Skip("Skipping E2E test in short mode")
    }

    buildGopher(t)
    gopherPath := getGopherPath(t)

    // Set up isolated environment
    tmpDir := t.TempDir()
    os.Setenv("GOPHER_CONFIG", filepath.Join(tmpDir, "config.json"))

    t.Run("my_scenario", func(t *testing.T) {
        output := runGopher(t, gopherPath, "my-command", "--my-flag")
        
        if !strings.Contains(output, "expected text") {
            t.Errorf("Unexpected output: %s", output)
        }
    })
}

2. Run Test:

go test ./test -run TestE2E_MyNewFeature -v

3. Add to Documentation:


πŸ› Debugging E2E Tests

Test Fails Locally:

# Run with verbose output
go test ./test -run TestE2E_FullWorkflow -v

# Check specific subtest
go test ./test -run TestE2E_FullWorkflow/version -v

# Run gopher command manually
./build/gopher version

Test Fails in CI:

# Reproduce CI environment
make ci

# Check test-matrix logs on GitHub
# Look for the specific OS/Go version combination that failed

Binary Not Found:

# Ensure build directory exists
make build

# Check binary was created
ls -la build/gopher*

πŸ“Š Performance

Test Suite Tests Time Can Skip?
Unit tests ~50 ~9s ❌ No
E2E tests ~17 ~3s βœ… Yes (with -short)
Total ~67 ~12s Β 

CI Impact: +3s per platform (acceptable)


βœ… CI Integration

test-matrix.yml runs E2E tests on:

Total: 10 platform/version combinations

Workflow:

- name: Run unit tests
  run: go test -v ./...

- name: Build
  run: go build -v -o build/gopher ./cmd/gopher

- name: Run E2E tests
  run: go test ./test -run TestE2E -v

🎯 Best Practices

DO:

DON’T:


πŸ“š Test Scenarios

Happy Path:

// All commands work as expected
gopher version      β†’ Shows version
gopher help         β†’ Shows help
gopher list         β†’ Lists versions
gopher alias list   β†’ Lists aliases

Edge Cases:

// Empty states
gopher alias list   β†’ "No aliases found"

// Invalid input
gopher install bad  β†’ Error
gopher alias create system 1.22 β†’ Error (reserved name)

Cross-Platform:

// Binary name varies by OS
Windows: gopher.exe
Unix:    gopher

// Paths vary by OS
Windows: %USERPROFILE%\gopher
Unix:    ~/.gopher

πŸš€ Future E2E Tests

Consider adding:

Tradeoff: More coverage vs slower tests


βœ… Summary

E2E Tests Provide:

Current Coverage:

Status: Production ready for v1.0.0 βœ…



Version: v1.0.0
Status: Production ready βœ