Multiple outputs
Reporting tests result to multiple outputs simultaneously may be achieved by using writer::Tee
.
extern crate cucumber; extern crate tokio; use std::{fs, io}; use cucumber::{writer, World as _, WriterExt as _}; #[derive(cucumber::World, Debug, Default)] struct World; #[tokio::main] async fn main() -> io::Result<()> { let file = fs::File::create(format!("{}/report.xml", env!("OUT_DIR")))?; World::cucumber() .with_writer( // NOTE: `Writer`s pipeline is constructed in a reversed order. writer::Basic::stdout() // And output to STDOUT. .summarized() // Simultaneously, add execution summary. .tee::<World, _>(writer::JUnit::for_tee(file, 0)) // Then, output to XML file. .normalized() // First, normalize events order. ) .run_and_exit("tests/features/book") .await; Ok(()) }
Using the same Writer
multiple times
While using writer::Tee
for different Writer
s is OK and straightforward most of the time, reusing the same Writer
multiple times isn't so obvious, because of the clap
complaining about identical CLI options (unfortunately, in a form of runtime panic only).
extern crate cucumber; extern crate tokio; use std::{fs, io}; use cucumber::{writer, World as _, WriterExt as _}; #[derive(cucumber::World, Debug, Default)] struct World; #[tokio::main] async fn main() -> io::Result<()> { let file = fs::File::create(format!("{}/report.txt", env!("OUT_DIR")))?; World::cucumber() .with_writer( writer::Basic::raw( io::stdout(), writer::Coloring::Auto, writer::Verbosity::Default, ) .tee::<World, _>(writer::Basic::raw( file, writer::Coloring::Never, 2, )) .summarized() .normalized(), ) .run_and_exit("tests/features/book") .await; Ok(()) }
thread 'main' panicked at 'Command cucumber: Argument names must be unique, but 'verbose' is in use by more than one argument or group'
To avoid this, you should manually construct the desired cli::Opts
and supply them via Cucumber::with_cli()
method. Example below uses two different writer::Basic
s, where one outputs to STDOUT and another one outputs to a file:
extern crate cucumber; extern crate tokio; use std::{fs, io}; use cucumber::{cli, writer, World as _, WriterExt as _}; #[derive(cucumber::World, Debug, Default)] struct World; #[tokio::main] async fn main() -> io::Result<()> { // Parse CLI arguments for a single `writer::Basic`. let cli = cli::Opts::<_, _, writer::basic::Cli>::parsed(); let cli = cli::Opts { re_filter: cli.re_filter, tags_filter: cli.tags_filter, parser: cli.parser, runner: cli.runner, // Replicate CLI arguments for every `writer::Basic`. writer: cli::Compose { left: cli.writer.clone(), right: cli.writer, }, custom: cli.custom, }; let file = fs::File::create(format!("{}/report.txt", env!("OUT_DIR")))?; World::cucumber() .with_writer( writer::Basic::raw( io::stdout(), writer::Coloring::Auto, writer::Verbosity::Default, ) .tee::<World, _>(writer::Basic::raw( file, writer::Coloring::Never, 2, )) .summarized() .normalized(), ) .with_cli(cli) // Supply the parsed `cli::Opts`. .run_and_exit("tests/features/book") .await; Ok(()) }