6

What would be the most idiomatic way to write tests for a CLI program using clap? I'm currently doing it like this:

#[derive(Debug, Parser)]
#[clap(author, version, about)]
pub struct StructArgs {
    #[clap(subcommand)]
    pub command_type: CommandType,
}

#[derive(Debug, Subcommand)]
pub enum CommandType {
    Command1(Command1Args),
    ...
}

#[derive(Debug, Args)]
pub struct Command1Args {
    pub field: String,
    ...
}

impl Command1Args {
    ...
}

#[test]
fn test_do_stuff() {
    let args = StructArgs::try_parse_from(
        std::iter::once("<PROGRAM NAME>")
        .chain(
            ["<ARG 1>", ..., "<ARG n>"]
            .iter()
            .cloned()
        )
    );

    if let CommandType::Command1(command1_args) = args.command_type {
        // do stuff with command1_args
    } else {
        panic!();
    }
}

Basically I pass to clap an iterator of arguments, then I check if the parsed command structure matches with the CommandType I expect, and I proceed to test its methods and internal state. The panic in the else branch is for failing the test if for some reason I get an unexpected CommandType, meaning most likely that I have written something wrong in the iterator.

Can this be improved further?

rdxdkr
  • 839
  • 1
  • 12
  • 22
  • 8
    Don't test that. You're not testing your code, you're testing `clap` itself. – Chayim Friedman May 31 '22 at 16:42
  • @ChayimFriedman So testing the internal state of those structs for which I derive `clap` features would be useless as well, because I'm already trusting that `clap` is working correctly. This means that if I want to test my own methods I can just construct manually new instances of those structs with the fields I need? What about integration tests taking into account even `main()` and the whole program during its execution? – rdxdkr May 31 '22 at 17:20
  • 1
    Facing the same question myself. I think using `parse_from` is the right way forward, and in the real program, pass `std::env::args_os()` instead of your own test code. The issue with integration tests that actually launch your program, is that you cannot test just the command line args parsing. – Yoel Gluschnaider Jan 06 '23 at 09:42

0 Answers0