diff --git a/Cargo.lock b/Cargo.lock index e97d4749..5c589fa9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -748,6 +748,28 @@ dependencies = [ "regex", ] +[[package]] +name = "googletest" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09213705c85aa0e4b4fff44a3a826a556979a34a266df6bcda703a49c69fb61e" +dependencies = [ + "googletest_macro", + "num-traits", + "regex", + "rustversion", +] + +[[package]] +name = "googletest_macro" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "005e4cb962c56efd249bdeeb4ac232b11e1c45a2e49793bba2b2982dcc3f2e9d" +dependencies = [ + "quote", + "syn 2.0.39", +] + [[package]] name = "h2" version = "0.3.22" @@ -1781,6 +1803,12 @@ dependencies = [ "base64", ] +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + [[package]] name = "ryu" version = "1.0.15" @@ -2185,6 +2213,9 @@ dependencies = [ [[package]] name = "testing" version = "0.1.0" +dependencies = [ + "googletest", +] [[package]] name = "thiserror" diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 36db5b6c..bb38b993 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -172,6 +172,7 @@ - [Test Modules](testing/unit-tests.md) - [Other Types of Tests](testing/other.md) - [Useful Crates](testing/useful-crates.md) + - [GoogleTest](testing/googletest.md) - [Compiler lints and Clippy](testing/lints.md) - [Exercise: Luhn Algorithm](testing/exercise.md) - [Solution](testing/solution.md) diff --git a/src/testing/Cargo.toml b/src/testing/Cargo.toml index 10005b57..657993f0 100644 --- a/src/testing/Cargo.toml +++ b/src/testing/Cargo.toml @@ -4,7 +4,15 @@ version = "0.1.0" edition = "2021" publish = false +[[example]] +name = "googletest-example" +crate-type = ["staticlib"] +path = "googletest.rs" +test = true + [[bin]] name = "luhn" path = "exercise.rs" +[dependencies] +googletest = "0.10.0" diff --git a/src/testing/googletest.md b/src/testing/googletest.md new file mode 100644 index 00000000..b22efc5f --- /dev/null +++ b/src/testing/googletest.md @@ -0,0 +1,73 @@ +--- +minutes: 5 +--- + +# GoogleTest + +The [GoogleTest](https://docs.rs/googletest/) crate allows for flexible test +assertions using _matchers_: + +```rust,ignore +{{#include googletest.rs:test_elements_are}} +``` + +If we change the last element to `"!"`, the test fails with a structured error +message pin-pointing the error: + + + +```text +---- test_elements_are stdout ---- +Value of: value +Expected: has elements: + 0. is equal to "foo" + 1. is less than "xyz" + 2. starts with prefix "!" +Actual: ["foo", "bar", "baz"], + where element #2 is "baz", which does not start with "!" + at src/testing/googletest.rs:6:5 +Error: See failure output above +``` + +
+ +- GoogleTest is not part of the Rust Playground, so you need to run this example + in a local environment. Use `cargo add googletest` to quickly add it to an + existing Cargo project. + +- The `use googletest::prelude::*;` line imports a number of + [commonly used macros and types][prelude]. + +- This just scratches the surface, there are many builtin matchers. + +- A particularly nice feature is that mismatches in multi-line strings strings + are shown as a diff: + +```rust,ignore +{{#include googletest.rs:test_multiline_string_diff}} +``` + + shows a color-coded diff (colors not shown here): + + + ```text + Value of: haiku + Expected: is equal to "Memory safety found,\nRust's silly humor guides the way,\nSecure code you'll write." + Actual: "Memory safety found,\nRust's strong typing guides the way,\nSecure code you'll write.", + which isn't equal to "Memory safety found,\nRust's silly humor guides the way,\nSecure code you'll write." + Difference(-actual / +expected): + Memory safety found, + -Rust's strong typing guides the way, + +Rust's silly humor guides the way, + Secure code you'll write. + at src/testing/googletest.rs:17:5 + ``` + +- The crate is a Rust port of + [GoogleTest for C++](https://google.github.io/googletest/). + +[prelude]: https://docs.rs/googletest/latest/googletest/prelude/index.html + +- GoogleTest is available for use in AOSP. + +
diff --git a/src/testing/googletest.rs b/src/testing/googletest.rs new file mode 100644 index 00000000..19d3b015 --- /dev/null +++ b/src/testing/googletest.rs @@ -0,0 +1,25 @@ +// ANCHOR: test_elements_are +use googletest::prelude::*; + +#[googletest::test] +fn test_elements_are() { + let value = vec!["foo", "bar", "baz"]; + expect_that!(value, elements_are!(eq("foo"), lt("xyz"), starts_with("b"))); +} +// ANCHOR_END: test_elements_are + +#[should_panic] +// ANCHOR: test_multiline_string_diff +#[test] +fn test_multiline_string_diff() { + let haiku = "Memory safety found,\n\ + Rust's strong typing guides the way,\n\ + Secure code you'll write."; + assert_that!( + haiku, + eq("Memory safety found,\n\ + Rust's silly humor guides the way,\n\ + Secure code you'll write.") + ); +} +// ANCHOR_END: test_multiline_string_diff