From bd80c18133fbd8f776ac835c8f5e28621186245a Mon Sep 17 00:00:00 2001 From: Scott Hart Date: Thu, 6 Aug 2026 17:09:48 -0400 Subject: [PATCH 1/2] chore: updated AGENTS.md with more testing guidelines --- .agents/AGENTS.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/.agents/AGENTS.md b/.agents/AGENTS.md index c3ec118d0aed1..4d2822bdf5da0 100644 --- a/.agents/AGENTS.md +++ b/.agents/AGENTS.md @@ -9,3 +9,38 @@ Status / StatusOr checks (using `google::cloud::testing_util::IsOk`). - Use `EXPECT_TRUE` / `ASSERT_TRUE` (or `EXPECT_FALSE` / `ASSERT_FALSE`) for standard boolean expression checks (e.g., `stream.good()`). +- **Prefer Declarative Container Matchers Over Imperative Loops:** Avoid manual + loops (`for (...)`), boolean search flags (`bool found = false;`), and manual + container filtering in tests. Use GoogleTest container matchers (e.g., + `testing::Contains`, `testing::Each`, `testing::ElementsAre`, + `testing::UnorderedElementsAre`, `testing::IsEmpty`, `testing::SizeIs`) to + express collection assertions declaratively. +- **Write Custom Matchers for Complex Objects and Protobufs:** When validating + complex objects, structs, or protobuf messages (e.g., time series, spans, + requests, responses), define custom matchers using `MATCHER_P` / `MATCHER_P2` + with `ExplainMatchResult`. Compose them using `testing::AllOf`, + `testing::AnyOf`, `testing::Property`, and `testing::Field`. + - *Why:* Declarative matchers provide detailed diagnostic mismatch + explanations when tests fail, whereas boolean flags only output + `Value of: found, Actual: false, Expected: true`. +- **Example Pattern:** + ```cpp + MATCHER_P(MetricType, matcher, "") { + return ExplainMatchResult(matcher, arg.metric().type(), result_listener); + } + + MATCHER_P2(HasMetricLabel, key, val_matcher, "") { + auto const& labels = arg.metric().labels(); + auto it = labels.find(key); + if (it == labels.end()) { + *result_listener << "no metric label '" << key << "'"; + return false; + } + return ExplainMatchResult(val_matcher, it->second, result_listener); + } + + // Composed assertion: + EXPECT_THAT(recorded_metrics, Contains(HasTimeSeries(AllOf( + MetricType(HasSubstr("outstanding_rpcs")), + HasMetricLabel("channel_pool_lb_policy", Eq("RANDOM_TWO_LEAST_USED")))))); + ``` From 46178e11dce08b723ea9b4becb08a76473d626c0 Mon Sep 17 00:00:00 2001 From: Scott Hart Date: Fri, 7 Aug 2026 10:33:49 -0400 Subject: [PATCH 2/2] Update .agents/AGENTS.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .agents/AGENTS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.agents/AGENTS.md b/.agents/AGENTS.md index 4d2822bdf5da0..99ca7bff715ea 100644 --- a/.agents/AGENTS.md +++ b/.agents/AGENTS.md @@ -40,7 +40,7 @@ } // Composed assertion: - EXPECT_THAT(recorded_metrics, Contains(HasTimeSeries(AllOf( + EXPECT_THAT(recorded_metrics, Contains(AllOf( MetricType(HasSubstr("outstanding_rpcs")), - HasMetricLabel("channel_pool_lb_policy", Eq("RANDOM_TWO_LEAST_USED")))))); + HasMetricLabel("channel_pool_lb_policy", Eq("RANDOM_TWO_LEAST_USED"))))); ```