Skip to main content
Unit testing fundamentals for embedded C and C++ with Razorcat TESSY, explained by GSAS Micro Systems for engineering teams in India, the UAE and Sri Lanka

Unit Testing Fundamentals for Embedded C and C++: Units, Interfaces, Test Drivers, Stubs and What the Safety Standards Demand

GSAS Engineering · · 9 min read

In embedded C a unit is a single function, the smallest reasonable test object of a C program, while in C++ the unit is a method, which cannot be executed without an object. Unit testing exercises that unit in isolation through a generated test driver that supplies the startup code, the main() entry point and the call, with stub functions replacing the units it calls, so the observed result depends on the unit alone.

The Word “Unit” Is Doing More Work Than You Think

Ask five embedded engineers what a unit test is and you get five answers: a call in a main() somewhere, a suite in CI, a bring-up script, a number on a dashboard. That ambiguity is expensive, because a safety assessor asking for unit test evidence is asking a precise question.

What Counts as a Unit in C

Razorcat, the Berlin developer of TESSY, puts it plainly in the TESSY 5.1 Manual glossary: a unit is a single function, the smallest reasonable test object of a C program. A Test Object is “the function to be tested,” and a TESSY module is built primarily from the test object (in C, a function in the sense of C) plus source files, compiler settings, interface description and test data.

The derivation is in the same manual. Part 4 of IEC 61508 defines a software module as a construction consisting of procedures and/or data declarations that can interact with other such modules, and for embedded software written in C, Razorcat notes, we can take a C-level function as a module. To avoid confusion with C source files, the manual calls those functions units. The standard says “module,” your build system says “translation unit,” and the discipline means one C function at a time.

What Counts as a Unit in C++

In C++ the unit is a method, and the mechanics change because a method cannot be called without an object. Razorcat’s TESSY Application Note #038, “Using C++,” is explicit:

  • On opening a module, TESSY analyzes the source files and provides the list of class constructors, methods and functions for all classes in them. The interface of each testable method appears in the Test Interface Editor, with the class member variables.
  • Constructors appear as test objects in their own right. Destructors do not appear in the Test Data Editor, because calling one destroys the object and TESSY cannot read values from destroyed objects.
  • Unlike normal C tests, per Razorcat, you always need a C++ object to execute any method. That instance comes from a special this variable: reuse one across test cases and it retains internal state, or create a new one per test step.
  • Every method can throw, so a special global output variable named “throws exception” is specified per test step. Overloads are disambiguated by signature: per Razorcat, the test object name includes the whole method signature.

Interface Analysis: The Unit’s Real Contract

Razorcat’s manual defines the interface of a unit as the input variables, meaning variables read by the unit, together with the output variables, meaning variables written by it. A variable can be both, and the return value, if present, is always an output. Crucially, the structure of a test case follows from the structure of the interface.

That is why unit testing is black-box work: per Razorcat, it tests at the interface of the unit and does not consider its internal structure. In TESSY the interface description, the passing direction and type of each parameter, global and external variable, is determined automatically and made changeable in the Test Interface Editor. Razorcat is equally clear about what falls outside: the interaction of units is not tested during unit testing, and interrupt behaviour is out of scope.

Test Drivers and Stubs

A C function is not a program. Something has to start the microcontroller, enter main(), set the inputs, call the function and capture what comes back. Razorcat’s glossary defines a Test Driver as C source files generated by TESSY for test execution, compiled and linked to build an application that prepares the input data, calls the test object and stores the actual result data. Per the manual, that driver carries startup code for the embedded microcontroller, the main() entry point, the call to the unit under test, and stub code where required.

A stub function, per Razorcat’s glossary, is a piece of code used to stand in for some other programming functionality. Per Application Note #004, “Using Stub Functions,” TESSY recognizes all external functions called by a test object and can provide stubs to be called instead, and local functions defined within the source file can also be replaced. Advanced Stubs handle the stub’s parameters and return values like normal inputs and outputs, so they surface in the Test Data Editor and the report.

Isolation Is the Whole Point

Razorcat’s manual states the definition that matters at audit: during unit testing of C programs a single C-level function is tested rigorously and in isolation from the rest of the application, where isolated means the test result does not depend on the behaviour of the other units, achieved by directly calling the unit under test and replacing calls to other units with stub functions.

The counter-example is sharper. Razorcat’s manual describes an “original binary test” approach, loading the unchanged application and running it until the unit is eventually reached. Its documented disadvantages: no control over when, or whether, the unit is reached; stubs cannot be used, so a unit is always tested using the other units of the application and errors of called units may show up during the test; and arbitrary test data cannot be used. Razorcat concludes that one could even insist this is not a unit test in its strictest sense. Certification authorities agree: EASA’s Certification Memorandum CM-SWCEH-002 describes coverage measurements taken by “executing requirements-based tests of that module in isolation from other program modules.”

On-Target Versus Host Execution

Host execution is fast and cheap. Target execution is what the certificate is about. Razorcat’s manual states that for embedded software it is essential that the unchanged source code, with all its non-ANSI keywords and peculiarities, is used for testing. Its example is a cross compiler permitting bit fields narrower than the integer size, which ANSI C forbids but which suits the target perfectly, and it observes that unit test results are worthless if that size cannot be maintained during the tests. It adds that the concluding tests must at least execute on the actual hardware, that is, the embedded microcontroller.

Host or simulatorOn target
CompilerPer Razorcat’s Application Note #048, verification of the TESSY core workflow covers tests conducted on a Windows host system using the GNU GCC compilerYour cross compiler, preferably the exact version used for the application (per Razorcat)
Compiler-specific behaviourNot exercised, so constructs such as narrow bit fields are absentRepresented, which is why Razorcat calls unchanged source essential
Memory constraintsEffectively noneMust fit target memory, hardest on single-chip parts (per Razorcat)
Typical useFast feedback, CI regression runsConcluding tests, which per Razorcat must at least run on the actual hardware

Razorcat’s TESSY 5 flyer lists test execution on hosts, simulators and hardware, so both columns are the same tool. Crossing between them is where adaptations bite, which is why Razorcat ships test driver communication tests, documented in Application Note #048, “Using the Test Driver Communication Tests.” They check the transfer of test data to the target and the transfer of data back from it, and Razorcat states that when TESSY is used within a safety related environment it is strongly recommended to run them, after initial project setup and after any change to the environment settings. For the debug-probe side, see our guide to TESSY on target with SEGGER J-Link.

Why the Standards Require This Rather Than Suggest It

Unit testing is not a good practice the safety standards nod at. It is normative text with “shall” in it.

IEC 61508-3

IEC 61508-3:2010 clause 7.4.7.1 states that each software module shall be verified as required by the software module test specification developed during software system design; clause 7.4.7.2 that this verification shall show whether or not each software module performs its intended function and does not perform unintended functions; clause 7.4.7.3 that the results shall be documented.

The annex tables set the intensity. In Table A.5, dynamic analysis and testing is Recommended at SIL 1 and Highly Recommended from SIL 2, while functional and black-box testing is Highly Recommended at every SIL. Table B.2 lists 100 percent structural test coverage targets for entry points, statements, branches and conditions/MC/DC, rated Recommended or Highly Recommended as the SIL rises, with a footnote that where 100 percent cannot be achieved, for example on defensive code, an appropriate explanation should be given. More on our IEC 61508 page.

DO-178C

Airborne software uses different vocabulary for the same activity. EASA’s Certification Memorandum CM-SWCEH-002 quotes ED-12C/DO-178C section 5.0, that low-level requirements are software requirements from which source code can be directly implemented without further information, and refers throughout to low-level testing against them. The purpose of structural coverage analysis, per the same memorandum, is to detect code that was not exercised during requirements-based tests, and it sets the criteria per software level by citing Objectives 5, 6 and 7 of Annex A Table A-7. DO-178C, dated 13 December 2011, is recognised by the FAA in Advisory Circular AC 20-115D as an acceptable means of compliance. See our DO-178C page.

ISO 26262

Per Perforce, ISO 26262 is a risk-based safety standard derived from IEC 61508, Part 6 covers product development at the software level, and Part 6 includes several tables that define the methods that must be considered in order to achieve compliance. Razorcat ties one TESSY capability directly to the standard: Call Pair Coverage checks whether all call points of functions or methods within the test object have been executed at least once, which per Razorcat meets ISO 26262 requirements as an alternative coverage procedure for integration tests instead of function coverage. For the ASIL view, see our ISO 26262 Part 6 unit testing checklist.

StandardWhat it calls the activityCoverage expectation, as published
IEC 61508-3:2010Software module testing, clause 7.4.7, written with “shall”Table B.2: 100 percent entry point, statement, branch and condition/MC/DC coverage, rated R or HR by SIL
DO-178CLow-level testing against low-level requirements, judged by structural coverage analysisPer EASA CM-SWCEH-002: statements at Level C; plus decisions at Level B; plus MC/DC at Level A
ISO 26262Unit-level verification within Part 6, product development at the software levelPer Perforce, Part 6 tables define the methods that must be considered; per Razorcat, Call Pair Coverage meets ISO 26262 for integration tests

If a tool produces your evidence, its own status matters. Razorcat’s FAQ states that TESSY V5.1 is qualified for safety-related software development, and TESSY carries TUV SUD certificate Z10 078930 0004 Rev. 01. The certification report behind that certificate, RB84018C version 2.0 of 13 November 2023, classifies TESSY as an offline support tool of class T2 under IEC 61508-4:2010 and records it as suitable for use in safety-related development according to IEC 61508:2010 and EN 50128:2011/A2:2020 for any SIL, ISO 26262:2018 for any ASIL, and IEC 62304:2006+A1:2015 for any software safety class.

One last distinction, since teams still conflate them. Unit testing is dynamic, running the code and comparing actual results against expected ones, and Razorcat lists eight coverage measurements in TESSY including statement (C0), branch (C1), decision and MC/DC. Static analysis reasons about code without running it, and Perforce Helix QAC and Klocwork sit on that side. Evidence packages generally need both, as covered in our TESSY plus Helix QAC guide and MC/DC coverage guide.

Getting Started in India, the UAE and Sri Lanka

GSAS Micro Systems is the authorized Razorcat engineering partner for India, the UAE and Sri Lanka. Our engineers set TESSY up against your actual cross compiler and debugger, define the interface and stub strategy for your first modules, and get host and on-target execution running side by side, so the fast loop and the certification loop both exist from day one. We support teams from Bengaluru, Hyderabad, Chennai, Pune, Mumbai and Delhi NCR, with INR invoicing and one support channel.

Razorcat’s public product pages currently document TESSY 5.1. If your programme needs the scope and availability of a later version, ask GSAS and we will confirm what applies to your project. Request a TESSY evaluation or read more about Razorcat and GSAS.

Interested in Razorcat tools?

Talk to our application engineers for personalized tool recommendations.

Frequently asked questions

What is a unit in embedded C and C++?
In C it is a single function. Razorcat's TESSY 5.1 Manual glossary defines a unit as a single function, the smallest reasonable test object of a C program, and defines the Test Object as the function to be tested. In C++ the unit is a method: per Razorcat's TESSY Application Note #038, TESSY lists class constructors, methods and functions for every class in the module's source files, constructors appear as test objects in their own right, and unlike normal C tests you always need a C++ object to execute any method.
Why do unit tests need a test driver and stub functions?
Because a C function is not a program. Razorcat's glossary defines a Test Driver as C source files generated by TESSY, compiled and linked to build an application that prepares the input data, calls the test object and stores the actual result data, and the manual adds that the driver carries the startup code for the embedded microcontroller, the main() entry point and the call to the unit under test. Stubs stand in for the functions the unit calls. Per Razorcat's Application Note #004, TESSY recognizes all external functions called by a test object and can provide stubs to be called instead.
Why does isolation matter so much in embedded unit testing?
Because without it a failure cannot be attributed to the unit. Razorcat's manual defines isolated as meaning the test result does not depend on the behaviour of the other units, achieved by directly calling the unit under test and replacing calls to other units with stub functions. Its counter-example, the original binary test, cannot use stubs, so per Razorcat a unit is always tested using the other units of the application and errors of called units may show up during the test. EASA's Certification Memorandum CM-SWCEH-002 likewise describes coverage measurements taken by executing requirements-based tests of a module in isolation from other program modules.
Should embedded unit tests run on the host or on the target?
Both, at different points. Razorcat's manual states that for embedded software it is essential that the unchanged source code, with all its non-ANSI keywords and peculiarities, is used for testing, and that unit test results are worthless if compiler-specific behaviour such as a narrow bit field cannot be maintained during the tests. It goes on to state that the concluding tests must at least execute on the actual hardware, that is, the embedded microcontroller. Razorcat's TESSY 5 flyer lists test execution on hosts, simulators and hardware, so host runs give fast CI feedback while target runs produce the certification evidence.
Do IEC 61508, DO-178C and ISO 26262 require unit testing or just recommend it?
They require it. IEC 61508-3:2010 clause 7.4.7.1 states that each software module shall be verified as required by the software module test specification, clause 7.4.7.2 that this verification shall show whether or not each module performs its intended function and does not perform unintended functions, and clause 7.4.7.3 that the results shall be documented. For airborne software, EASA's CM-SWCEH-002 describes low-level testing against low-level requirements with structural coverage analysis, citing Objectives 5, 6 and 7 of DO-178C Annex A Table A-7. Per Perforce, ISO 26262 is derived from IEC 61508 and its Part 6 includes several tables defining the methods that must be considered to achieve compliance.
Where can teams in India, the UAE or Sri Lanka get TESSY?
From GSAS Micro Systems, the authorized Razorcat engineering partner for India, the UAE and Sri Lanka, with local engineering support, INR invoicing and one support channel across Bengaluru, Hyderabad, Chennai, Pune, Mumbai and Delhi NCR. Razorcat's public product pages currently document TESSY 5.1, so ask GSAS to confirm the version scope and availability that applies to your programme.

Stay in the Loop

Get monthly compliance updates, product insights, and engineering best practices delivered to your inbox.

Related Articles

Classification tree and combination table used to design embedded unit test cases in Razorcat's Classification Tree Editor for TESSY, available in India from GSAS Micro Systems
Compliance & Safety Razorcat Automotive & Mobility

Test Case Design with the Classification Tree Method: Deriving Unit Tests You Can Defend in an Audit

Ad-hoc test cases can be perfectly good tests and still fail an audit, because nothing on file records why that particular set was sufficient. The Classification Tree Method derives test cases from the input space instead: identify the test-relevant aspects as classifications, partition each into equivalence classes, then combine leaf classes in a combination table. Razorcat implements CTM in the Classification Tree Editor, available integrated into TESSY or standalone. GSAS Micro Systems is the authorized Razorcat engineering partner for India, the UAE and Sri Lanka.

1 Aug 2026 · 10 min read
Fault injection and robustness testing for safety-related embedded C and C++ software, explained for Indian engineering teams by GSAS Micro Systems, the authorized Razorcat engineering partner
Compliance & Safety Razorcat Automotive & Mobility

Fault Injection and Robustness Testing for Embedded Software: What ISO 26262, IEC 61508 and DO-178C Actually Ask For

Every safety-related unit contains code that correct inputs never execute: range checks, error returns, timeouts, recovery paths. The functional safety standards require that code to be verified, and they are explicit about how. ISO 26262-6 lists fault injection test as a method for both software unit verification and software integration verification; IEC 61508-3 recommends defensive programming from SIL 2 upward and then concedes, in a footnote, that defensive code is exactly what stops teams reaching 100 percent structural coverage. This guide separates robustness testing from fault injection, maps each to the clause that asks for it, and shows how Razorcat implements automated fault injection in TESSY without leaving instrumentation in production code.

1 Aug 2026 · 11 min read
Buyer-side evaluation framework for embedded unit testing tools, covering compiler and debugger fit, on-target execution, coverage levels and qualification evidence, from GSAS Micro Systems in India
Compliance & Safety Razorcat Automotive & Mobility

How to Evaluate a Unit Testing Tool for Embedded Software: A Buyer's Framework for Indian Teams

Unit test tool evaluations rarely fail on features. They fail because the tool cannot drive the compiler and debugger the project is already committed to, or because the evidence it produces sits outside the scope of the certificate the assessor asks for. This is a buyer-side framework: six questions, what a credible answer looks like in vendor documentation, and a four-week pilot that measures the answers instead of accepting them.

1 Aug 2026 · 10 min read