In the fast-evolving world of automotive software, the pressure to deliver high-quality and safety-compliant code under tight timelines is greater than ever. This has led to a growing shift toward Shift-Left testing, where developers take on more testing responsibilities early in the development cycle, inspired by methodologies used in IT development.
Unlike IT software, automotive development presents unique challenges. Developers must manage well-architected code, performance, memory safety, and compliance to automotive standards, leaving little room for inefficient testing workflows. While Test-Driven Development (TDD) offers clear benefits, like early bug detection and improved quality, it only works if testing tools are easy to adopt and seamlessly integrated into the developer’s environment.
In this blog, we’ll explore the specific testing challenges C/C++ developers face and how IDE-integrated test solutions can make unit testing more efficient, reliable, and automotive-ready.
The Reality of Testing C/C++ Code
Testing C and C++ code is rarely as seamless as it is in higher-level languages, excluding Model-Based Design (MBD), which offers an even more streamlined testing experience. One of the first hurdles developers face is the lack of built-in unit testing frameworks. Unlike Python, Java, or JavaScript, which come with integrated libraries that support unit testing out of the box, C and C++ require additional setup. Moreover, these modern languages benefit from features like reflection and introspection, which allow test discovery with minimal effort.
In contrast, setting up a test environment in C or C++ often means pulling in external frameworks. For stubbing and mocking, developers typically rely on tools like CMock or FakeIt, which are powerful but not trivial to configure. The same applies to measuring code coverage or analyzing runtime errors. Each of these tasks requires separate tools and careful integration.
Despite these challenges, the testing landscape in C and C++ has improved. Frameworks like Google Test and Catch2 have made the experience more developer-friendly, reducing the gap between C/C++ and higher-level languages. However, even these modern tools don’t cover everything. They still need to be combined with additional solutions for managing test cases, tracking coverage, and analyzing runtime behavior.
In the end, setting up a robust unit testing environment for C or C++ embedded projects takes effort. It requires careful evaluation and selection of the right frameworks, followed by expert configuration. Once the setup is complete, it must be rolled out to development teams along with clear guidelines to ensure consistency and maintainability across the project.
The specificities of Automotive Software
Testing automotive software isn’t just about checking if the code runs. It’s about making sure the system behaves as intended and safely, performs reliably, and complies with strict industry standards. That’s what makes it fundamentally different from general-purpose software testing.
Automotive software is typically modular, with components interacting through signals or service interfaces. This architecture introduces a layer of complexity in testing. It’s not enough to call functions and check outputs. You often need to generate time-series signals, simulate communication patterns, and define sophisticated pass/fail criteria. Doing this manually is not only time-consuming but also error prone.
Then there’s the safety aspect. A runtime error in automotive software can have serious consequences. That’s why robustness testing is essential. Developers need to check for issues like division by zero, array bounds violations, downcast, and other runtime faults. Techniques like boundary value analysis and equivalence class testing are key to uncovering these edge cases.
On top of that, compliance with standards like AUTOSAR and ISO 26262 adds another layer of requirements. AUTOSAR demands hardware abstraction, which means unit tests must simulate or stub RTE interfaces. ISO 26262 goes even further, requiring rigorous testing practices such as requirements-based testing, interface testing, MC/DC coverage, and full traceability from requirements to test results.
Documentation isn’t optional. It’s a core part of the process, especially for audits and safety assessments.
Modern automotive testing also leverages advanced techniques to improve efficiency and coverage. Automatic test generation, whether driven by requirements or coverage goals helps reduce manual effort. Dead code analysis ensures that every line of code has a purpose. Formal specification and formal verification are increasingly used to explore edge cases and mathematically prove correctness in safety critical components.
In short, testing automotive software is a multi-dimensional challenge. It requires more than just a test framework. It demands a strategy, the right tools, and a deep understanding of the system-under-test.
Integrating automotive test solutions seamlessly into the developer workflow
As discussed earlier, open-source tools are built with general-purpose software in mind. They don’t account for the specific needs of automotive systems, especially the ones we’ve outlined above. To meet these requirements, many projects end up combining their unit test environments with automotive-ready testing solutions. But the real question is: how can teams get the best of both worlds?
Visual Studio Code has become a favorite IDE among embedded software developers, and for good reason. It’s lightweight, highly customizable, and backed by a rich ecosystem of extensions, including from the automotive community. With tools like Intellisense, Git integration, CMake Tools, Google Test, and GDB debugging, developers can build and test embedded applications efficiently, all within a familiar and flexible environment. This makes VS Code a highly recommended environment for embedded C/C++ development and testing.
When it comes to unit testing, automotive teams often choose GoogleTest. It’s well-documented, widely adopted, and provides the essentials: test suites, assertions, and fixtures. But while it’s a solid starting point, it doesn’t cover the full range of needs in automotive software testing. It lacks native support for AUTOSAR RTE interfaces, doesn’t offer test management or requirements traceability, and doesn’t provide advanced coverage metrics like MC/DC. There’s also no built-in support for automated test case generation or architectural awareness, which limits its scalability in safety-critical projects.
This is where BTC EmbeddedTester comes in. Integrated directly into VS Code, or possibly in any other IDE, it brings a set of automotive-grade testing capabilities right to the developer’s desktop. It supports automatic stub code generation, including AUTOSAR RTE interfaces, and allows developers to link test cases directly to system and software requirements. These links are not static, they include update mechanisms that highlight changes in requirements, helping developers quickly adapt their tests. The integration also supports pushing test results back into the requirements management system, closing the loop between development and verification.
On the coverage side, BTC EmbeddedTester provides detailed analysis, including statement, branch, and MC/DC metrics, essential for safety certification. It also supports automatic test case generation, which helps reduce manual effort and improve test completeness. If a line of code isn’t covered, the tool can analyze whether it’s dead code or if a test case can be generated to reach it.
BTC EmbeddedTester supports two complementary testing approaches within VS Code.
- Developers can follow a “test-as-code” workflow, writing tests manually and enhancing them with BTC’s features. For example, teams using GoogleTest can integrate their test suites with BTC EmbeddedTester to achieve automotive-ready testing without changing their workflow.
- Alternatively, the tool can provide “architecture-aware” testing based on a structural view of the software architecture, enabling more intelligent testing strategies. This includes working with time-series signals, performing interface-level testing, applying boundary value analysis, using test oracles, and even applying formal verification techniques.
Together, these capabilities transform Visual Studio Code from a general-purpose development environment into a powerful platform for developing and validating both non-safety and safety-critical automotive software. Moreover, they enable a harmonized testing workflow across teams, without the need for complex deployment setups or extensive configuration guidelines. For more details, check out the overview of the latest BTC EmbeddedTester extension for VS Code.
Conclusion
“Shifting left” with unit testing in automotive software development is a necessity. As developers take on more responsibility for testing, integrating automotive-ready solutions directly into their IDE becomes essential. While open-source tools like GoogleTest offer a solid foundation, they aren’t equipped to handle the full spectrum of automotive requirements, especially in safety-critical contexts.
BTC EmbeddedTester addresses these gaps by bringing advanced testing capabilities, such as AUTOSAR RTE support, requirements traceability, MC/DC coverage, and automated test generation, right into the developer’s workflow. Whether through a test-as-code approach or architecture-aware testing, developers can now validate both non-safety and safety-critical software efficiently and reliably within environments like Visual Studio Code.
This integration not only improves test coverage and quality but also aligns development practices with industry standards like ISO 26262, helping teams to deliver robust, compliant automotive software faster and with greater confidence.
👉 Get in touch with our team to discuss how we can support your Developer Testing activities straight from your coding IDE.