Skip to content

Commit da004f7

Browse files
committed
add control over running integration tests
1 parent 872631d commit da004f7

File tree

4 files changed

+186
-3
lines changed

4 files changed

+186
-3
lines changed

library/test/src/cli.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::env;
44
use std::path::PathBuf;
55

6-
use super::options::{ColorConfig, Options, OutputFormat, RunIgnored};
6+
use super::options::{ColorConfig, Options, OutputFormat, RunIgnored, RunIntegration};
77
use super::time::TestTimeOptions;
88
use std::io::{self, IsTerminal};
99

@@ -15,6 +15,7 @@ pub struct TestOpts {
1515
pub force_run_in_process: bool,
1616
pub exclude_should_panic: bool,
1717
pub run_ignored: RunIgnored,
18+
pub run_integration: RunIntegration,
1819
pub run_tests: bool,
1920
pub bench_benchmarks: bool,
2021
pub logfile: Option<PathBuf>,
@@ -48,6 +49,8 @@ fn optgroups() -> getopts::Options {
4849
let mut opts = getopts::Options::new();
4950
opts.optflag("", "include-ignored", "Run ignored and not ignored tests")
5051
.optflag("", "ignored", "Run only ignored tests")
52+
.optflag("", "exclude-integration", "Exclude integration tests")
53+
.optflag("", "integration", "Run only integration tests")
5154
.optflag("", "force-run-in-process", "Forces tests to run in-process when panic=abort")
5255
.optflag("", "exclude-should-panic", "Excludes tests marked as should_panic")
5356
.optflag("", "test", "Run tests and not benchmarks")
@@ -259,6 +262,7 @@ fn parse_opts_impl(matches: getopts::Matches) -> OptRes {
259262
let shuffle_seed = get_shuffle_seed(&matches, allow_unstable)?;
260263

261264
let include_ignored = matches.opt_present("include-ignored");
265+
let exclude_integration = matches.opt_present("exclude-integration");
262266
let quiet = matches.opt_present("quiet");
263267
let exact = matches.opt_present("exact");
264268
let list = matches.opt_present("list");
@@ -269,6 +273,7 @@ fn parse_opts_impl(matches: getopts::Matches) -> OptRes {
269273

270274
let logfile = get_log_file(&matches)?;
271275
let run_ignored = get_run_ignored(&matches, include_ignored)?;
276+
let run_integration = get_run_integration(&matches, exclude_integration)?;
272277
let filters = matches.free.clone();
273278
let nocapture = get_nocapture(&matches)?;
274279
let test_threads = get_test_threads(&matches)?;
@@ -284,6 +289,7 @@ fn parse_opts_impl(matches: getopts::Matches) -> OptRes {
284289
force_run_in_process,
285290
exclude_should_panic,
286291
run_ignored,
292+
run_integration,
287293
run_tests,
288294
bench_benchmarks,
289295
logfile,
@@ -465,6 +471,19 @@ fn get_run_ignored(matches: &getopts::Matches, include_ignored: bool) -> OptPart
465471
Ok(run_ignored)
466472
}
467473

474+
fn get_run_integration(matches: &getopts::Matches, exclude_integration: bool) -> OptPartRes<RunIntegration> {
475+
let run_integration = match(exclude_integration, matches.opt_present("integration")) {
476+
(true, true) => {
477+
return Err("the options --exclude-integration and --integration are mutually exclusive".into());
478+
},
479+
(true, false) => RunIntegration::No,
480+
(false, true) => RunIntegration::Only,
481+
(false, false) => RunIntegration::Yes,
482+
};
483+
484+
Ok(run_integration)
485+
}
486+
468487
fn get_allow_unstable(matches: &getopts::Matches) -> OptPartRes<bool> {
469488
let mut allow_unstable = false;
470489

library/test/src/lib.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
// Public reexports
2727
pub use self::bench::{black_box, Bencher};
2828
pub use self::console::run_tests_console;
29-
pub use self::options::{ColorConfig, Options, OutputFormat, RunIgnored, ShouldPanic};
29+
pub use self::options::{ColorConfig, Options, OutputFormat, RunIgnored, RunIntegration, ShouldPanic};
3030
pub use self::types::TestName::*;
3131
pub use self::types::*;
3232
pub use self::ColorConfig::*;
@@ -40,7 +40,7 @@ pub mod test {
4040
cli::{parse_opts, TestOpts},
4141
filter_tests,
4242
helpers::metrics::{Metric, MetricMap},
43-
options::{Options, RunIgnored, RunStrategy, ShouldPanic},
43+
options::{Options, RunIgnored, RunIntegration, RunStrategy, ShouldPanic},
4444
run_test, test_main, test_main_static,
4545
test_result::{TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk},
4646
time::{TestExecTime, TestTimeOptions},
@@ -492,6 +492,17 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescA
492492
RunIgnored::No => {}
493493
}
494494

495+
// Exclude integration tests if instructed
496+
match opts.run_integration {
497+
RunIntegration::Yes => {},
498+
RunIntegration::No => {
499+
filtered.retain(|test| test.desc.test_type != TestType::IntegrationTest);
500+
},
501+
RunIntegration::Only => {
502+
filtered.retain(|test| test.desc.test_type == TestType::IntegrationTest);
503+
}
504+
}
505+
495506
filtered
496507
}
497508

library/test/src/options.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ pub enum RunIgnored {
4545
Only,
4646
}
4747

48+
/// Whether integration tests should be run or not
49+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
50+
pub enum RunIntegration {
51+
Yes,
52+
No,
53+
Only,
54+
}
55+
4856
#[derive(Clone, Copy)]
4957
pub enum RunStrategy {
5058
/// Runs the test in the current process, and sends the result back over the

library/test/src/tests.rs

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::{
1313
DynTestName,
1414
MetricMap,
1515
RunIgnored,
16+
RunIntegration,
1617
RunStrategy,
1718
ShouldPanic,
1819
StaticTestName,
@@ -39,6 +40,7 @@ impl TestOpts {
3940
force_run_in_process: false,
4041
exclude_should_panic: false,
4142
run_ignored: RunIgnored::No,
43+
run_integration: RunIntegration::Yes,
4244
run_tests: false,
4345
bench_benchmarks: false,
4446
logfile: None,
@@ -832,3 +834,146 @@ fn test_dyn_bench_returning_err_fails_when_run_as_test() {
832834
let result = rx.recv().unwrap().result;
833835
assert_eq!(result, TrFailed);
834836
}
837+
838+
#[test]
839+
pub fn do_not_run_integration_test_if_excluded() {
840+
fn f() -> Result<(), String> {
841+
panic!();
842+
}
843+
let desc = TestDescAndFn {
844+
desc: TestDesc {
845+
name: StaticTestName("whatever"),
846+
ignore: true,
847+
ignore_message: None,
848+
should_panic: ShouldPanic::No,
849+
compile_fail: false,
850+
no_run: false,
851+
test_type: TestType::IntegrationTest,
852+
},
853+
testfn: DynTestFn(Box::new(f)),
854+
};
855+
let (tx, rx) = channel();
856+
run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx);
857+
let result = rx.recv().unwrap().result;
858+
assert_ne!(result, TrOk);
859+
}
860+
861+
862+
863+
fn one_intregration_one_unit_test_one_unknown() -> Vec<TestDescAndFn> {
864+
vec![
865+
TestDescAndFn {
866+
desc: TestDesc {
867+
name: StaticTestName("1"),
868+
ignore: false,
869+
ignore_message: None,
870+
should_panic: ShouldPanic::No,
871+
compile_fail: false,
872+
no_run: false,
873+
test_type: TestType::IntegrationTest,
874+
},
875+
testfn: DynTestFn(Box::new(move || Ok(()))),
876+
},
877+
TestDescAndFn {
878+
desc: TestDesc {
879+
name: StaticTestName("2"),
880+
ignore: false,
881+
ignore_message: None,
882+
should_panic: ShouldPanic::No,
883+
compile_fail: false,
884+
no_run: false,
885+
test_type: TestType::UnitTest,
886+
},
887+
testfn: DynTestFn(Box::new(move || Ok(()))),
888+
},
889+
TestDescAndFn {
890+
desc: TestDesc {
891+
name: StaticTestName("3"),
892+
ignore: false,
893+
ignore_message: None,
894+
should_panic: ShouldPanic::No,
895+
compile_fail: false,
896+
no_run: false,
897+
test_type: TestType::Unknown,
898+
},
899+
testfn: DynTestFn(Box::new(move || Ok(()))),
900+
},
901+
]
902+
}
903+
904+
#[test]
905+
fn parse_exclude_integration_flag() {
906+
let args = vec!["progname".to_string(), "filter".to_string(), "--exclude-integration".to_string()];
907+
let opts = parse_opts(&args).unwrap().unwrap();
908+
assert_eq!(opts.run_integration, RunIntegration::No);
909+
}
910+
911+
#[test]
912+
fn parse_integration_flag() {
913+
let args = vec!["progname".to_string(), "filter".to_string(), "--integration".to_string()];
914+
let opts = parse_opts(&args).unwrap().unwrap();
915+
assert_eq!(opts.run_integration, RunIntegration::Only);
916+
}
917+
918+
#[test]
919+
fn parse_integration_flags_not_set() {
920+
let args = vec!["progname".to_string(), "filter".to_string()];
921+
let opts = parse_opts(&args).unwrap().unwrap();
922+
assert_eq!(opts.run_integration, RunIntegration::Yes);
923+
}
924+
925+
#[test]
926+
pub fn filter_for_exclude_integration_option() {
927+
// The filter should filter out all the integration tests
928+
929+
let mut opts = TestOpts::new();
930+
opts.run_tests = true;
931+
opts.run_integration = RunIntegration::No;
932+
933+
let tests = one_intregration_one_unit_test_one_unknown();
934+
let filtered = filter_tests(&opts, tests);
935+
936+
assert_eq!(filtered.len(), 2);
937+
assert_eq!(filtered[0].desc.name.to_string(), "2");
938+
assert_eq!(filtered[0].desc.test_type, TestType::UnitTest);
939+
assert_eq!(filtered[1].desc.name.to_string(), "3");
940+
assert_eq!(filtered[1].desc.test_type, TestType::Unknown);
941+
}
942+
943+
#[test]
944+
pub fn filter_for_integration_option() {
945+
// When we run integrations tests the test filter should filter out all the
946+
// non-integration tests
947+
948+
let mut opts = TestOpts::new();
949+
opts.run_tests = true;
950+
opts.run_integration = RunIntegration::Only;
951+
952+
let tests = one_intregration_one_unit_test_one_unknown();
953+
let filtered = filter_tests(&opts, tests);
954+
955+
assert_eq!(filtered.len(), 1);
956+
assert_eq!(filtered[0].desc.name.to_string(), "1");
957+
assert_eq!(filtered[0].desc.test_type, TestType::IntegrationTest);
958+
}
959+
960+
#[test]
961+
pub fn filter_for_integration_yes_option() {
962+
// When we run integrations tests the test filter should filter out all the
963+
// non-integration tests
964+
965+
let mut opts = TestOpts::new();
966+
opts.run_tests = true;
967+
opts.run_integration = RunIntegration::Yes;
968+
969+
let tests = one_intregration_one_unit_test_one_unknown();
970+
let filtered = filter_tests(&opts, tests);
971+
972+
assert_eq!(filtered.len(), 3);
973+
assert_eq!(filtered[0].desc.name.to_string(), "1");
974+
assert_eq!(filtered[0].desc.test_type, TestType::IntegrationTest);
975+
assert_eq!(filtered[1].desc.name.to_string(), "2");
976+
assert_eq!(filtered[1].desc.test_type, TestType::UnitTest);
977+
assert_eq!(filtered[2].desc.name.to_string(), "3");
978+
assert_eq!(filtered[2].desc.test_type, TestType::Unknown);
979+
}

0 commit comments

Comments
 (0)