gotestdox

repository·main·Indexed 42 days ago

https://github.com/bitfield/gotestdox

A command-line tool that transforms Go test results into human-readable documentation by converting CamelCase test names into plain-text sentences. It can be used as a standalone CLI to run tests or as a text filter for `go test -json` output.

Tokens
2.2K
Snippets
11
Records
15
Agent score
45%

What's inside gotestdox

  1. Format multi-word function names using underscores

    main

    By default, gotestdox converts CamelCase to space-separated sentences. If you are testing a specific function (e.g., HandleInput) and want to prevent the function name itself from being split into multiple words, use an underscore after the function name in your test name. The first underscore marks the end of the function name.

    // If you name your test like this:
    func TestHandleInput_ClosesInputAfterReading(t *testing.T) {}
    
    // gotestdox will render it as:
    // ✔ HandleInput closes input after reading
  2. Use gotestdox as a text filter via stdin

    main

    You can run go test -json manually and pipe its output into gotestdox. In this mode, gotestdox acts purely as a text filter and ignores any flags or arguments passed to it. It will still report exit status 1 if any tests fail.

    go test -json | gotestdox
  3. Run gotestdox on a Go project

    main

    To run tests in your current project and see the formatted documentation output, execute gotestdox followed by your target packages. For example, to run all tests in the current tree, use ./....

    gotestdox ./...
  4. gotestdox behavior and output features

    main

    Exit Status

    gotestdox returns exit status 1 if any tests fail. When a test fails, it prints the output messages from the offending test.

    Colour

    Passing tests are marked with a green ✔ and failing tests with a red x. Colour is automatically detected for terminals but is disabled if:

    • Output is redirected to a file.
    • The NO_COLOR environment variable is set to any value.

    Filtering

    • gotestdox only prints events about tests. It ignores benchmarks and examples.
    • Fuzz test cases are excluded from output unless they are failing.
  5. Pass arguments to go test via gotestdox

    main

    Any arguments or flags you provide to gotestdox are passed directly to the underlying go test -json command. This allows you to use standard Go test flags like -run to filter specific tests.

    gotestdox -run ParseJSON
  6. Initialize a TestDoxer with NewTestDoxer

    main

    Use NewTestDoxer() to create a new *TestDoxer instance. By default, it is configured to use os.Stdin, os.Stdout, and os.Stderr for its I/O streams. This struct holds the state of the test execution, including whether the tests passed (OK field).

    td := gotestdox.NewTestDoxer()
  7. Run Go tests using ExecGoTest

    main

    The ExecGoTest(userArgs []string) method runs the go test -json command automatically. It takes any additional arguments you would normally pass to go test (like package paths) and executes them.

    It handles the process lifecycle, captures the JSON output, and calls Filter() to process the results. If any test fails or the command returns an error, td.OK will be set to false.

    td := gotestdox.NewTestDoxer()
    // This is equivalent to running 'go test -json ./...' 
    td.ExecGoTest([]string{"./...", "-v"})
    
    if !td.OK {
        fmt.Println("Tests failed!")
    }
  8. Prettify Go test names into readable sentences

    main

    Use Prettify to convert raw Go test names (such as those produced by go test -json) into human-readable sentences. It handles camel-case transitions, underscores, and subtest separators (/) to reverse the transformations applied by the Go testing package.

    Handling Multi-word Function Names

    Because Go function names are often camel-cased, Prettify might struggle to distinguish between a function name and the rest of the test description. To resolve this ambiguity, you can insert an underscore (_) immediately after the function name in the input string. This tells Prettify to treat the preceding words as a single multi-word function name.

    Debugging

    If you need to see the internal decision-making process of the prettifier, set the GOTESTDOX_DEBUG environment variable. This will cause Prettify to output detailed logs to the DebugWriter stream.

    import "github.com/bitfield/gotestdox"
    
    // Example 1: Standard subtest
    // Input: "TestFoo/has_well-formed_output"
    // Output: "Foo has well-formed output"
    result := gotestdox.Prettify("TestFoo/has_well-formed_output")
    
    // Example 2: Resolving multi-word function names
    // Input: "TestHandleInput_ClosesInputAfterReading"
    // Output: "HandleInput closes input after reading"
    result = gotestdox.Prettify("TestHandleInput_ClosesInputAfterReading")
  9. Format test events with Event.String

    main

    The String() method on an Event returns a human-readable, prettified string. It converts the test name into a sentence and prefixes it with a status symbol:

    • ✔ (green) for ActionPass.
    • x (red) for ActionFail.

    It also appends the elapsed time in seconds (e.g., (0.01s)). Color is applied automatically if the output is a terminal and NO_COLOR is not set.

  10. Parse Go test JSON with ParseJSON

    main

    The ParseJSON(line string) (Event, error) function takes a single line of JSON text (emitted by go test -json) and unmarshals it into an Event struct. This is useful if you are implementing custom processing logic for Go test events.

    event, err := gotestdox.ParseJSON(`{"Action":"pass","Test":"TestExample","Elapsed":0.01}`)
    if err != nil {
        log.Fatal(err)
    }
  11. Process piped JSON with Filter

    main

    If you are already piping JSON data into the application (e.g., go test -json | gotestdox), use the Filter() method.

    Filter() reads from the TestDoxer.Stdin stream line by line, parses the JSON records, and prints prettified test results to TestDoxer.Stdout. It sorts tests alphabetically within each package and includes test output if a test fails. If any test fails or a parsing error occurs, td.OK is set to false.

    // Assuming td.Stdin is already populated with JSON data
    td := gotestdox.NewTestDoxer()
    td.Filter()
    
    if !td.OK {
        // Handle failure
    }