Skip to content

Commit e970af1

Browse files
satylogincopybara-github
authored andcommitted
PUBLIC: add_failure_at!() macro implementation for non fatal failure in tests
This is the rust equivalent for[] used to generate **non-fatal** failures at invocation location marking the tests as failed but allowing function execution to **continue**. In order to use this the test must have `#[googletest::test]` attribute. PiperOrigin-RevId: 625949442
1 parent 8cd9288 commit e970af1

9 files changed

+231
-4
lines changed

googletest/src/assertions.rs

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ macro_rules! verify_pred {
291291
/// [`and_log_failure`](crate::GoogleTestSupport::and_log_failure).
292292
#[macro_export]
293293
macro_rules! fail {
294-
($($message:expr),+) => {{
294+
($($message:expr),+ $(,)?) => {{
295295
$crate::assertions::internal::create_fail_result(
296296
format!($($message),*),
297297
file!(),
@@ -325,7 +325,7 @@ macro_rules! fail {
325325
/// ```
326326
#[macro_export]
327327
macro_rules! succeed {
328-
($($message:expr),+) => {{
328+
($($message:expr),+ $(,)?) => {{
329329
println!(
330330
"{}\n{}",
331331
format!($($message),*),
@@ -368,7 +368,7 @@ macro_rules! succeed {
368368
/// ```
369369
#[macro_export]
370370
macro_rules! add_failure {
371-
($($message:expr),+) => {{
371+
($($message:expr),+ $(,)?) => {{
372372
use $crate::GoogleTestSupport;
373373
$crate::assertions::internal::create_fail_result(
374374
format!($($message),*),
@@ -383,6 +383,57 @@ macro_rules! add_failure {
383383
};
384384
}
385385

386+
/// Generates a failure at specified location marking the test as failed but
387+
/// continue execution.
388+
///
389+
/// This is a **not-fatal** failure. The test continues execution even after the
390+
/// macro execution.
391+
///
392+
/// This can only be invoked inside tests with the
393+
/// [`googletest::test`][crate::test] attribute. The failure must be generated
394+
/// in the same thread as that running the thread itself.
395+
///
396+
/// ```ignore
397+
/// use googletest::prelude::*;
398+
///
399+
/// #[googletest::test]
400+
/// fn should_fail_but_not_abort() {
401+
/// add_failure_at!("src/my_file.rs", 32, 12);
402+
/// }
403+
/// ```
404+
///
405+
/// One may include formatted arguments in the failure message:
406+
///
407+
/// ```ignore
408+
/// use googletest::prelude::*;
409+
///
410+
/// #[googletest::test]
411+
/// fn should_fail_but_not_abort() {
412+
/// add_failure_at!(
413+
/// "src/my_file.rs",
414+
/// 32,
415+
/// 12,
416+
/// "I am just a fake test: {}", "a fake test indeed",
417+
/// );
418+
/// }
419+
/// ```
420+
#[macro_export]
421+
macro_rules! add_failure_at {
422+
($file:expr, $line:expr, $column:expr, $($message:expr),+ $(,)?) => {{
423+
use $crate::GoogleTestSupport;
424+
$crate::assertions::internal::create_fail_result(
425+
format!($($message),*),
426+
$file,
427+
$line,
428+
$column,
429+
).and_log_failure();
430+
}};
431+
432+
($file:expr, $line:expr, $column:expr $(,)?) => {
433+
add_failure_at!($file, $line, $column, "Failed")
434+
};
435+
}
436+
386437
/// Matches the given value against the given matcher, panicking if it does not
387438
/// match.
388439
///

googletest/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ pub mod prelude {
5050
pub use super::Result;
5151
// Assert macros
5252
pub use super::{
53-
add_failure, assert_that, expect_pred, expect_that, fail, succeed, verify_pred, verify_that,
53+
add_failure, add_failure_at, assert_that, expect_pred, expect_that, fail, succeed,
54+
verify_pred, verify_that,
5455
};
5556
}
5657

integration_tests/Cargo.toml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,26 @@ name = "add_failure_macro_needs_googletest_attribute"
125125
path = "src/add_failure_macro_needs_googletest_attribute.rs"
126126
test = false
127127

128+
[[bin]]
129+
name = "add_failure_at_macro_causes_failure_but_continues_execution"
130+
path = "src/add_failure_at_macro_causes_failure_but_continues_execution.rs"
131+
test = false
132+
133+
[[bin]]
134+
name = "add_failure_at_macro_allows_empty_message"
135+
path = "src/add_failure_at_macro_allows_empty_message.rs"
136+
test = false
137+
138+
[[bin]]
139+
name = "add_failure_at_macro_allows_formatted_arguments"
140+
path = "src/add_failure_at_macro_allows_formatted_arguments.rs"
141+
test = false
142+
143+
[[bin]]
144+
name = "add_failure_at_macro_needs_googletest_attribute"
145+
path = "src/add_failure_at_macro_needs_googletest_attribute.rs"
146+
test = false
147+
128148
[[bin]]
129149
name = "failure_due_to_returned_error"
130150
path = "src/failure_due_to_returned_error.rs"
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
fn main() {}
16+
17+
#[cfg(test)]
18+
mod tests {
19+
use googletest::prelude::*;
20+
21+
#[googletest::test]
22+
fn should_fail_but_not_abort() {
23+
add_failure_at!("my_file.rs", 1, 1,);
24+
}
25+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
fn main() {}
16+
17+
#[cfg(test)]
18+
mod tests {
19+
use googletest::prelude::*;
20+
21+
#[googletest::test]
22+
fn should_fail_but_not_abort() {
23+
let argument = "An argument";
24+
add_failure_at!("my_file.rs", 1, 1, "Failure message with argument: {argument}");
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
fn main() {}
16+
17+
#[cfg(test)]
18+
mod tests {
19+
use googletest::prelude::*;
20+
21+
#[googletest::test]
22+
fn should_fail_but_not_abort() {
23+
add_failure_at!("first_file.rs", 32, 12, "First failure",);
24+
add_failure_at!("second_file.rs", 32, 12, "Second failure");
25+
}
26+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
fn main() {}
16+
17+
#[cfg(test)]
18+
mod tests {
19+
use googletest::prelude::*;
20+
21+
#[test]
22+
fn should_fail() {
23+
add_failure_at!("file.rs", 1, 1);
24+
}
25+
}

integration_tests/src/integration_tests.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,55 @@ mod tests {
658658
verify_that!(output, contains_regex("Did you annotate the test with googletest::test?"))
659659
}
660660

661+
#[googletest::test]
662+
fn add_failure_at_macro_causes_failure_but_continues_execution() -> Result<()> {
663+
let output = run_external_process_in_tests_directory(
664+
"add_failure_at_macro_causes_failure_but_continues_execution",
665+
)?;
666+
667+
expect_that!(
668+
output,
669+
contains_regex(indoc! {"
670+
First failure
671+
at .*first_file.rs:32:12
672+
"})
673+
);
674+
expect_that!(
675+
output,
676+
contains_regex(indoc! {"
677+
Second failure
678+
at .*second_file.rs:32:12
679+
"})
680+
);
681+
Ok(())
682+
}
683+
684+
#[test]
685+
fn add_failure_at_macro_allows_empty_message() -> Result<()> {
686+
let output =
687+
run_external_process_in_tests_directory("add_failure_at_macro_allows_empty_message")?;
688+
689+
verify_that!(output, contains_regex("Failed"))
690+
}
691+
692+
#[test]
693+
fn add_failure_at_macro_allows_formatted_arguments() -> Result<()> {
694+
let output = run_external_process_in_tests_directory(
695+
"add_failure_at_macro_allows_formatted_arguments",
696+
)?;
697+
698+
verify_that!(output, contains_regex("Failure message with argument: An argument"))
699+
}
700+
701+
#[test]
702+
fn add_failure_at_macro_needs_googletest_attribute() -> Result<()> {
703+
let output = run_external_process_in_tests_directory(
704+
"add_failure_at_macro_needs_googletest_attribute",
705+
)?;
706+
707+
verify_that!(output, contains_regex("Did you annotate the test with googletest::test?"))
708+
}
709+
661710
#[test]
662711
fn test_using_normal_test_attribute_macro_formats_failure_message_correctly() -> Result<()> {
663712
let result = should_display_error_correctly_without_google_test_macro();

run_integration_tests.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ INTEGRATION_TEST_BINARIES=(
4242
"add_failure_macro_allows_empty_message"
4343
"add_failure_macro_allows_formatted_arguments"
4444
"add_failure_macro_needs_googletest_attribute"
45+
"add_failure_at_macro_causes_failure_but_continues_execution"
46+
"add_failure_at_macro_allows_empty_message"
47+
"add_failure_at_macro_allows_formatted_arguments"
48+
"add_failure_at_macro_needs_googletest_attribute"
4549
"fatal_and_non_fatal_failure"
4650
"first_failure_aborts"
4751
"google_test_with_rstest"

0 commit comments

Comments
 (0)