Modul- und Integrationstests sind entscheidende Komponenten eines übergreifenden Testprozesses für Software. Besonders nützlich sind sie vor allem bei Applikationen, die hundertprozentige Codeabdeckung vor ihrem Feldeinsatz erfordern. Es gibt zahlreiche Werkzeuge, die beim automatischen Erstellen von Test-Frameworks und dem Verwalten von Testfällen helfen. Einer der häufig missverstandenen und vielleicht auch beschönigten Aspekte bei der Auswahl von Testwerkzeugen betrifft die Art und Weise, wie diese Werkzeuge die Syntax des Anwendungscodes analysieren und den Test-Framework aufbauen.
Auch wenn der Kern der Programmiersprachen C und C++ durch ANSI- oder ISO-Standards bestimmt wird, fügen Compiler-Anbieter Spracherweiterungen hinzu, um ihre Compiler für eine bestimmte Architektur zu optimieren. Zwei gängige Spracherweiterungen sind zum Beispiel:
Die Herausforderung für den Parser eines Modultest-Automatisierungswerkzeugs ist es, diese Compiler-spezifischen Erweiterungen beziehungsweise Schlüsselworte zu verstehen und einen dafür geeigneten Testcode zu generieren. Man darf sich allerdings fragen, was in diesem Zusammenhang »geeignet« bedeutet.
Viele Automatisierungswerkzeuge führen lediglich Makros ein, um diese Erweiterungen per »#define« auf null zu setzen:
Mit diesem Vorgehen kann der Toolanbieter eine breite Palette von Compilern unterstützen, ohne seinen Parser für jeden Compiler-Anbieter anpassen zu müssen. Allerdings hat dieses Vorgehen auch gravierende Nachteile: Es verändert den zu testenden Code und erzeugt im Vergleich zu den auf einem realen System laufenden Binärdaten eine völlig andere Binärdatei.
Dies kann dazu führen, dass es im Code nicht-überprüfte Grenzbedingungen (aufgrund von unterschiedlich dimensionierten Typen) gibt oder dass sich schlimmstenfalls wegen der Auslassung eines Schlüsselworts die Bedeutung des Codes komplett verändert. Die folgenden zwei Beispiele verdeutlichen, wie sich derartig eingesetzte Makros auswirken können.