Skip to content

Testing

This document outlines how to run tests and the conventions for writing new tests in spoofdpi.

Running Tests

To run tests that do not require network access, use the standard go test command from the root directory:

$ go test ./...

To run all tests, including tests that require network access, pass the network build tag:

$ go test -tags network ./...

To run all tests with verbose output (showing all test names):

$ go test -v -tags network ./...

To run a specific test function (e.g., TestCreateCommand_Flags):

$ go test -v -run TestCreateCommand_Flags ./internal/config/

Conventions

spoofdpi uses the standard testing package enhanced by testify for assertions and requirements.

1. Framework

  • Use testify/assert for general assertions where a failure should record an error but continue the test.
  • Use testify/require for checks that must pass for the rest of the test to proceed (e.g., checking for errors after a function call, ensuring setup was successful).
import (
    "testing"
    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/require"
)

func TestExample(t *testing.T) {
    result, err := SomeFunction()

    // Stop immediately if there's an error
    require.NoError(t, err)

    // Assert the result, but continue even if it fails
    assert.Equal(t, "expected", result)
}

2. Table-Driven Tests

For testing multiple scenarios of the same logic, table-driven tests are strongly preferred. This keeps the test code clean and makes it easy to add new cases.

func TestCalculation(t *testing.T) {
    tcs := []struct {
        name     string
        input    int
        expected int
    }{
        {
            name:     "positive number",
            input:    5,
            expected: 10,
        },
        {
            name:     "zero",
            input:    0,
            expected: 0,
        },
    }

    for _, tc := range tcs {
        t.Run(tc.name, func(t *testing.T) {
            result := calculate(tc.input)
            assert.Equal(t, tc.expected, result)
        })
    }
}

3. Naming

  • Test functions should start with Test followed by the name of the function or feature being tested (e.g., TestCreateCommand).
  • Use clear and descriptive names for table-driven test cases (e.g., name: "default values (no flags)").