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:
parent
7d10518b24
commit
8f9902cc3e
@ -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
51
src/chromium/testing.md
Normal 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>
|
||||
|
33
src/chromium/testing/build-gn.md
Normal file
33
src/chromium/testing/build-gn.md
Normal 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" ]
|
||||
}
|
||||
```
|
21
src/chromium/testing/rust-gtest-interop.md
Normal file
21
src/chromium/testing/rust-gtest-interop.md
Normal 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
|
14
src/exercises/chromium/testing.md
Normal file
14
src/exercises/chromium/testing.md
Normal 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.
|
Loading…
x
Reference in New Issue
Block a user