# Testing with tmux

Source: https://libtmux.org/en/tmux/guides/testing-with-libtmux/

> Test on a private tmux server and preserve errors during cleanup.

Give each test its own tmux socket. Start it with a known configuration, assert
the state your program needs, and stop only the server the test owns. This keeps
a test run separate from your interactive sessions.

## Run an isolated test

This complete shell test creates a session and a window, checks their names,
and prints `tmux fixture passed` on success. It requires tmux 3.2a or newer and
a POSIX shell. Save it as `test-tmux.sh`.

```sh title="test-tmux.sh"
#!/bin/sh
set -eu
directory=$(mktemp -d "${TMPDIR:-/tmp}/libtmux-guide.XXXXXX")
socket="$directory/tmux.sock"

cleanup() {
    status=$?
    trap - 0 HUP INT TERM
    if [ -S "$socket" ] && ! tmux -S "$socket" kill-server; then
        printf 'Cannot stop tmux; kept %s\n' "$directory" >&2
        exit 1
    fi
    rm -rf "$directory" || status=$?
    exit "$status"
}
trap cleanup 0
trap 'exit 1' HUP INT TERM

tmux -S "$socket" -f /dev/null new-session -d -s fixture -n main 'cat'
tmux -S "$socket" new-window -t fixture: -n worker 'cat'
name=$(tmux -S "$socket" display-message -p -t fixture:worker '#{session_name}')
if [ "$name" != fixture ]; then
    printf 'Expected fixture, got %s.\n' "$name" >&2
    exit 1
fi
windows=$(tmux -S "$socket" list-windows -t '=fixture' -F '#{window_name}')
if ! printf '%s\n' "$windows" | grep -Fqx worker; then
    printf '%s\n' 'The worker window was not created.' >&2
    exit 1
fi
printf '%s\n' 'tmux fixture passed'
```

Run the saved script:

```console
$ sh test-tmux.sh
```

The trap preserves a failed assertion's exit status and also reports cleanup
failures. If the server cannot be stopped, its socket directory stays available
for inspection. Each invocation gets a fresh directory from `mktemp`.

## Wait for the state you assert

A successful `send-keys` call establishes that tmux accepted input, not that the
application finished processing it. For output assertions, use a bounded wait
such as the [complete capture example](https://libtmux.org/en/tmux/examples/capture-pane-output/). A fixed
pause alone cannot establish that the result arrived.

<a id="java-docs-tests"></a>

## Use a language test fixture

Language ports have different fixture and lifetime APIs. Select a port from
the dropdown for its testing guidance. The complete programs below demonstrate
creating a private server, checking a result and cleaning up through that port:

[Python](https://libtmux.org/en/py/latest/examples/capture-pane-output/) ·
[TypeScript](https://libtmux.org/en/ts/latest/examples/capture-pane-output/) ·
[Go](https://libtmux.org/en/go/latest/examples/capture-pane-output/) ·
[Rust](https://libtmux.org/en/rs/latest/examples/capture-pane-output/) ·
[Java](https://libtmux.org/en/java/latest/examples/capture-pane-output/) ·
[Kotlin](https://libtmux.org/en/kotlin/latest/examples/capture-pane-output/) ·
[Scala](https://libtmux.org/en/scala/latest/examples/capture-pane-output/) ·
[C#](https://libtmux.org/en/csharp/latest/examples/capture-pane-output/) ·
[F#](https://libtmux.org/en/fsharp/latest/examples/capture-pane-output/) ·
[C++](https://libtmux.org/en/cxx/latest/examples/capture-pane-output/) ·
[Swift](https://libtmux.org/en/swift/latest/examples/capture-pane-output/) ·
[Ruby](https://libtmux.org/en/ruby/latest/examples/capture-pane-output/) ·
[Lua](https://libtmux.org/en/lua/latest/examples/capture-pane-output/)

## Where to go next

[Attaching to tmux](https://libtmux.org/en/tmux/guides/attaching-to-tmux/) connects to a server that should remain
running. [Querying and filtering](https://libtmux.org/en/tmux/guides/querying-and-filtering/) selects an exact
target, and [Capturing output](https://libtmux.org/en/tmux/guides/capturing-output/) reads its screen.

## tmux reference

See [new-session](https://libtmux.org/en/tmux/latest/manual/new-session/),
[new-window](https://libtmux.org/en/tmux/latest/manual/new-window/), and
[kill-server](https://libtmux.org/en/tmux/latest/manual/kill-server/) for the commands used by the
fixture. The [global options](https://libtmux.org/en/tmux/latest/manual/full/#DESCRIPTION)
describe socket selection and configuration files.

The [tmux manual](https://github.com/tmux/tmux/blob/94796f6b1182507efac8a272fc309a79e22e58a5/tmux.1)
documents these commands and their flags.
