Testing Clikt Commands¶
Clikt includes the test
extension to help testing commands and their output.
@Test
fun testHello() {
val command = Hello()
val result = command.test("--name Foo")
assertEqual(result.stdout, "Hello, Foo!")
assertEqual(result.exitCode, 0)
assertEqual(command.name, "Foo")
}
class Hello: CliktCommand() {
val name by option()
override fun run() {
echo("Hello, $name!")
}
}
Calling test
will run the command with the given arguments and return a result object that contains the
captured outputs and result status code. You can check the captured output with the stdout
property of the result,
errors output with stderr
, or both combined in with output
.
Caution
Output printed with Kotlin’s print
and println
functions are not captured.
Use echo
instead.
Testing Environment Variables¶
You can set environment variables for your command by passing in a map of envvars
.
@Test
fun testHello() {
val command = Hello()
val result = command.test("", envvars=mapOf("HELLO_NAME" to "Foo"))
assertEqual(result.stdout, "Hello, Foo!")
}
class Hello: CliktCommand() {
val name by option(envvar="HELLO_NAME")
override fun run() {
echo("Hello, $name!")
}
}
To keep tests reproducible, only the envvar values you provide to test
are visible to the command. To include system
envvars as well, pass includeSystemEnvvars=true
to test
.
Testing Prompt Options¶
If you use prompt
options, you can use the stdin
parameter of test
to pass a string
containing all the lines of input. If you have multiple prompts, each input should be separated by
\n
.
@Test
fun testAdder() {
val command = Adder()
val result = command.test("", stdin = "2\n3")
assertEqual(result.stdout, "first: second: result: 2 + 3 = 5")
}
class Adder : TestCommand() {
val first by option().prompt()
val second by option().prompt()
override fun run_() {
echo("result: $first + $second = ${first + second}")
}
}
Custom Testing¶
If the test
helper doesn’t cover all the use cases you need to test, you can run your command
yourself.
If your command uses environment variables, you can configure the context to return test values for them.
To capture output, override the command’s console.
By default CliktCommand.main
, calls exitProcess
when errors occur, which would stop
tests from running. You have a couple of choices to handle this:
Configuring exitProcess
¶
CliktCommand.main
calls Context.exitProcess
to exit the process. You can set
that to an empty lambda to skip it, or one that captures the status value if you want to check it in
you tests.
Using parse
instead of main
¶
Instead of calling main
, you can use CliktCommand.parse
, which throws exceptions with
error details rather than printing the details and exiting the process. See the documentation on
exceptions for more information on the exceptions that can be thrown.