Examples and Tests

I just discovered how to add example binaries to a library crate thanks to Add examples to your Rust libraries

This is great, and I love the fact the examples get rebuilt automatically as part of cargo test.

That said... given that they are rebuilt, is there an idiomatic way to use them in the tests? E.g., I could run the example program with some parameters and examine its output.

To do this, (1) cargo must build the examples before running any test and (2) the examples should be in a predictable location.

(2) is trivial - the binaries are in target//examples/ which is easy enough (it does require me to detect which mode the test is being executed at).

Is (1) guaranteed though?

Unfortunately there isn't a good story for automated testing of example programs. The examples are not guaranteed to be built for an integration test. One option now is to use a separate script to drive whatever tests you want to execute (like by running cargo run --example foo -- somearg and checking the output).

A pity. It seems simple enough to just build them before the tests - is this a reasonable feature request?

Currently they are built in parallel, so doing this unconditionally would make cargo test take longer in many cases.

You can use a crate like escargot and/or assert_cmd to make your test code explicitly build and run the binaries it depends on.

1 Like

That makes sense - parallel builds/tests are important. I'll try the crates you pointed at - thanks!

Hmmm, none of them seems geared towards building example binaries. Still, I can probably do something along these lines, or just have a script that runs cargo run example ... before running cargo test.

The example method from escargot::CargoBuild will build an example binary.

How did I miss that?

To provide flags and capture the output I had to change the example there of ...exec().unwrap() to ...run().unwrap().command().args(...).output().unwrap() - took a bit of trial and error to get that incantation - but now it works perfectly.

Thanks!

This topic wouldn't be complete if not mentioning that you can add #[test]s to your examples and make sure to add cargo test --examples to test them in CI. If your main function is minimal you can arrange for everything to be tested, if wanted.