# Write Unit Tests for a Go Project

Yes. An agent runs Go coverage, adds testing package tests for the least-covered logic files, and opens a pull request with the delta.

[Run this on Rush](https://cloud.getrush.ai/run/write-unit-tests/go/), in a Project that has your repository.

## What the agent does

The agent inspects the module and the tests that already exist. In charmbracelet/glow it reads `go.mod` (`module charm.land/glow/v3`, Go `1.26.7`), `Taskfile.yaml` (`task test` runs `go test ./...`), and the small set of `*_test.go` files: `glow_test.go`, `url_test.go`, `utils/textsize_test.go`, and under `ui/` (`ui_test.go`, `pager_test.go`, `rawpaint_test.go`). Large logic files with little or no direct coverage include `main.go` (Cobra command wiring, readme discovery), `ui/stash.go`, `ui/pager.go`, `ui/ui.go`, `github.go` / `gitlab.go` (README API lookup), `url.go` (`readmeURL` for `github://` and `gitlab://` schemes), and `style.go`.

It runs `go test ./... -coverprofile=coverage.out` (or `task test` with cover flags) and ranks packages by coverage, skipping generated or pure wiring when the logic lives elsewhere. The five files it picks are ones with real branches: URL scheme parsing in `url.go`, GitHub/GitLab README JSON parsing, stash sorting helpers, text size utilities not already claimed by `textsize_test.go`, and error paths in `utils/utils.go`.

New tests use the standard `testing` package and table-driven cases. Where code talks to the network (`http.Get` in `findGitHubREADME`), the agent injects an `httptest.Server` or extracts the parse path so the test does not need the public API. TUI code under `ui/` is tested at the helper level (keys, sorting, raw paint) rather than driving a full Bubble Tea session unless a lightweight pattern already exists in `ui_test.go`.

It re-runs coverage, writes before/after numbers into the pull request description, and leaves production `.go` files unchanged unless a test reveals a bug worth fixing (named in the description). `go test ./...` must pass before the pull request opens. When `Taskfile.yaml` is present it also confirms `task test` still invokes the same package set, so contributors who use Task see the new cases without a second command list.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "Run the test suite with coverage, pick the five least-covered files that hold real logic, and write Go testing tests for them that exercise behaviour, not implementation details. Do not change production code unless a test reveals a bug; if it does, say so in the description. Open a pull request with the coverage before and after.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

What comes back is a pull request on a new branch. In a Glow-shaped module it adds `*_test.go` files next to the packages under test (for example more cases beside `url_test.go`, or new tests for `github.go` parsing with `httptest`). Module path and Go version stay as in `go.mod`.

The description lists the five files, coverage before and after from `go tool cover -func`, and any bug fix that had to land. The trajectory keeps the full `go test` output, including which packages were skipped as pure wiring.

Before merging, a reviewer checks that network calls are stubbed, that tests assert behaviour (parsed URLs, error strings, sort order) rather than private struct fields, and that `task test` / `go test ./...` stays green. Once merged, existing CI workflows pick up the new files without a workflow edit unless the project had no test job at all.

## Run it on every Monday morning

Schedule a weekly job that sends this request against each Go module you care about. Each run opens its own pull request with the coverage delta for that module's thinnest files.

Collect `run.completed` on the API key webhook and fan the pull request URLs into your eng channel. Stay inside `max_concurrent` when many modules share one key.

## Why run it on Rush?

Go coverage is quick, but chasing TUI and HTTP edge cases still means a dirty worktree and repeated `go test` loops on your laptop. On Rush the agent owns that loop in a sandbox with the module's Go version, stubs network boundaries, and returns a pull request that already passes.

The coverage delta in the description is the proof. You can run the same job across a fleet of Go CLIs without checking out each one locally.

## Frequently asked questions

### Will it try to drive the full Bubble Tea UI?

Only if an existing test shows a stable pattern for it. Otherwise it tests pure helpers and URL/API parsing, which is where Glow's uncovered branches usually sit.

### Does it need network access to GitHub?

Tests should not. The agent uses `httptest` or fixture JSON for README API responses so `go test ./...` works offline in CI.

### testify or stdlib testing?

It follows the repository. Glow's existing tests use the standard library, so new tests stay on `testing` and table-driven subtests unless the module already imports testify.

### What Go version runs in the sandbox?

The version in `go.mod` (Glow currently names `1.26.7`). The agent does not downgrade the module to match an older toolchain.
