# Testing

> Write the App's tests with Go's testing package, and run them with act test, which prints failures, runs failed tests again and runs on every change.

This guide covers testing a Tinka App. You will learn how to:

- Run the App's tests with `act test`
- Run some of the tests, with `go test`'s flags
- Run only the tests that failed last time
- Run the tests on every change
- Read the results as an agent

## Overview

A Tinka App's tests are Go tests: functions named `TestXxx` in `_test.go` files, using the standard library's `testing` package, run by `go test`. Nothing about them is specific to Tinka, so every editor, coverage tool and CI system that knows Go runs them.

`act test` runs `go test` for you, with the same flags and the same cache. It tests the whole App by default, prints failures the way `go test` does, remembers which tests failed so you can run only them again, and runs the tests again on every change. It prints the `go test` command it runs first, so you can always run the same thing without it.

## Run the tests

Run `act test` from the App's directory:

```sh
act test
```

```text title="Output"
$ GOWORK=off go test -json ./...
--- FAIL: TestTitle (0.00s)
    --- FAIL: TestTitle/empty (0.00s)
        posts_test.go:8: an empty title was accepted
FAIL
FAIL	example.com/blog/posts	0.005s
ok  	example.com/blog/users	0.004s
Error: 1 test failed.
  Fix: Run act test --failed to run only them again
```

`act test` runs `go test` with `-json` and prints what `go test` prints without it, so it can read the results as they come. A package whose code and tests haven't changed since its last passing run comes from `go test`'s cache, marked `(cached)`, and takes no time.

Running the tests runs the App's code, so the first time, `act` asks whether you trust the App's directory. See [act trust](../../reference/commands.md#act-trust).

## Run some of the tests

Flags and packages after `act test` go to `go test`, as they are. Without packages, `act test` tests the whole App:

```sh
act test -run TestPublish ./posts
act test -v -count=1 ./...
```

`-run` selects tests by name, `-v` prints every test's output, and `-count=1` runs tests whose results are cached. See `go help testflag` for the rest.

## Run failed tests again

`act test` remembers the tests that failed. `--failed` runs only them, in the packages they failed in:

```sh
act test --failed
```

Once they pass, `act test --failed` has nothing left to run, and says so.

## Run the tests on every change

`--watch` runs the tests, then again each time a Go file, a test or a file under `testdata` changes, until you press Ctrl+C:

```sh
act test --watch
```

`go test`'s cache makes each run cost only the packages your change affects.

## Read results as an agent

When an agent runs `act test`, or with `--json`, it prints one JSON result: how many tests passed, failed and were skipped, in how many packages, and how many came from the cache. A failed run fails with the code `tests_failed`, or `build_failed` when a package doesn't compile, and carries the same counts in `error.details`, with each failed test and the last lines it printed:

```text title="Output"
{"command":"test","result":"error","error":{"code":"tests_failed","message":"1 test failed","fix":"Run act test --failed to run only them again","details":{"passed":1,"failed":2,"skipped":0,"packages":1,"cached":0,"failures":[{"package":"example.com/blog/posts","test":"TestTitle/empty","output":"--- FAIL: TestTitle/empty (0.00s)\n    posts_test.go:8: an empty title was accepted\n"}],"go_command":"GOWORK=off go test -json ./..."}},"log":"/tmp/act-2741.log","tail":"--- FAIL: TestTitle (0.00s)\n    --- FAIL: TestTitle/empty (0.00s)\n        posts_test.go:8: an empty title was accepted\nFAIL\nFAIL\texample.com/blog/posts\t0.005s","duration_ms":319}
```

`failed` counts a failing subtest and its parent, while `failures` lists only the subtest, since it says what went wrong.

See also: [Console tests](commands.md), [Commands reference](../../reference/commands.md#act-test)
