❯ go-clikit
v0.10.0 pkg.go.dev ↗

guides › test what a command reports

Test what a command reports

Check the spans a command reports, and the text a display draws, in a Go test, with progresstest.

The progress of a command is part of what it does. A test can check it as it checks the result: which spans started, how each ended, and that the events keep every promise of the vocabulary.

Procedure#

  1. Call progresstest.Watch with the context of the test. It returns a context with a Bus, and a progresstest.Watcher.
  2. Run the code under test with that context.
  3. Compare the tree of the Watcher with the tree you expect. Targets that read the same fold into one line, so the tree is the same however the work was scheduled.
  4. Call Finish. It checks every rule of the events. A test that does not call it is checked when it ends.
_ = func(t *testing.T) {
	ctx, w := progresstest.Watch(t.Context(), t)
	_ = reset(ctx, []string{"exe1", "exe2", "exe3"})
	want := `step reset the machines total=3 [fold]: failed (target): exe3: no answer
  target exe3: failed (target): {}: no answer
  target exe[1-2]: ok
`
	if got := w.Finish(); got != want {
		t.Errorf("the work reported\n%s\nwant\n%s", got, want)
	}
}
ExampleWatch in progress/progresstest/example_test.go. CI compiles it.
NOTE

The rules that progresstest.Check enforces are an interface (decision 15). A new or stricter rule is a breaking change, so a test that passes today does not fail after a minor release for a rule.

Test what a display draws#

A progresstest.Screen is a terminal in memory. It applies the cursor moves and erases that a display writes, and shows what a person would see. With Styles set, it records the colours of each run of text too.

screen := &progresstest.Screen{}
fmt.Fprint(screen, "uptime · 1/3 · 0:01")
fmt.Fprint(screen, "\r\x1b[2Kuptime · 3/3 · 0:02\n")
fmt.Fprint(screen, "\x1b[?25l")
fmt.Println(screen.String())
uptime · 3/3 · 0:02
^[[?25l
ExampleScreen in progress/progresstest/example_test.go. CI runs it and checks its output.

The recordings on this site come from a Screen. A test of the site checks them against the displays, so they show what the code draws.