# How to Run bpftime Unit Tests: Complete Guide for Developers

> Learn how to run bpftime unit tests with our comprehensive guide. Execute the Catch2 test suite covering runtime, daemon, and verifier components. Follow simple build and test commands for instant verification.

- Repository: [eunomia-bpf/bpftime](https://github.com/eunomia-bpf/bpftime)
- Tags: how-to-guide
- Published: 2026-03-01

---

**Run `make unit-test` after building with `make build-unit-test` to execute the Catch2-based test suite covering the runtime, daemon, and verifier components.**

The `bpftime` project provides a comprehensive unit testing framework built on **Catch2** to validate its userspace eBPF runtime, daemon IPC mechanisms, and program verifier. Whether you are contributing new features or verifying your build environment, knowing how to run bpftime unit tests correctly ensures code quality and system compatibility.

## Understanding the bpftime Unit Test Architecture

### Test Framework and Directory Structure

All unit tests in `bpftime` utilize the **Catch2** header-only library, which provides the `TEST_CASE` macro for defining test scenarios. The test suite is organized into three primary directories:

- `runtime/unit-test/…` – Contains tests for the userspace eBPF VM, map implementations (hash maps, ring buffers, stack traces), helper functions, and attach mechanisms. Example: [`runtime/unit-test/test_probe.cpp`](https://github.com/eunomia-bpf/bpftime/blob/main/runtime/unit-test/test_probe.cpp) validates probe read/write operations.
- `daemon/test/…` – Houses tests for the daemon side of the shared-memory IPC system.
- `bpftime-verifier/test/…` – Includes tests for the PREVAIL-based eBPF program verifier.

### Makefile Targets for Test Orchestration

The top-level `Makefile` defines specific targets to manage the testing lifecycle:

- `build-unit-test` – Configures CMake with `-DBPFTIME_ENABLE_UNIT_TESTING=1` and compiles the test binaries.
- `unit-test-runtime` – Builds eBPF test programs under `runtime/test/bpf`, copies the resulting `.bpf.o` files, sets `BPFTIME_VM_NAME=llvm`, and executes the runtime test binary.
- `unit-test-daemon` – Runs the daemon test executable independently.
- `unit-test` – A convenience target that depends on both `unit-test-runtime` and `unit-test-daemon` to run the complete suite.

## Step-by-Step Guide to Running bpftime Unit Tests

### Prerequisites and Dependencies

Before running tests, ensure your environment includes:

- **CMake** (3.16 or higher)
- A **C++20-compatible compiler** (GCC 10+ or Clang 12+)
- **LLVM development packages** (required for the JIT backend used during testing)
- Standard build tools (make, git)

The repository README contains the specific package installation commands for Ubuntu, Fedora, and other distributions.

### Building the Test Binaries

Compile the unit test executables using the dedicated Makefile target:

```bash
make build-unit-test

```

This command performs two critical actions:

1. Configures the build with `-DBPFTIME_ENABLE_UNIT_TESTING=1` to include test sources.
2. Compiles two executables: `bpftime_runtime_tests` and `bpftime_daemon_tests` (located in the `build/` directory).

### Executing the Full Test Suite

Run the complete test suite with a single command:

```bash
make unit-test

```

This executes both the runtime and daemon tests sequentially. The runtime portion automatically handles eBPF program compilation and environment setup, including setting `BPFTIME_VM_NAME=llvm` to utilize the LLVM JIT backend.

### Running Individual Test Components

For targeted testing during development, run specific components:

```bash

# Execute only daemon IPC tests

make unit-test-daemon

# Execute only runtime tests (maps, VM, helpers)

make unit-test-runtime

```

The `unit-test-runtime` target first builds the eBPF object files in `runtime/test/bpf/` and copies them to the appropriate directory before invoking the test binary.

## Advanced Testing Scenarios

### Testing with Alternative VM Backends

By default, the runtime tests use the **LLVM JIT** backend. To validate against the **ubpf** interpreter or other VM implementations, override the environment variable:

```bash
BPFTIME_VM_NAME=ubpf make unit-test-runtime

```

This flexibility ensures compatibility across different execution engines and helps identify backend-specific regressions.

## Summary

- **bpftime** uses **Catch2** for unit testing, with tests organized under `runtime/unit-test/`, `daemon/test/`, and `bpftime-verifier/test/`.
- Use `make build-unit-test` to compile test binaries and `make unit-test` to execute the full suite.
- Run `make unit-test-runtime` or `make unit-test-daemon` to test specific components.
- Set `BPFTIME_VM_NAME` to switch between LLVM JIT and ubpf backends during testing.

## Frequently Asked Questions

### What testing framework does bpftime use?

bpftime uses the **Catch2** header-only testing framework. This is evident in test files like [`runtime/unit-test/test_probe.cpp`](https://github.com/eunomia-bpf/bpftime/blob/main/runtime/unit-test/test_probe.cpp) and [`runtime/unit-test/maps/test_stack_map.cpp`](https://github.com/eunomia-bpf/bpftime/blob/main/runtime/unit-test/maps/test_stack_map.cpp), which utilize the `TEST_CASE` macro and assertion macros provided by Catch2.

### How do I run only the runtime tests without the daemon?

Execute `make unit-test-runtime` from the repository root. This target builds the necessary eBPF test programs, sets the `BPFTIME_VM_NAME=llvm` environment variable, and runs only the `bpftime_runtime_tests` binary, skipping the daemon tests entirely.

### Can I use a different VM backend for testing?

Yes. Override the `BPFTIME_VM_NAME` environment variable before invoking the test target. For example, run `BPFTIME_VM_NAME=ubpf make unit-test-runtime` to test against the ubpf interpreter instead of the default LLVM JIT backend.

### Where are the test logs located when tests fail?

Catch2 outputs test results directly to stdout/stderr with detailed failure messages including file names and line numbers (e.g., `runtime/unit-test/test_probe.cpp:25`). The Makefile does not redirect output to log files by default, so you should capture the terminal output or run tests with output redirection (`make unit-test 2>&1 | tee test.log`) to preserve failure logs.