Why I Started Using This Tool
When I first joined a team working on safety-critical embedded software, I was handed a codebase, a testing mandate, and a tool called LDRA TBRUN. My team kept talking about "white box coverage" and "gray box harnesses," and I smiled and nodded while quietly panicking.
If that sounds familiar, this guide is for you. I spent weeks piecing together the theory, the tool mechanics, and the practical setup steps. Here is everything I wish someone had handed me on day one โ organized, plain-English, and honest about the parts that trip beginners up.
What It Does
LDRA TBRUN (Test Bed RUN) is a unit and integration testing framework that is part of the broader LDRA tool suite, which is widely used in safety-critical industries including nuclear, aerospace, automotive, medical devices, and rail. At its core, TBRUN automates the execution of test cases against your source code while simultaneously measuring how thoroughly those tests exercise the code's internal structure.
Think of it this way: most basic testing tools tell you whether your software passes or fails a test. LDRA TBRUN goes a level deeper โ it tells you which lines, branches, and conditions inside your code were actually reached during the test, and which were never touched at all. In safety-critical development, that distinction is not just useful โ it is often a regulatory requirement.
Key capabilities at a glance:
- Automated test case execution โ run hundreds of unit tests against individual functions or modules without manual intervention
- Structural coverage measurement โ track statement, branch, MC/DC (Modified Condition/Decision Coverage), and other coverage metrics required by standards like DO-178C and ISO 26262
- Test harness generation โ automatically build the scaffolding (stubs, drivers, and wrappers) needed to isolate and call individual units under test
- Support for multiple testing strategies โ natively handles both white box and gray box testing approaches, which is the central focus of this guide
Fundamental Theory: White Box, Gray Box, and Black Box Testing
Before touching the tool, you need a solid mental model of the three core testing paradigms. These are not just academic categories โ they directly determine how you configure LDRA TBRUN and what coverage metrics you can realistically achieve.
Black Box Testing
In black box testing, the tester has no visibility into the internal structure of the code being tested. You feed inputs in, observe outputs out, and judge correctness purely against a specification. You do not care how the code works internally โ only that it behaves correctly from the outside.
When it is appropriate: system-level acceptance testing, user interface validation, API contract testing, or any scenario where the implementation details are proprietary or irrelevant to the test goal.
Limitation: because you cannot see inside the code, you have no way to know which internal paths your tests are covering. You could have excellent functional results and still have large swathes of untested logic hiding inside your modules.
White Box Testing
White box testing (also called clear box, glass box, or structural testing) gives the tester full visibility into the source code. You design your test cases not just around what the code is supposed to do, but around its actual internal structure โ its branches, loops, conditionals, and data flows.
When it is appropriate: unit testing of individual functions, safety-critical systems where you must prove every logical path has been exercised, and compliance with standards like DO-178C (avionics), ISO 26262 (automotive), or IEC 62443 (industrial).
Why it matters: white box testing is the only way to achieve verified structural coverage. You can deliberately craft inputs that force the code down the "else" branch of an if-statement, or ensure a loop executes zero times, once, and multiple times โ scenarios that black box testing might miss entirely.
Gray Box Testing
Gray box testing sits between the two extremes. The tester has partial knowledge of the internal structure โ typically the high-level architecture, interfaces, and data structures โ but not necessarily line-by-line source code access during test design. The tests are designed with awareness of how components interact, but execution may happen at a higher integration level rather than isolated unit level.
When it is appropriate: integration testing where you understand module interfaces but are treating sub-components as semi-opaque units; testing firmware where you can observe memory states but not step through every source line; validating software against hardware in a target environment where some internals are abstracted away by the runtime or OS.
The practical distinction: in gray box testing you are usually still measuring structural coverage (so source code is involved), but the test design perspective and the execution environment introduce a layer of opacity that pure white box testing does not have.
A useful mental comparison:
| Dimension | Black Box | Gray Box | White Box |
|---|---|---|---|
| Source code visibility | None | Partial | Full |
| Test design basis | Specification only | Spec + architecture | Spec + internal structure |
| Coverage measurable? | No | Partially | Yes, fully |
| Typical level | System/acceptance | Integration | Unit |
| LDRA TBRUN applicability | Limited | Yes | Yes (primary use) |
LDRA TBRUN Specifics: How the Tool Implements Each Approach
White Box Testing in LDRA TBRUN
When you configure TBRUN for white box testing, the workflow centers on three phases: instrumentation, harness generation, and coverage collection.
1. Instrumentation
Before your tests run, LDRA instruments your source code. This means the LDRA toolchain inserts lightweight monitoring probes at every branch point, decision, and statement in your code. These probes do not change the functional behavior of the software โ they simply record, at runtime, whether each point was reached.
This is the foundation of white box coverage measurement. Without instrumentation, the tool has no mechanism to know what happened inside your functions during test execution.
Common beginner mistake: forgetting to re-instrument after modifying source code. If you change a function and run tests against a previously instrumented build, your coverage data will be misaligned with the actual code. Always instrument fresh after any source change.
2. Test Harness Generation
Unit testing requires isolation โ you want to test one function at a time without triggering real behavior in all the other functions it calls. LDRA TBRUN generates a test harness automatically, which includes:
- Stubs: replacement functions that stand in for the real implementations of called functions. A stub might simply return a fixed value or log that it was called, without executing the real code.
- Drivers: a wrapper that calls your function under test with specific input values and captures the outputs.
- Global variable initializers: setup code that puts shared memory and global state into known starting conditions before each test case runs.
In white box mode, TBRUN has full access to the source code and can generate highly accurate stubs based on the actual function signatures and data types in your project. This precision is one of white box testing's biggest practical advantages.
3. Test Case Design and Coverage Targets
With the harness in place, you create test cases by specifying input values and expected outputs. In LDRA TBRUN, this is done through its test case editor or imported from external test specification documents.
The key discipline in white box testing is designing test cases with your coverage metric in mind. The common metrics TBRUN measures include:
- Statement Coverage (SC): every executable statement has been reached at least once
- Branch Coverage (BC): every decision outcome (true/false) has been exercised
- MC/DC (Modified Condition/Decision Coverage): each individual condition in a compound decision has independently affected the decision outcome โ required by DO-178C Level A and ISO 26262 ASIL D
After each test run, TBRUN generates a coverage report showing exactly which lines, branches, and conditions were hit. Your job as a tester is to look at the uncovered items and ask: "what input do I need to reach this path?" You then add test cases until you hit your coverage target โ often 100% MC/DC for the most safety-critical code.
Practical tip: start with branch coverage before attempting MC/DC. Branch coverage will surface the obviously missing paths quickly, and then you can focus MC/DC effort on the specific compound decisions that remain uncovered.
Gray Box Testing in LDRA TBRUN
Gray box testing in TBRUN typically comes into play at the integration testing level or when testing software running on a target hardware environment (as opposed to a host simulation).
Integration-Level Gray Box Setup
When you move from unit testing individual functions to testing how multiple modules interact, you may not want to stub out every called function. Instead, you let some real implementations run, treating them as semi-opaque components. TBRUN supports this by allowing you to selectively stub some functions while linking real implementations of others into the test build.
This configuration means you are:
- Measuring structural coverage of the module under primary focus (white box perspective)
- Allowing real side effects from called modules to influence behavior (gray box perspective)
- Verifying that the integration seams โ the interfaces between components โ behave correctly under realistic conditions
Target-Based Testing
A very common gray box scenario in embedded systems development is running tests on the actual target hardware rather than a host PC simulator. In this setup:
- The source is instrumented and compiled with the target compiler for the real processor
- The test harness runs on the target
- Coverage data is captured and downloaded back to the LDRA host tool for analysis
You have full source-level visibility (white box instrumentation), but the execution environment โ interrupts, hardware timers, memory-mapped peripherals โ introduces real-world complexity that a host simulation cannot fully replicate. That mixture of source transparency and environmental opacity is the defining characteristic of gray box testing in TBRUN.
My Honest Pros & Cons
โ What I Love
- Coverage traceability is built-in โ you can link each test case directly to a requirements ID, which is exactly what auditors want to see when you submit for DO-178C or ISO 26262 certification
- Harness generation saves enormous time โ building stubs manually for a large codebase is tedious and error-prone; TBRUN does it in seconds and gets the data types right
- The gap analysis report is genuinely useful โ after a test run, TBRUN shows you exactly what is not covered and highlights the specific branch or condition you are missing, which makes writing the next test case straightforward rather than a guessing game
- Standards compliance is first-class โ the tool is certified by tool qualification authorities for use in DO-178C, ISO 26262, and IEC 61508 projects, so you are not bolting compliance onto a general-purpose tool
โ What Could Be Better
- The learning curve for project configuration is steep โ getting the compiler integration, instrumentation settings, and linker scripts right for a new project can take days, and the documentation assumes more prior knowledge than beginners usually have
- License costs are significant โ TBRUN is an enterprise tool with enterprise pricing; small teams or hobbyist projects will find it inaccessible, and the cost structure can be confusing with add-ons for target environments and additional coverage metrics
Pricing: Is It Worth It?
LDRA does not publish list prices publicly โ licensing is done through direct sales and is typically structured per-seat with optional add-ons for specific target environments, additional language support, or requirements management integration.
In practice, TBRUN is budgeted as part of a safety certification effort, where the tool cost is a small fraction of the overall project cost compared to the regulatory risk of inadequate testing. For a DO-178C Level A project, the cost of not having verifiable coverage is a failed certification โ which is orders of magnitude more expensive than the tool license.
My take: if you are working on a safety-critical project with a real certification mandate, TBRUN pays for itself quickly; if you are not in that context, lighter-weight open-source alternatives are worth exploring first.
Common Pitfalls and Troubleshooting Tips
Pitfall 1 โ Treating coverage as the goal rather than the evidence Reaching 100% MC/DC does not mean your software is correct โ it means your tests have exercised every logical path. You still need correct expected values in your test cases. Coverage without assertions is just code execution, not verification.
Pitfall 2 โ Stub behavior masking integration defects In white box unit testing, your stubs return fixed values. If a real called function would actually return an error code under certain conditions, your white box tests will never surface that interaction. This is precisely why gray box integration testing is a necessary complement, not a replacement.
Pitfall 3 โ Ignoring unreachable code warnings LDRA will sometimes flag code as structurally unreachable โ paths the compiler or logic analysis determines can never execute. Do not dismiss these. Unreachable code in safety-critical software is often a symptom of a logic error or a dead code remnant that should be removed. Address it, do not just exclude it from coverage targets.
Pitfall 4 โ Running stale builds After any source change, regenerate stubs and re-instrument before running tests. LDRA does have mechanisms to detect build mismatches, but do not rely on them โ build fresh as a discipline.
Final Verdict
LDRA TBRUN is a serious tool built for serious testing contexts. If you are a junior engineer joining a safety-critical project in nuclear, aerospace, automotive, or medical devices, investing time to understand how it implements white box and gray box testing will pay dividends for your entire career in that domain.
Who should use this: teams working under DO-178C, ISO 26262, IEC 62443, or similar standards where structural coverage measurement and test traceability are regulatory requirements โ not just nice-to-haves.
Who should look elsewhere: developers building commercial software without safety certification requirements, or students learning testing fundamentals who would benefit from starting with lighter-weight, open-source unit testing frameworks before encountering enterprise-grade tooling.
Start with white box unit testing on a single well-defined module, get comfortable with the harness generation and coverage reporting workflow, and then expand to gray box integration scenarios once you have that foundation solid. The theory and the tool will make much more sense when you build up from one function at a time.