Cheer ships an in-process test runner that captures output and returns the handler's return value. No subprocess, no argv escaping, no port juggling.
Basic
test "greet prints a greeting" do
result = Cheer.Test.run(MyApp.CLI.Greet, ["world"])
assert result.return == :ok
assert result.output =~ "Hello, world!"
endCheer.Test.run/3 takes the same arguments as Cheer.run/3: a command
module, argv, and an optional prog.
Return shape
%Cheer.Test{
return: term(), # whatever your run/2 returned (or :ok if cheer handled an error)
output: String.t() # everything written to stdout during the invocation
}Testing validation failures
When validation fails, cheer prints an error and does not invoke run/2.
Assert on the captured output:
test "rejects out-of-range times" do
result = Cheer.Test.run(MyApp.CLI.Greet, ["world", "--times", "100"])
assert result.output =~ "must be 1-10"
refute result.output =~ "Hello"
endTesting subcommand routing
test "db migrate with a target" do
result = Cheer.Test.run(Devtool.CLI, ["db", "migrate", "--target", "20240101"])
assert result.output =~ "Migrating to version 20240101"
endSame as production: the router walks the tree, parses each level's options,
and dispatches to the leaf's run/2.
Testing help output
test "help includes all subcommands" do
result = Cheer.Test.run(Devtool.CLI, ["--help"])
assert result.output =~ "server"
assert result.output =~ "db"
endIntegration tests
For end-to-end tests that exercise the real escript binary, use the
usual System.cmd/2 against your built artifact. Cheer's test runner
is for fast, in-process unit tests of parsing and handler logic, not
for testing the escript launcher itself.
See also
- REPL mode -- interactive equivalent of the in-process runner.