Automating Reliability Engineering with Unit Testing, HIL Testing & EmbedOps – Part 1

Dev Containers

A key challenge for embedded systems developers is ensuring high-reliability operation in products designed for years-long deployments, sometimes in remote locations. A prime example of such a device is a Bluetooth-enabled environmental sensor node that performs functions such as advertising over Bluetooth Low Energy (BLE), transmitting temperature and humidity data, and supporting over-the-air (OTA) firmware updates and diagnostics.

In commercial markets, tens of thousands, hundreds of thousands, or more of these units ship over the course of the product lifecycle. Any failures in functionality or performance could have dire consequences for the manufacturer:

  • Time-to-market delays can lead to missed opportunities and lost revenue as competitors capture new customers by launching similar products.
  • Costly recalls erode profit as returned units are refunded, repaired, or replaced, depending on the nature of the failure.
  • Security vulnerabilities can cause service disruptions and data breaches that further damage brand reputation and the likelihood of repeat business with customers.

To avoid these pitfalls, development teams can leverage automation and modern engineering practices for faster ad-hoc testing and bug remediation. Still, this can be challenging when working with manual build processes across distributed teams using inconsistent toolchains. Dojo Five EmbedOps helps embedded teams quickly stand up unit testing, hardware‑in‑the‑loop (HIL) testing, and automated reporting to find and address operating deficiencies that could bring down a commercial product, whether during development or after deployment.

In part 1, we investigate how EmbedOps streamlines unit testing.

BLE Sensor Node Proof of Concept

Let’s build out the example BLE-enabled environmental sensor mentioned previously into something more real. We will use a Nordic nRF52 wireless system-on-a-chip (SoC) as a baseline and start by defining some of the system’s key functions. These include:

  • Periodically reading the temperature and humidity from a sensor
  • Flash an LED to indicate status
  • Using Nordic’s UART Service (NUS) for diagnostic echo

The EmbedOps DevKit Quickstart guide explains how to spin up a Zephyr‑based LED‑blink project that runs inside a dev container—this takes around 5 minutes to create after installing the EmbedOps CLI and required tools such as Docker.

Running the eo init command in a fresh repository will prompt users to select a preferred continuous integration (CI) platform (GitLab, GitHub, or Bitbucket) and the base container OS for the Linux distribution. Once confirmed, EmbedOps registers the project and creates the following to ensure all dev team members have the same tool versions:

  • .embedops/repo_id.yml — Connects your repo to the EmbedOps platform
  • .embedops/template-settings.yml — Saves your configuration choices
  • .devcontainer/ — The dev container configuration
  • CI configuration files for your chosen provider

Developers can then use eo add unittest to set up a unit testing framework based on Ceedling or Google Test. Alternatively, the eo add hil command is used to add HIL scaffolding. The EmbedOps CLI automatically downloads templates for test harnesses, CI scripts, and the required dev container features to conduct these tests.

eo add unittest, Step 1. Select the GoogleTest framework

eo add unittest, Step 2. Specify the source directory

eo add unittest, Step 3. Specify the test directory

eo add unittest, Step 4. Enable code coverage

eo add unittest, Step 5. The unit test template has been added successfully to the project

The EmbedOps HIL reference documentation also includes example projects such as the NUS Echo demo. This example shows the test procedure for a device that has NUS echo implemented, advertising as “EmbedOps HIL Demo Device” and echoing any data sent over NUS. The test sends data and asserts whether the received data is the same as what was sent, thereby verifying correct operation. (Note: HIL testing is explored in more detail in Part 2.)

Unit Testing

The next step is to write a unit test. Unit tests run off-target and offer fast evaluation of short sections of code—hundreds or thousands of unit tests can be conducted per second. These tests verify that each section of code performs as it should, returning the correct result for a given input.

Through unit testing, developers can catch programming and other errors, reducing the cost of fixes later in development or after deployment. In addition to localizing failures for easier troubleshooting, unit testing also allows firmware development to progress independently when hardware isn’t ready.

While embedded teams often use custom boards for hardware testing, relying purely on real-world testing slows development and blocks parallel work. To conduct effective off-target testing, firmware developers require detailed unit testing architectures and dependency injection—i.e., simulated hardware dependencies—when isolating code modules.

Additionally, different compilers, linkers, and build systems can produce test results that vary across different host machines. The key advantage of using dev container environments created by EmbedOps is that it standardizes development toolchains across the team to ensure reproducible test results.

Developers may perceive unit tests as extra work or struggle to recreate hardware dependencies when isolating firmware modules. To ease the adoption of this development best practice, the eo add unittest template creates the required scaffolding for detailed unit testing and shows examples to get developers started.

The below code snippet is a unit test covering the conversion of Zephyr sensor subsystem values into values for the respective sensor type (pressure in this example). struct sensor_value is mocking the Zephyr sensor API, allowing us to test the functionality.

For example, consider creating a test for the conversion of Zephyr sensor subsystem values into unit values for the respective sensor value types (pressure in this example). For simplicity, the tests do not include the zephyr subsystem linking it to the tests would be an unnecessary complication considering what we need to test.

The definition of the struct sensor_value is a mocking of the Zephyr sensor API allowing us to test the functionality.

struct sensor_value {                                                                                                  
  int32_t val1;
  int32_t val2;
};

void setUp(void) {}

void tearDown(void) {}

void test_pressure_conversion(void) {
  struct sensor_value val;

  val.val1 = 1;
  val.val2 = 500000;
  TEST_ASSERT_EQUAL_INT32(1500, sensor_value_to_pressure(&val));

  val.val1 = 0;
  val.val2 = 0;
  TEST_ASSERT_EQUAL_INT32(0, sensor_value_to_pressure(&val));

  val.val1 = -1;
  val.val2 = -500000;
  TEST_ASSERT_EQUAL_INT32(0, sensor_value_to_pressure(&val));

  val.val1 = 1000;
  val.val2 = 999000;
  TEST_ASSERT_EQUAL_INT32(1000999, sensor_value_to_pressure(&val));

  val.val1 = 0;
  val.val2 = 999;
  TEST_ASSERT_EQUAL_INT32(0, sensor_value_to_pressure(&val));

  val.val1 = 0;
  val.val2 = 1000;
  TEST_ASSERT_EQUAL_INT32(1, sensor_value_to_pressure(&val));
}

Unit testing frameworks like Ceedling or Google Test can be used to generate a JUnit XML report by enabling the junit_tests_report plugin in EmbedOps.

1. First, execute eo test to run all unit tests. The CLI compiles the code inside the container and reports pass/fail results. For large projects, eo test –optimize runs only the tests affected by uncommitted changes, which can save time during development.

Running unit test locally on the host machine

2. At the end of the unit test job, call eo report unittest to upload the test report (e.g., the JUnit XML report for Ceedling). This will push the pass/fail metrics to the EmbedOps platform. The web app then tracks unit test counts and trends over time for a detailed understanding of firmware quality over the development cycle.

Running unit test on GitLab CI pipeline

The Branches page on the EmbedOps platform shows the passing test

The Unit Tests page on the EmbedOps platform shows the unit test trends over time

The Consequences of Insufficient Testing

Unfortunately, there are numerous instances of commercial Bluetooth products reaching the market and failing as a result of errors that could have been prevented with sufficient unit testing. The Samsung Mobile Exynos 7885 and even Bluetooth stacks, drivers, and software development kits (SDKs) from embedded technology suppliers like Espressif Systems, TI, Microchip, and others are among them.

This roster of household name technology brands should be both comforting and cautionary. Poor testing, or not testing at all, is an industry-wide problem that plagues everyone from Fortune 500 organizations down to small teams of contractors.

EmbedOps helps build robust testing practices into development workflows by providing an intuitive, modern development infrastructure that “shifts left” testing into the development process. Dojo Five and its partners have successfully leveraged the EmbedOps framework, methodologies, and practices in countless commercial embedded products, including BLE-enabled drones, medical devices, clinical wearables, and more.

Takeaways

This article has covered several discussions of how the Dojo Five EmbedOps platform can streamline testing for verified operating quality:

  1. EmbedOps creates consistent build and test containers to eliminate “works on my machine” problems that are common across distributed development teams.
  2. The eo add unittest command is used to scaffold Ceedling and Google Test testing tools. Developers should run tests frequently using the eo test command, and these test runs can be optimized with –optimize.
  3. Unit tests can check that a function returns the expected result for a given input.  For a function that restructures data format, for example, it tests that for a known set of input data, the code returns the data in the correct new structure or produces errors correctly.
  4. In embedded systems, especially, many things can’t be directly addressed through I/O-independent unit tests, such as data acquisition functionality. Here, developers must use mocks, fakes, and stubs to isolate any dependencies before unit testing—a section in this blog explains these test doubles in full.
  5. When unit tests reach their limits, HIL tests offer the next step for testing code performance using real-world hardware and data interactions.

Conclusion

Unit testing may seem daunting at first, but Dojo Five EmbedOps streamlines the process for consistent results across distributed teams. With a BLE sensor application example, this article has shown just how quickly teams can set up these practices using their preferred CI platform and testing framework to dramatically improve the quality of embedded products.

For developers looking to get hands-on experience with the EmbedOps platform, Dojo Five offers its EmbedOps DevKit—available from the Dojo Five team. After running through the DevKit Quickstart guide, developers can explore other EmbedOps templates, such as memory analysis and cppcheck, that support additional debugging and analysis during development.

By enabling easy adoption of thorough testing and reporting procedures, EmbedOps helps embedded teams build confidence when commercializing their products. Moreover, this testing streamlines certification so that when customers receive products, quality and reliability are assured.

Additional Resources

Discover why Dojo Five EmbedOps is the embedded enterprise choice for build tool and test management.

Sign up to receive a free account to the EmbedOps platform and start building with confidence..

  • Connect a repo
  • Use Dev Containers with your Continuous Integration (CI) provider
  • Analyze memory usage
  • Integrate and visualize static analysis results
  • Perform Hardware-in-the-Loop (HIL) tests
  • Install the Command Line Interface for a developer-friendly experience

Subscribe to our Monthly Newsletter

Subscribe to our monthly newsletter for development insights delivered straight to your inbox.

Interested in learning more?

Best-in-class embedded firmware content, resources and best practices

Laptop with some code on screen

I want to write my first embedded program. Where do I start?

The boom in the Internet of Things (IoT) commercial devices and hobbyist platforms like the Raspberry Pi and Arduino have created a lot of options, offering inexpensive platforms with easy to use development tools for creating embedded projects. You have a lot of options to choose from. An embedded development platform is typically a microcontroller chip mounted on a circuit board designed to show off its features. There are typically two types out there: there are inexpensive versions, sometimes called

Read More »
Medical device monitoring vitals

IEC-62304 Medical Device Software – Software Life Cycle Processes Primer – Part 1

IEC-62304 Software Lifecycle requires a lot of self-reflection to scrutinize and document your development processes. There is an endless pursuit of perfection when it comes to heavily regulated industries. How can you guarantee something will have zero defects? That’s a pretty hefty task. The regulatory approach for the medical device industry is process control. The concept essentially states that if you document how every step must be completed, and provide checks to show every step has been completed properly, you

Read More »
Operating room filled with medical devices

IEC-62304 Medical Device Software – Software Life Cycle Processes Primer – Part II

Part I provides some background to IEC-62304. Part II provides a slightly more in-depth look at some of the specifics. The IEC 62304 Medical Device Software – Software Lifecycle Processes looks into your development processes for creating and maintaining your software. The standard is available for purchase here. So what activities does the standard look at? Here are some of the major topics. For any given topic, there will be a lot more specifics. This will look at a few

Read More »