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.
In unit tests, you won’t want to use CliktCommand.main
, since it calls exitProcess
when errors occur.
Instead, you should instead 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.
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.