Skip to content

Commit

Permalink
Cargo test quicker by not building untested examples when filtered
Browse files Browse the repository at this point in the history
  • Loading branch information
dwijnand committed Feb 25, 2019
1 parent aef99e0 commit 110c813
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 16 deletions.
31 changes: 21 additions & 10 deletions src/bin/cargo/commands/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,17 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {

let mut compile_opts = args.compile_options(config, CompileMode::Test, Some(&ws))?;

// `TESTNAME` is actually an argument of the test binary, but it's
// important, so we explicitly mention it and reconfigure.
let test_name: Option<&str> = args.value_of("TESTNAME");
let mut test_args = vec![];
test_args.extend(test_name.into_iter().map(|s| s.to_string()));
test_args.extend(
args.values_of("args")
.unwrap_or_default()
.map(|s| s.to_string()),
);

let no_run = args.is_present("no-run");
let doc = args.is_present("doc");
if doc {
Expand All @@ -117,6 +128,16 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
FilterRule::none(),
FilterRule::none(),
);
} else if test_name.is_some() {
if let CompileFilter::Default { .. } = compile_opts.filter {
compile_opts.filter = ops::CompileFilter::new(
LibRule::Default, // compile the library, so the unit tests can be run filtered
FilterRule::All, // compile the binaries, so the unit tests in binaries can be run filtered
FilterRule::All, // compile the tests, so the integration tests can be run filtered
FilterRule::none(), // specify --examples to unit test binaries filtered
FilterRule::none(), // specify --benches to unit test benchmarks filtered
); // also, specify --doc to run doc tests filtered
}
}

let ops = ops::TestOptions {
Expand All @@ -125,16 +146,6 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
compile_opts,
};

// `TESTNAME` is actually an argument of the test binary, but it's
// important, so we explicitly mention it and reconfigure.
let mut test_args = vec![];
test_args.extend(args.value_of("TESTNAME").into_iter().map(|s| s.to_string()));
test_args.extend(
args.values_of("args")
.unwrap_or_default()
.map(|s| s.to_string()),
);

let err = ops::run_tests(&ws, &ops, &test_args)?;
match err {
None => Ok(()),
Expand Down
1 change: 0 additions & 1 deletion tests/testsuite/freshness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,6 @@ fn changing_profiles_caches_targets() {
"\
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] target[..]debug[..]deps[..]foo-[..][EXE]
[DOCTEST] foo
",
)
.run();
Expand Down
42 changes: 37 additions & 5 deletions tests/testsuite/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ fn cargo_test_verbose() {
[COMPILING] foo v0.5.0 ([CWD])
[RUNNING] `rustc [..] src/main.rs [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `[..]target/debug/deps/foo-[..][EXE] hello`",
[RUNNING] `[CWD]/target/debug/deps/foo-[..] hello`
",
)
.with_stdout_contains("test test_hello ... ok")
.run();
Expand Down Expand Up @@ -601,21 +602,21 @@ fn pass_through_command_line() {
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] target/debug/deps/foo-[..][EXE]
[DOCTEST] foo",
",
)
.with_stdout_contains("running 1 test")
.with_stdout_contains("test bar ... ok")
.with_stdout_contains("running 0 tests")
.run();

p.cargo("test foo")
.with_stderr(
"\
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] target/debug/deps/foo-[..][EXE]
[DOCTEST] foo",
",
)
.with_stdout_contains("running 1 test")
.with_stdout_contains("test foo ... ok")
.with_stdout_contains("running 0 tests")
.run();
}

Expand Down Expand Up @@ -1462,6 +1463,37 @@ fn test_run_implicit_example_target() {
.run();
}

#[test]
fn test_filtered_excludes_compiling_examples() {
let p = project()
.file(
"src/lib.rs",
"#[cfg(test)] mod tests { #[test] fn foo() { assert!(true); } }",
)
.file("examples/ex1.rs", "fn main() {}")
.build();

p.cargo("test -v foo")
.with_stdout(
"
running 1 test
test tests::foo ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
",
)
.with_stderr("\
[COMPILING] foo v0.0.1 ([CWD])
[RUNNING] `rustc --crate-name foo src/lib.rs [..] --test [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `[CWD]/target/debug/deps/foo-[..] foo`
",
)
.with_stderr_does_not_contain("[RUNNING][..]rustc[..]ex1[..]")
.run();
}

#[test]
fn test_no_harness() {
let p = project()
Expand Down

0 comments on commit 110c813

Please sign in to comment.