1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-04-27 17:42:18 +02:00

Chromium: new subsection about gtest tests (#1551)

This commit is contained in:
Lukasz Anforowicz 2023-12-05 02:39:02 -08:00 committed by GitHub
parent 7d10518b24
commit 8f9902cc3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 123 additions and 0 deletions

View File

@ -252,6 +252,10 @@
- [Depending on Rust code from Chromium C++](chromium/build-rules/depending.md)
- [Visual Studio code](chromium/build-rules/vscode.md)
- [Exercise](exercises/chromium/build-rules.md)
- [Testing](chromium/testing.md)
- [`rust_gtest_interop` library](chromium/testing/rust-gtest-interop.md)
- [GN rules for Rust tests](chromium/testing/build-gn.md)
- [Exercise](exercises/chromium/testing.md)
- [Interoperability with C++](chromium/interoperability-with-cpp.md)
- [Example bindings](chromium/interoperability-with-cpp/example-bindings.md)
- [Limitations of CXX](chromium/interoperability-with-cpp/limitations-of-cxx.md)

51
src/chromium/testing.md Normal file
View File

@ -0,0 +1,51 @@
# Testing
Rust community typically authors unit tests in a module placed in the same
source file as the code being tested. This was covered
[earlier](../testing.md) in the course and looks like this:
```rust
#[cfg(test)]
mod tests {
#[test]
fn my_test() { todo!() }
}
```
In Chromium we place unit tests in a separate source file and we continue to
follow this practice for Rust --- this makes tests consistently discoverable and
helps to avoid rebuilding `.rs` files a second time (in the `test`
configuration).
This results in the following options for testing Rust code in Chromium:
* Native Rust tests (i.e. `#[test]`).
Discouraged outside of `//third_party/rust`.
* `gtest` tests authored in C++ and exercising Rust via FFI calls. Sufficient
when Rust code is just a thin FFI layer and the existing unit tests provide
sufficient coverage for the feature.
* `gtest` tests authored in Rust and using the crate under test through its
public API (using `pub mod for_testing { ... }` if needed). This is the
subject of the next few slides.
<details>
Mention that native Rust tests of third-party crates should eventually be
exercised by Chromium bots. (Such testing is needed rarely --- only after
adding or updating third-party crates.)
Some examples may help illustrate when C++ `gtest` vs Rust `gtest` should be
used:
* QR has very little functionality in the first-party Rust layer (it's just a
thin FFI glue) and therefore uses the existing C++ unit tests for testing
both the C++ and the Rust implementation (parametrizing the tests so they
enable or disable Rust using a `ScopedFeatureList`).
* Hypothetical/WIP PNG integration may need to implement memory-safe
implementation of pixel transformations that are provided by `libpng`
but missing in the `png` crate - e.g. RGBA => BGRA, or gamma correction.
Such functionality may benefit from separate tests authored in Rust.
</details>

View File

@ -0,0 +1,33 @@
# GN rules for Rust tests
The simplest way to build Rust `gtest` tests is to add them to an existing test
binary that already contains tests authored in C++. For example:
```gn
test("ui_base_unittests") {
...
sources += [ "my_rust_lib_unittest.rs" ]
deps += [ ":my_rust_lib" ]
}
```
Authoring Rust tests in a separate `static_library` also works, but requires
manually declaring the dependency on the support libraries:
```gn
rust_static_library("my_rust_lib_unittests") {
testonly = true
is_gtest_unittests = true
crate_root = "my_rust_lib_unittest.rs"
sources = [ "my_rust_lib_unittest.rs" ]
deps = [
":my_rust_lib",
"//testing/rust_gtest_interop",
]
}
test("ui_base_unittests") {
...
deps += [ ":my_rust_lib_unittests" ]
}
```

View File

@ -0,0 +1,21 @@
# `rust_gtest_interop` library
The [`rust_gtest_interop`][0] library provides a way to:
* Use a Rust function as a `gtest` testcase
(using the `#[gtest(...)]` attribute)
* Use `expect_eq!` and similar macros (similar to `assert_eq!` but not
panicking and not terminating the test when the assertion fails).
Example:
```rust,ignore
use rust_gtest_interop::prelude::*;
#[gtest(MyRustTestSuite, MyAdditionTest)]
fn test_addition() {
expect_eq!(2 + 2, 4);
}
```
[0]: https://chromium.googlesource.com/chromium/src/+/main/testing/rust_gtest_interop/README.md

View File

@ -0,0 +1,14 @@
# Testing exercise
Time for another exercise!
In your Chromium build:
* Add a testable function next to `hello_from_rust`.
Some suggestions:
adding two integers received as arguments,
computing the nth Fibonacci number,
summing integers in a slice, etc.
* Add a separate `..._unittest.rs` file with a test for the new function.
* Add the new tests to `BUILD.gn`.
* Build the tests, run them, and verify that the new test works.