Skip to content

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.