5. Run host tests#

pw_unit_test provides an extensive GoogleTest-compatible unit testing framework. Before building and running the app, let’s first verify that the app’s logic is correct by exercising the app’s unit tests:

  1. Open //modules/blinky/blinky_test.cc.

    Remember that // represents the root directory of your Sense repository. E.g. if your Sense repo was located at /home/example/sense/ then //modules/blinky/blinky_test.cc would be located at /home/examples/sense/modules/blinky/blinky_test.cc.

  2. Make the Toggle test fail by changing one of the expected values. Example:

    TEST_F(BlinkyTest, Toggle) {
      // ...
      auto event = FirstActive();
      ASSERT_NE(event, monochrome_led_.events().end());
      EXPECT_EQ(event->state, State::kInactive);   // add this line
      // EXPECT_EQ(event->state, State::kActive);  // comment out this line
      EXPECT_GE(ToMs(event->timestamp - start), kIntervalMs * 0);
      start = event->timestamp;
      // ...
    }
    

    Caution

    Remember to save your changes!

  3. Run the tests:

    Make sure that your platform is set to host_simulator, as demonstrated in Navigate the code intelligently. If VS Code was displaying red squiggly line warnings in blinky_test.cc, those should go away.

    In Bazel Targets expand //modules/blinky, then right-click :blinky_test (cc_test), then select Test target.

    Selecting Test target

    Starting blinky_test#

    A task launches a terminal. You should see blinky_test fail:

    INF  LED blinking: ON
    INF  [*]
    INF  [ ]
    INF  Stopped blinking
    [       OK ] BlinkyTest.BlinkSlow
    [==========] Done running all tests.
    [  PASSED  ] 3 test(s).
    [  FAILED  ] 1 test(s).
    ================================================================================
    INFO: Found 1 test target...
    Target //modules/blinky:blinky_test up-to-date:
      bazel-bin/modules/blinky/blinky_test
    INFO: Elapsed time: 2.060s, Critical Path: 1.75s
    INFO: 27 processes: 15 internal, 12 linux-sandbox.
    INFO: Build completed, 1 test FAILED, 27 total actions
    //modules/blinky:blinky_test                   FAILED in 0.0s
      /home/kayce/.cache/bazel/_bazel_kayce/e6adb4cdc44e1f72d34a105431e60eae/execroot/_main/bazel-out/k8-fastbuild/testlogs/modules/blinky/blinky_test/test.log
    
    Executed 1 out of 1 test: 1 fails locally.
    

    Press any key to close the terminal that was launched.

    Tip

    When you want to run all unit tests, open a VS Code Terminal and execute bazelisk test //.... You don’t need to manually set up bazelisk, the Pigweed extension for VS Code sets it up for you.

    1. Run the tests with the following command:

    Run the following command. You should see output similar to what’s shown after the command. The key line is Executed 1 out of 1 test: 1 fails locally.

    bazelisk test //modules/blinky:blinky_test
    

    You should see output similar to this:

    INF  LED blinking: ON
    INF  [*]
    INF  LED blinking: OFF
    INF  [ ]
    INF  LED blinking: ON
    INF  [*]
    INF  [ ]
    INF  Stopped blinking
    [       OK ] BlinkyTest.BlinkMany
    [ RUN      ] BlinkyTest.BlinkSlow
    INF  [ ]
    INF  PWM: -
    INF  [ ]
    INF  [ ]
    INF  PWM: +
    INF  PWM: +
    INF  PWM: +
    INF  Blinking 1 times at a 320ms interval
    INF  LED blinking: OFF
    INF  [ ]
    INF  LED blinking: ON
    INF  [*]
    INF  [ ]
    INF  Stopped blinking
    [       OK ] BlinkyTest.BlinkSlow
    [==========] Done running all tests.
    [  PASSED  ] 3 test(s).
    [  FAILED  ] 1 test(s).
    ================================================================================
    INFO: Found 1 test target...
    Target //modules/blinky:blinky_test up-to-date:
      bazel-bin/modules/blinky/blinky_test
    INFO: Elapsed time: 2.032s, Critical Path: 1.69s
    INFO: 9 processes: 1 internal, 8 linux-sandbox.
    INFO: Build completed, 1 test FAILED, 9 total actions
    //modules/blinky:blinky_test                   FAILED in 0.0s
      /home/kayce/.cache/bazel/_bazel_kayce/e6adb4cdc44e1f72d34a105431e60eae/execroot/_main/bazel-out/k8-fastbuild/testlogs/modules/blinky/blinky_test/test.log
    
    Executed 1 out of 1 test: 1 fails locally.
    

    Tip

    To run all host tests, run this command:

    bazelisk test //...
    
  4. Revert the test to its original state. Remember to save your change.

  5. Run the tests again and make sure they pass this time.

    You should see blinky_test pass this second time:

    INFO: Analyzed target //modules/blinky:blinky_test (0 packages loaded, 0 targets configured).
    INFO: Found 1 test target...
    Target //modules/blinky:blinky_test up-to-date:
      bazel-bin/modules/blinky/blinky_test
    INFO: Elapsed time: 1.861s, Critical Path: 1.65s
    INFO: 4 processes: 4 linux-sandbox.
    INFO: Build completed successfully, 4 total actions
    //modules/blinky:blinky_test                   PASSED in 0.0s
    
    Executed 1 out of 1 test: 1 test passes.
    

Note

If you see warnings that begin with There were tests whose specified size is too big, you can ignore them. If you encounter this warning in your own project, it means you need to adjust the timeout of the tests.

Summary#

We know that unit tests are a little boring, but they’re an important part of Pigweed’s mission. When you’re on a large embedded development team creating a new product, it’s much easier to iterate quickly when you have confidence that your code changes do not introduce bugs in other parts of the codebase. The best way to build that confidence is to rigorously test every part of your codebase and to make sure all these tests pass before allowing any new code to merge.

Pigweed spends a lot of time making it easier for teams to test their codebases, such as making it easy to run unit tests on your development host rather than on physical hardware. This is especially useful when your physical hardware doesn’t exist yet because your hardware team hasn’t finished designing it!

Another reason why it’s important to make code that can be tested on your host: security and robustness. This enables you to run modern code analysis tooling like ASAN, TSAN, MSAN, fuzzers, and more. These tools are unlikely to run correctly in on-device embedded contexts. Fun fact: We caught real bugs in Sense with this tooling during development!

Now it’s time for the fun stuff. Head over to 6. Run the host app to try out the bringup app, blinky.