Skip to content

Commit acf7b50

Browse files
committed
Auto merge of #64663 - jakoschiko:report-time, r=alexcrichton
libtest: Add --report-time flag to print test execution time Implements the flag `--report-time` to print the execution time of each executed (successful or failed) test. Closes #46610 # Example `cargo test -- --report-time` produces the following output to stdout: ``` running 6 tests test tests::ignore ... ignored test tests::noop ... ok 0.000s test tests::should_panic ... ok 0.000s test tests::panic_after_10millis ... FAILED 0.010s test tests::sleep_100millis ... ok 0.100s test tests::sleep_10secs ... ok 10.001s failures: ---- tests::panic_after_10millis stdout ---- thread 'tests::panic_after_10millis' panicked at 'foo', src\lib.rs:31:9 failures: tests::panic_after_10millis test result: FAILED. 4 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out ``` `cargo test -- --report-time -Z unstable-options --format=json` produces the following output to stdout: ``` { "type": "suite", "event": "started", "test_count": 6 } { "type": "test", "event": "started", "name": "tests::ignore" } { "type": "test", "event": "started", "name": "tests::noop" } { "type": "test", "event": "started", "name": "tests::panic_after_10millis" } { "type": "test", "event": "started", "name": "tests::should_panic" } { "type": "test", "name": "tests::ignore", "event": "ignored" } { "type": "test", "event": "started", "name": "tests::sleep_100millis" } { "type": "test", "name": "tests::noop", "event": "ok", "exec_time": "0.000s" } { "type": "test", "event": "started", "name": "tests::sleep_10secs" } { "type": "test", "name": "tests::should_panic", "event": "ok", "exec_time": "0.000s" } { "type": "test", "name": "tests::panic_after_10millis", "event": "failed", "exec_time": "0.010s", "stdout": "thread 'tests::panic_after_10millis' panicked at 'foo', src\\lib.rs:31:9\n" } { "type": "test", "name": "tests::sleep_100millis", "event": "ok", "exec_time": "0.101s" } { "type": "test", "name": "tests::sleep_10secs", "event": "ok", "exec_time": "10.000s" } { "type": "suite", "event": "failed", "passed": 4, "failed": 1, "allowed_fail": 0, "ignored": 1, "measured": 0, "filtered_out": 0 } ``` `cargo test -- --report-time --logfile foo.log` produces the following logfile: ``` ignored tests::ignore ok tests::noop 0.000s ok tests::should_panic 0.000s failed tests::panic_after_10millis 0.010s ok tests::sleep_100millis 0.100s ok tests::sleep_10secs 10.001s ```
2 parents c7bc0bf + d91b965 commit acf7b50

File tree

6 files changed

+168
-48
lines changed

6 files changed

+168
-48
lines changed

src/libtest/formatters/json.rs

+26-6
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,20 @@ impl<T: Write> JsonFormatter<T> {
2727
ty: &str,
2828
name: &str,
2929
evt: &str,
30+
exec_time: Option<&TestExecTime>,
3031
stdout: Option<Cow<'_, str>>,
3132
extra: Option<&str>,
3233
) -> io::Result<()> {
3334
self.write_message(&*format!(
3435
r#"{{ "type": "{}", "name": "{}", "event": "{}""#,
3536
ty, name, evt
3637
))?;
38+
if let Some(exec_time) = exec_time {
39+
self.write_message(&*format!(
40+
r#", "exec_time": "{}""#,
41+
exec_time
42+
))?;
43+
}
3744
if let Some(stdout) = stdout {
3845
self.write_message(&*format!(
3946
r#", "stdout": "{}""#,
@@ -69,6 +76,7 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
6976
&mut self,
7077
desc: &TestDesc,
7178
result: &TestResult,
79+
exec_time: Option<&TestExecTime>,
7280
stdout: &[u8],
7381
state: &ConsoleTestState,
7482
) -> io::Result<()> {
@@ -78,24 +86,36 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
7886
None
7987
};
8088
match *result {
81-
TrOk => self.write_event("test", desc.name.as_slice(), "ok", stdout, None),
89+
TrOk => {
90+
self.write_event("test", desc.name.as_slice(), "ok", exec_time, stdout, None)
91+
}
8292

83-
TrFailed => self.write_event("test", desc.name.as_slice(), "failed", stdout, None),
93+
TrFailed => {
94+
self.write_event("test", desc.name.as_slice(), "failed", exec_time, stdout, None)
95+
}
8496

8597
TrFailedMsg(ref m) => self.write_event(
8698
"test",
8799
desc.name.as_slice(),
88100
"failed",
101+
exec_time,
89102
stdout,
90103
Some(&*format!(r#""message": "{}""#, EscapedString(m))),
91104
),
92105

93-
TrIgnored => self.write_event("test", desc.name.as_slice(), "ignored", stdout, None),
94-
95-
TrAllowedFail => {
96-
self.write_event("test", desc.name.as_slice(), "allowed_failure", stdout, None)
106+
TrIgnored => {
107+
self.write_event("test", desc.name.as_slice(), "ignored", exec_time, stdout, None)
97108
}
98109

110+
TrAllowedFail => self.write_event(
111+
"test",
112+
desc.name.as_slice(),
113+
"allowed_failure",
114+
exec_time,
115+
stdout,
116+
None,
117+
),
118+
99119
TrBench(ref bs) => {
100120
let median = bs.ns_iter_summ.median as usize;
101121
let deviation = (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as usize;

src/libtest/formatters/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub(crate) trait OutputFormatter {
1616
&mut self,
1717
desc: &TestDesc,
1818
result: &TestResult,
19+
exec_time: Option<&TestExecTime>,
1920
stdout: &[u8],
2021
state: &ConsoleTestState,
2122
) -> io::Result<()>;

src/libtest/formatters/pretty.rs

+17-12
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,20 @@ impl<T: Write> PrettyFormatter<T> {
3030
&self.out
3131
}
3232

33-
pub fn write_ok(&mut self) -> io::Result<()> {
34-
self.write_short_result("ok", term::color::GREEN)
33+
pub fn write_ok(&mut self, exec_time: Option<&TestExecTime>) -> io::Result<()> {
34+
self.write_short_result("ok", term::color::GREEN, exec_time)
3535
}
3636

37-
pub fn write_failed(&mut self) -> io::Result<()> {
38-
self.write_short_result("FAILED", term::color::RED)
37+
pub fn write_failed(&mut self, exec_time: Option<&TestExecTime>) -> io::Result<()> {
38+
self.write_short_result("FAILED", term::color::RED, exec_time)
3939
}
4040

41-
pub fn write_ignored(&mut self) -> io::Result<()> {
42-
self.write_short_result("ignored", term::color::YELLOW)
41+
pub fn write_ignored(&mut self, exec_time: Option<&TestExecTime>) -> io::Result<()> {
42+
self.write_short_result("ignored", term::color::YELLOW, exec_time)
4343
}
4444

45-
pub fn write_allowed_fail(&mut self) -> io::Result<()> {
46-
self.write_short_result("FAILED (allowed)", term::color::YELLOW)
45+
pub fn write_allowed_fail(&mut self, exec_time: Option<&TestExecTime>) -> io::Result<()> {
46+
self.write_short_result("FAILED (allowed)", term::color::YELLOW, exec_time)
4747
}
4848

4949
pub fn write_bench(&mut self) -> io::Result<()> {
@@ -54,8 +54,12 @@ impl<T: Write> PrettyFormatter<T> {
5454
&mut self,
5555
result: &str,
5656
color: term::color::Color,
57+
exec_time: Option<&TestExecTime>,
5758
) -> io::Result<()> {
5859
self.write_pretty(result, color)?;
60+
if let Some(exec_time) = exec_time {
61+
self.write_plain(format!(" {}", exec_time))?;
62+
}
5963
self.write_plain("\n")
6064
}
6165

@@ -166,6 +170,7 @@ impl<T: Write> OutputFormatter for PrettyFormatter<T> {
166170
&mut self,
167171
desc: &TestDesc,
168172
result: &TestResult,
173+
exec_time: Option<&TestExecTime>,
169174
_: &[u8],
170175
_: &ConsoleTestState,
171176
) -> io::Result<()> {
@@ -174,10 +179,10 @@ impl<T: Write> OutputFormatter for PrettyFormatter<T> {
174179
}
175180

176181
match *result {
177-
TrOk => self.write_ok(),
178-
TrFailed | TrFailedMsg(_) => self.write_failed(),
179-
TrIgnored => self.write_ignored(),
180-
TrAllowedFail => self.write_allowed_fail(),
182+
TrOk => self.write_ok(exec_time),
183+
TrFailed | TrFailedMsg(_) => self.write_failed(exec_time),
184+
TrIgnored => self.write_ignored(exec_time),
185+
TrAllowedFail => self.write_allowed_fail(exec_time),
181186
TrBench(ref bs) => {
182187
self.write_bench()?;
183188
self.write_plain(&format!(": {}\n", fmt_bench_samples(bs)))

src/libtest/formatters/terse.rs

+1
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ impl<T: Write> OutputFormatter for TerseFormatter<T> {
174174
&mut self,
175175
desc: &TestDesc,
176176
result: &TestResult,
177+
_: Option<&TestExecTime>,
177178
_: &[u8],
178179
_: &ConsoleTestState,
179180
) -> io::Result<()> {

0 commit comments

Comments
 (0)