• Home
Name Date Size #Lines LOC

..--

BUILD.gnD03-May-20241.8 KiB7565

README.mdD03-May-20244 KiB142115

expect_macros.rsD03-May-20248.9 KiB291184

gtest_attribute.rsD03-May-202420.1 KiB491305

rust_gtest_interop.ccD03-May-20241.1 KiB3322

rust_gtest_interop.hD03-May-20244.4 KiB10741

rust_gtest_interop.rsD03-May-202411.1 KiB276150

rust_gtest_interop_unittest.rsD03-May-20242.9 KiB12184

rust_gtest_interop_unittest_main.ccD03-May-20242 KiB6137

README.md

1# Rust integration into C++ Gtest targets.
2
3This directory contains the tools for writing gtest-based tests in Rust and
4integrating them into Chromium's C++ gtest binaries. The tools are all
5accessible through the `rust_gtest_interop` target which is automatically
6included in test targets that depend on `//testing/gtest`.
7
8## To add rust unittests to a C++ Gtest target
9
10A typical Gtest target is defined in a BUILD.gn file, with something like this:
11
12`BUILD.gn`:
13```gn
14test("some_unittests") {
15  sources = [
16    "a_cpp_file.cc",
17    "another_cpp_file.cc",
18  ]
19  deps = [
20    "//testing/gtest",
21  ]
22}
23```
24
25To add a Rust file to the test suite, simply add it to the `rs_sources`. Unlike
26other Rust crates, the `crate_root` is not specified, since it is generated from
27the sources list.
28
29`BUILD.gn`:
30```gn
31test("some_unittests") {
32  sources = [
33    "a_cpp_file.cc",
34    "another_cpp_file.cc",
35  ]
36  rs_sources = [
37    "a_rust_file.rs",
38  ]
39  deps = [
40    "//testing/gtest",
41  ]
42}
43```
44
45## To write a Gtest unit test in Rust
46
47To write a unit test, you simply write a function an decorate it with the
48`#[gtest]` macro. The macro takes 2 arguments, which are the test suite name and
49the test name, just like the C++ `TEST()` macro.
50
51The `#[gtest]` macro is provided by the `rust_gtest_interop_rs` crate, and is
52exported in the `prelude` module. Typically a unit test file would start with
53`use rust_gtest_interop_rs::prelude::*;` which includes all of the available
54gtest macros. This is similar to writing `#include
55"testing/gtest/include/gtest/gtest.h"` in C++.
56
57A Rust test:
58```rs
59use rust_gtest_interop_rs::prelude::*;  // Provides all the gtest macros.
60
61#[gtest(MyTestSuite, MyTestOfThing)]
62fn test() {
63  ...
64}
65```
66
67A C++ test:
68```cpp
69#include "testing/gtest/include/gtest/gtest.h"  // Provides all the gtest macros.
70
71TEST(MyTestSuite, MyTestOfThing) {
72  ...
73}
74```
75
76### Expectations
77
78We have access to many of the same EXPECT macros in Rust that are familiar to
79C++ Gtest users, though they are used with Rust's macro syntax.
80
81The macros currently available are:
82```rs
83expect_true!(is_friday());
84expect_false!(is_saturday());
85
86expect_eq!(2, 1 + 1);  // A == B
87expect_ne!(3, 1 + 2);  // A != B
88
89expect_lt!(1 * 1, 1 * 2);  // A < B
90expect_gt!(4 * 1, 1 * 2);  // A > B
91expect_le!(2 * 1, 1 * 2);  // A <= B
92expect_ge!(3 * 1, 2 * 3);  // A >= B
93```
94
95### Returning a Result
96
97A C++ test always returns void and Rust tests usually do as well. But if your
98test calls a function that returns `Result`, it is convenient to make use of the
99[`?` operator](https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator)
100instead of checking the Result value explicitly. Thus a test can either return:
101
1021. `()` aka void.
1031. `std::result::Result<(), E>` for any `E` that can be converted to a
104   `std::error::Error`. (Or in Rust parlance, for any `E` for which there is
105   `Into<std::error::Error>`). Common error types are `std::io::Error` or
106   `String`.
107
108If the test with a `std::result::Result` return type returns `Result::Err`, the
109test will fail and display the error.
110
111In this example, the test will fail if it can not read from `file.txt`, or if it
112does not contain `"hello world"`:
113```rs
114#[gtest(TestingIO, ReadFile)]
115fn test() -> std::io::Result {
116  let s = std::fs::read_to_string("file.txt")?;
117  expect_eq!(s, "hello world");
118  Ok(())
119}
120```
121
122### Shared helper utilities
123
124Sometimes tests across different test files want to share helper utilities. Such
125helpers should be placed in a separate GN target, typically named with a
126`_test_support` suffix, such as `starship_test_support` for the
127`starship_unittests`. And would also usually be found in a `test/` subdirectory.
128
129#### Example
130The `starship_unittests` test() target would include any unit test files, such as
131`starship_unittest.rs`. And the `starship_test_support` static_library() target
132would include the files in the `test/` subdirectory, such as
133`starship_test_helper.rs` and `starship_test_things.rs`.
134```
135src/
136  starship/
137    starship_unittest.rs
138    test/
139      starship_test_helper.rs
140      starship_test_things.rs
141```
142