Skip to content
cjohnhansonPublic

About

Rust e2e testing framework — test scenarios as directed graphs of filesystem states

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

missouri

Show-me state. End-to-end testing as directed graphs of filesystem states.

Missouri tests a CLI tool by modeling its behavior as a directed graph of filesystem states. A state is a directory. It holds the exact files that must exist at that point in the test. A transition is a shell command. Missouri runs the command, then compares the resulting directory against the target state directory, byte for byte.

There is no assertion language. The expected state is the directory.

How it works

A test suite is a set of directories, and each directory is a state. Each state's .missouri/missouri.yml declares its transitions. A transition names a command to run and the state directory that the filesystem must match after the command. Missouri finds every path through the graph, runs each path in a temp directory with a cleared environment, and diffs the result against the target.

clean/                  # starting state (empty project)
  .missouri/
    missouri.yml        # transitions: [{command: "echo hello > out.txt", target: ../built}]
built/                  # expected state after command
  .missouri/
    missouri.yml
  out.txt               # file that should exist: contains "hello"
$ missouri run
✓ [1/1]
PASS clean → built 14ms

1 passed, 0 failed, 1 step in 14ms

A state can have several outgoing transitions, which is branching, and several states can point at the same target, which is convergence. The directory tree is the test suite.

Isolation

Every command runs with env_clear(). The process inherits no environment variable from the host. Declare every variable a test needs in the test config. The test then behaves the same on your machine and in CI.

For stronger isolation, missouri also runs a command inside a nix shell or a Docker container.

Beyond filesystem diffs

A state can also declare assertions. An assertion is a shell command, and its exit code and output decide whether it passes. A transition can declare a custom comparator for a file that a byte-for-byte diff reads wrong, and a background service for a command that needs a server running. An agent assertion hands a judgment call to an LLM.

Install

The command is missouri, whichever package you install.

Archives of precompiled binaries are available for macOS and Linux. The Linux binaries are static executables. Each archive holds the binary, its man pages, the README and the licence. There is no Windows build.

Package manager Package Command
Homebrew cjohnhanson/tap/missouri brew install cjohnhanson/tap/missouri
Cargo missouri cargo install --locked missouri
uv msri uv tool install msri
npm @cjohnhanson/msri npm install -g @cjohnhanson/msri

On Debian or Ubuntu, download the .deb from the releases page and install it:

wget https://github.com/cjohnhanson/missouri/releases/download/v0.2.3/missouri_0.2.3-1_amd64.deb
sudo dpkg -i missouri_0.2.3-1_amd64.deb

To run it once without installing anything:

uvx msri run
npx @cjohnhanson/msri run

Building

missouri is written in Rust, so you need a Rust installation to compile it. missouri compiles with Rust 1.88 or newer. A C compiler is needed as well, which aws-lc-sys uses for its cryptography.

To build missouri:

git clone https://github.com/cjohnhanson/missouri
cd missouri
cargo build --release
./target/release/missouri --version

Usage

missouri init              # set up a new project
missouri state add <name>  # create a state directory
missouri run               # execute all test paths
missouri run -v            # verbose output
missouri list              # show states, transitions, paths
missouri validate          # check graph is well-formed
missouri report            # generate a report from a recorded run
missouri docs [topic]      # bundled documentation

Documentation

Related

  • tisket. An issue tracker. Markdown issues with YAML frontmatter, in the repository.
  • zettel. Zettelkasten notes for a repository.
  • almanac. An agent skill index over pluggable sources.
  • gaff. A context-lifecycle handler for coding agents.
  • mdstore. The frontmattered markdown library that tisket, zettel, and almanac store documents with.

License

MIT.

About

Rust e2e testing framework — test scenarios as directed graphs of filesystem states

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages