# How to Test F Prime Code: Component Unit Testing with Google Test

> Learn how to test F Prime code using Google Test. Discover the three-layer architecture for component unit testing and streamline your development with fprime-util check.

- Repository: [NASA/fprime](https://github.com/nasa/fprime)
- Tags: how-to-guide
- Published: 2026-07-13

---

**F Prime unit testing relies on a three-layer architecture where `fprime-util impl --ut` generates scaffold files, developers implement test logic in a `Tester` class derived from `GTestBase`, and the `register_fprime_ut` CMake macro integrates everything with Google Test for execution via `fprime-util check`.**

Testing flight software in the nasa/fprime repository requires a structured workflow that verifies component behavior at the unit level. The framework automates the creation of test harnesses through autocoded base classes while providing assertion macros specific to telemetry, events, and command responses. This guide walks through the complete workflow from scaffold generation to coverage analysis.

## Understanding the F Prime Unit Test Architecture

F Prime component testing follows a three-class hierarchy defined in the `test/ut/` directory. This design separates auto-generated infrastructure from developer-written test logic.

### TesterBase: The Port Mirroring Foundation

The **TesterBase** class is auto-generated for each component and mirrors its ports, internal histories, and parameter structures. It provides helper methods to interact with the component under test, including `sendCOMMAND`, `invoke_to_<port>`, `paramSet_<Param>`, and `setTime`. The base also manages history buffers through `clearHistory()`, which must be called between test actions to ensure isolated assertions.

### GTestBase: Google Test Integration

The **GTestBase** class derives from `TesterBase` and introduces Google Test headers alongside F Prime-specific assertion macros. This layer is technically optional for platforms that cannot link Google Test, but it is standard for development environments. It provides macros like `ASSERT_TLM_*`, `ASSERT_EVENTS_*`, and `ASSERT_CMD_RESPONSE_*` that verify component outputs against expected values.

### Tester: Developer Test Implementation

The **Tester** class is where you write concrete test cases. It inherits from `GTestBase` (or `TesterBase` if omitting Google Test) and contains methods like `testNominal()` and `testErrorCase()`. Here you implement the sequence of stimuli and assertions that define each test scenario. The class typically manages the component instance and calls `connectPorts()` and `initComponents()` during setup.

## Generating Test Scaffolds with fprime-util

All F Prime unit tests begin with scaffold generation. Execute the following command in your component directory:

```bash
fprime-util impl --ut

```

This creates template files under `test/ut/`:

- `<Component>Tester.template.hpp` and `.cpp` – Rename these to `<Component>Tester.hpp` and `<Component>Tester.cpp` to implement your test class
- [`TestMain.cpp`](https://github.com/nasa/fprime/blob/main/TestMain.cpp) – The Google Test entry point containing `main()` and `TEST()` macros

The templates include placeholders for namespace declarations, constructor/destructor definitions, and the initial `connectPorts()` implementation required to wire the test harness to the component's input and output ports.

## Implementing Test Cases and Helper Methods

After renaming the templates, populate the `Tester` class with test logic. The implementation typically follows this pattern:

```cpp
#include "<Namespace>/<Component>/test/ut/<Component>Tester.hpp"
#include "<Namespace>/<Component>/<Component>.hpp"

namespace <Namespace> {

<Component>Tester::<Component>Tester() 
    : <Component>GTestBase("<Component>Tester", MAX_HISTORY_SIZE) {
    this->connectPorts();
    this->initComponents();
}

void <Component>Tester::testNominal() {
    // Clear history buffers before the test action
    this->clearHistory();
    
    // Send a command with opcode, argument, and instance ID
    this->sendCOMMAND_NAME(0, 42, 7);
    
    // Dispatch for active/queued components
    this->component.doDispatch();
    
    // Verify command response
    ASSERT_CMD_RESPONSE_SIZE(1);
    ASSERT_CMD_RESPONSE(0, 
        <Component>::OPCODE_COMMAND_NAME, 
        0, 
        Fw::CmdResponse::OK);
    
    // Verify telemetry channel
    ASSERT_TLM_ChannelName_SIZE(1);
    ASSERT_TLM_ChannelName(0, 42);
}

} // namespace <Namespace>

```

Key implementation details include calling `clearHistory()` to reset internal buffers, invoking `doDispatch()` for active components to process queued messages, and using the `sendCOMMAND_*` methods generated by the autocoder to stimulate command input ports.

## Writing Test Assertions with F Prime Macros

F Prime extends Google Test with domain-specific assertions that verify flight software behavior. These macros check the component's history buffers rather than immediate return values:

- **Command Verification**: `ASSERT_CMD_RESPONSE(opcode, seq, response)` validates command execution status
- **Telemetry Verification**: `ASSERT_TLM_<ChannelName>(index, expectedValue)` checks telemetry values by channel name
- **Event Verification**: `ASSERT_EVENTS_<EventName>(index, args...)` verifies event reporting
- **Port Call Verification**: `ASSERT_FROM_PORT_<PortName>_SIZE(count)` ensures port invocations occurred

For components with complex state transitions, use the **STest** library to implement rule-based testing. Include [`STest/Random/Random.hpp`](https://github.com/nasa/fprime/blob/main/STest/Random/Random.hpp) to seed reproducible random data via `STest::Random::seed()` in your [`TestMain.cpp`](https://github.com/nasa/fprime/blob/main/TestMain.cpp).

## Registering Tests in CMakeLists.txt

Each component must register its unit test target using the `register_fprime_ut` macro in its [`CMakeLists.txt`](https://github.com/nasa/fprime/blob/main/CMakeLists.txt):

```cmake
register_fprime_ut(
    AUTOCODER_INPUTS "${CMAKE_CURRENT_LIST_DIR}/<Component>.fpp"
    SOURCES
        "${CMAKE_CURRENT_LIST_DIR}/test/ut/<Component>TestMain.cpp"
        "${CMAKE_CURRENT_LIST_DIR}/test/ut/<Component>Tester.cpp"
    DEPENDS STest
    UT_AUTO_HELPERS  # Automatically generates connectPorts/initComponents

)

```

The `AUTOCODER_INPUTS` parameter links the component's FPP model files, while `UT_AUTO_HELPERS` instructs the build system to generate standard helper implementations. The `DEPENDS STest` line includes the testing utilities library for random data generation and rule-based test scenarios.

## Building and Executing Unit Tests

Compile and run tests using the F Prime utility commands:

```bash

# Build all unit test binaries

fprime-util build --ut

# Execute all registered tests

fprime-util check

# Run with coverage analysis

fprime-util check --coverage

```

The `--coverage` flag generates gcov reports showing line and branch coverage for your component implementation. Tests execute as standard Google Test binaries, supporting filter flags and verbose output through the underlying test framework.

## Summary

- **Scaffold Generation**: Use `fprime-util impl --ut` to create `Tester` class templates and [`TestMain.cpp`](https://github.com/nasa/fprime/blob/main/TestMain.cpp) in the `test/ut/` directory
- **Three-Layer Architecture**: Inherit from `GTestBase` (which extends `TesterBase`) to access port helpers and assertion macros
- **Test Implementation**: Write test methods in the `Tester` class, calling `clearHistory()` between actions and `doDispatch()` for active components
- **Assertion Macros**: Use `ASSERT_CMD_RESPONSE_*`, `ASSERT_TLM_*`, and `ASSERT_EVENTS_*` to verify component outputs against recorded histories
- **Build Integration**: Register tests with `register_fprime_ut` in [`CMakeLists.txt`](https://github.com/nasa/fprime/blob/main/CMakeLists.txt), including `STest` dependencies for advanced testing
- **Execution**: Build with `fprime-util build --ut` and run with `fprime-util check --coverage`

## Frequently Asked Questions

### How do I generate the initial test files for an F Prime component?

Run `fprime-util impl --ut` from within the component directory. This command creates `<Component>Tester.template.hpp`, `<Component>Tester.template.cpp`, and [`TestMain.cpp`](https://github.com/nasa/fprime/blob/main/TestMain.cpp) under `test/ut/`. Rename the template files to remove the `.template` extension before implementing your test logic.

### What is the difference between TesterBase and GTestBase?

`TesterBase` is an auto-generated class that mirrors your component's ports and provides methods like `sendCOMMAND` and `clearHistory`. `GTestBase` inherits from `TesterBase` and adds Google Test integration plus F Prime-specific assertion macros like `ASSERT_TLM_*`. You typically inherit from `GTestBase` to write tests, though you can use `TesterBase` directly on platforms without Google Test support.

### How do I verify command handling in F Prime unit tests?

Invoke commands using the auto-generated `sendCOMMAND_<Name>` method, then call `doDispatch()` if testing an active component. Verify the response using `ASSERT_CMD_RESPONSE_SIZE(1)` followed by `ASSERT_CMD_RESPONSE(index, opcode, seq, Fw::CmdResponse::OK)` to confirm the command executed successfully.

### How do I run F Prime unit tests with code coverage?

Execute `fprime-util check --coverage` after building with `fprime-util build --ut`. This runs all registered tests and generates gcov coverage reports showing which lines of your component implementation were exercised during the test suite execution.