Test Organization and Coverage

Overview

Well-organized tests and good coverage help maintain code quality over time.

File Organization

mypackage/
├── user.go          # Implementation
├── user_test.go     # Tests
├── user_internal_test.go  # Internal tests
└── testdata/        # Test fixtures
    └── users.json

Package Naming

// Same package (white-box testing)
package mypackage

// External package (black-box testing)
package mypackage_test

Testdata Directory

func TestParseConfig(t *testing.T) {
    data, err := os.ReadFile("testdata/config.json")
    if err != nil {
        t.Fatal(err)
    }
    // Use data
}

Code Coverage

# Show coverage percentage
go test -cover

# Generate coverage profile
go test -coverprofile=coverage.out

# View in browser
go tool cover -html=coverage.out

# Show coverage by function
go tool cover -func=coverage.out

Coverage Modes

# Statement coverage (default)
go test -covermode=set

# Count mode (how many times)
go test -covermode=count

# Atomic (for concurrent tests)
go test -covermode=atomic

Test Groups

func TestUser(t *testing.T) {
    t.Run("Create", func(t *testing.T) {
        // Test creation
    })

    t.Run("Update", func(t *testing.T) {
        // Test update
    })

    t.Run("Delete", func(t *testing.T) {
        // Test deletion
    })
}

Skipping Tests

func TestIntegration(t *testing.T) {
    if testing.Short() {
        t.Skip("skipping in short mode")
    }
    // Long test
}
go test -short  # Skip long tests

Summary

Flag Purpose
-cover Show coverage %
-coverprofile=file Generate profile
-short Skip long tests
-run=Pattern Run matching tests