Step 4 — Validation

Test targets can be defined on different architectural levels. They are attached to unit, component, and dependable_element via the tests attribute. On component and dependable_element level, the test should focus more on integration and system testing, while on unit level, the test should focus on unit testing.

rules_score does not require a separate test specification document. Instead, test intent is captured as a Given-When-Then description right next to the code as record properties in the test name/body itself. The specification will then be rendered in the traceability report, together with the test results and coverage information.

src/my_unit_test.cpp

#include <gtest/gtest.h>

#include "src/my_unit.h"

TEST(MyUnitTest, ConfigureAndGet) {
  ::testing::Test::RecordProperty(
      "lobster-tracing", "MinimalExample.FEAT_001 MinimalExample.FEAT_002");

  ::testing::Test::RecordProperty("given",
                                  "a default-constructed MyUnit instance");
  MyUnit unit{};

  ::testing::Test::RecordProperty(
      "when",
      "When configure is called with a key that hasn't been configured yet");
  unit.configure("mode", "fast");

  ::testing::Test::RecordProperty("then", "get returns the configured value");
  EXPECT_EQ(unit.get("mode"), "fast");
}

TEST(MyUnitTest, MissingKeyReturnsEmpty) {
  ::testing::Test::RecordProperty("lobster-tracing", "MinimalExample.FEAT_002");

  ::testing::Test::RecordProperty("given",
                                  "a default-constructed MyUnit instance");
  MyUnit unit{};

  ::testing::Test::RecordProperty(
      "when", "When get is called with a key that hasn't been configured yet");
  const auto retrieved_value = unit.get("undefined");

  ::testing::Test::RecordProperty("then", "get returns an empty value");
  EXPECT_EQ(retrieved_value, "");
}

Each RecordProperty("lobster-tracing", "...") call names the requirement identifiers covered by that test case. The optional given/when/then properties capture the Given-When-Then specification for that test case:

  • given — the initial state or precondition

  • when — the action or event under test

  • then — the expected outcome

They are picked up the same way as lobster-tracing — as plain RecordProperty calls — and are rendered alongside the test result in the traceability report. Test cases without them are still traced, but show up without a Given-When-Then specification.

BUILD

cc_test(
    name = "my_unit_test",
    srcs = ["src/my_unit_test.cpp"],
    deps = [
        ":my_unit_lib",
        "@googletest//:gtest_main",
    ],
)

unit(
    name = "MyUnit",
    implementation = [":my_unit_lib"],
    scope = ["//:my_unit_lib"],
    unit_design = [":MyUnit_design"],
    tests = [":my_unit_test"],
)

Run the tests with:

bazel test //:my_unit_test

→ Full guide: ../validation.rst