Seien Sie am 30. April dabei: Vorstellung von Parasoft C/C++test CT für kontinuierliche Tests und Compliance-Exzellenz | Registrierung

Warum Stubs in Unit-Tests Integrationstests verbessern

Headshot von Miroslaw Zielinski, Direktor Produktmanagement bei Parasoft
24. April 2023
6 min lesen

Wenn Sie Schwierigkeiten beim Hinzufügen von Stubs zu Ihren Tests hatten, erfahren Sie hier, wie eine spezielle Option für Stubs in Parasoft C/C++test es Ihnen erleichtern kann, automatische Stubs oder Benutzer-Stubs zu generieren.

Ein wichtiger und einflussreicher Kunde von uns, der an einem sicherheitskritischen Projekt arbeitet, das gemäß der Norm IEC 61508 für funktionale Sicherheit entwickelt wird, kontaktierte uns. Sie baten um Anleitung zur Optimierung der Produktivität ihrer Entwickler durch weitere Reduzierung des Rauschens, das durch Unit-Tests entsteht – Rauschen, das durch das Fehlen von Stubbing entsteht.

Wir haben festgestellt, dass die Art und Weise, wie unser Kunde seine Komponententests durchführte, eher dem Integrationstest entsprach. Dabei wurden die zu testenden Units nicht von ihren abhängigen Komponenten (andere Dateien oder Funktionen im Projekt) isoliert, und die Unit-Testfälle wurden gegen die meisten abgeschlossenen Anwendungen ausgeführt.

Ein solcher Ansatz ist kein klassisches Unit-Testing. Dies wird allgemein als Testen der Integrationsebene bezeichnet. Integrationstests sind sehr effizient, um eine gute Testabdeckung für funktionale und nichtfunktionale Anforderungen zu demonstrieren. Es kann auch eine hervorragende Testabdeckung bieten, wenn die strukturelle Codeabdeckung aktiviert ist.

Was sind Stubs beim Testen?

Unit-Test Es geht mehr darum, die Funktion, Methode oder Prozedur zu isolieren, die auch als Einheit bezeichnet wird. Diese Isolierung erfolgt durch Stubbing von Abhängigkeiten und das Erzwingen bestimmter Ausführungspfade.

Stubs treten an die Stelle des Codes in der Einheit, der von Code außerhalb der Einheit abhängig ist. Es bietet dem Entwickler oder Tester auch die Möglichkeit, die Stub-Antwort oder das Ergebnis zu manipulieren, so dass die Einheit auf verschiedene Weise und für verschiedene Zwecke genutzt werden kann, beispielsweise um sicherzustellen, dass die Einheit zuverlässig funktioniert, sicher ist und in einigen Fällen Fälle, ist auch frei von Sicherheitslücken.

Warum werden Stubs verwendet?

Der beste Weg, um zu erklären, warum Stubs verwendet werden und welchen Wert sie bringen, ist, einen Anwendungsfall schrittweise durchzugehen. Sehen Sie sich zum Beispiel den folgenden Code an.

Screenshot des Codes für einen Einheitentestfall, der eine „if“-Anweisung zeigt, die testet, ob der Puffer für Samples erfolgreich zugewiesen wurde

Am Anfang der Funktion steht eine if-Anweisung, die testet, ob der Puffer für Samples erfolgreich allokiert wurde. Die meisten Testfälle für diese Funktion wurden ohne Stubs implementiert, da sie sich auf den regulären Kontrollfluss konzentrieren, mit Ausnahme des Testfalls, der das Verhalten der Funktion überprüft, wenn die Pufferzuweisung fehlschlägt. Dieser Testfall erfordert einen Stub für die allocateSampleBuffer Funktion, um den Fehler zu simulieren.

Sobald der Stub hinzugefügt wurde, wird er konsistent auf den getesteten Code angewendet. Ein Benutzer, der am Testfall „Zuweisungsfehler“ arbeitet, hat eine einfache Möglichkeit, eine spezielle Callback-Funktion in den Stub zu installieren, die den gewünschten Effekt simuliert: Zuweisungsfehler oder nichts tun, da der Stub standardmäßig einen Nullzeiger zurückgibt, was ist für den Testfall erwartet. Aber alle anderen Testfälle erfordern jetzt Aufmerksamkeit, da für sie eine Stub-Konfiguration hinzugefügt werden muss, um unerwünschte Änderungen im Kontrollfluss zu vermeiden.

Natürlich können Entwickler zurückgehen und ihren Testfall neu konfigurieren, um den Stub zu berücksichtigen, aber das bedeutet zusätzlichen Zeitaufwand für die Analyse der Fehlerursache, die Vorbereitung einer dedizierten Callback-Funktion für den Stub und die Beseitigung des Rauschens im Testprozess, der war das Hauptanliegen des Kunden, als er uns kontaktierte.

Verwenden von Stubs in Unit-Testing-C- und C++-Code

Parasoft C / C ++ test macht es viel einfacher, Stubs automatisch zu generieren oder Stubs manuell zu erstellen. Die Option ist an zwei Stellen verfügbar:

Für automatisch generierte Stubs: Testkonfiguration -> Ausführung -> Symbole (Registerkarte)

Screenshot, der das Auswahlfeld für automatisch generierte Stubs in Parasfot C/C++test zeigt, wobei „Stub-Callbacks aktivieren“ und „Aufruf in ursprüngliche Funktion einfügen“ ausgewählt sind.

Für Benutzer-Stubs und Auto-Stubs: Stub-Einstellungsbereich der Stubs-Ansicht

Screenshot von Parasoft C/C++test zeigt Stub-Einstellungen

 

 

 

 

Screenshot, der den Ausgabeort für automatisch generierte Stubs von Parasoft C/c++test zeigt

Wenn die Option „Aufruf der ursprünglichen Funktion einfügen“ aktiviert ist, Parasoft C / C ++ test ändert die Standardmethode, mit der die Stubs generiert werden. Die Änderung erfolgt in einem Stub-Verhalten, wenn kein Rückruf installiert ist. Der mit der neuen Option generierte Stub fungiert als Proxy und ruft die ursprüngliche Funktionsdefinition auf, es sei denn, der Benutzer stellt eine testfallspezifische Rückruffunktion bereit, die alternative Aktivitäten ausführen soll.

Stubs, die ohne die neue Option generiert wurden, einschließlich Legacy-Stubs, versuchen nicht, das ursprüngliche Symbol in der Standardsituation aufzurufen. Wenn keine testfallspezifische Rückruffunktion installiert ist, wird der Stub nichts tun und nur einen Standardwert zurückgeben, wie z. B. einen Nullzeiger oder einen numerischen Nullwert.

Wann man Stubs verwendet

Um sicherzustellen, dass der Unterschied deutlich wird, vergleichen wir die Situation mit aktivierter und nicht aktivierter Option „Aufruf an ursprüngliche Funktion einfügen“ für den Fall, dass der Benutzer keinen dedizierten Rückruf bereitgestellt hat.

Hier ist ein Stub, der für generiert wurde goo Funktion ohne die Option „Aufruf der ursprünglichen Funktion einfügen“. Es funktioniert auf folgende Weise:

Bildschirmaufnahme in Parasoft C/C++test, die einen Stub zeigt, der für die goo-Funktion ohne die Option „Aufruf der ursprünglichen Funktion einfügen“ generiert wurde.

 

 

 

 

 

So sieht es für denselben Stub aus, für den generiert wurde goo Funktion mit die Option „Aufruf der ursprünglichen Funktion einfügen“ aktiviert:

Screenshot von Parasoft C/C++test, der einen für die goo-Funktion generierten Stub zeigt, wobei die Option „Aufruf der ursprünglichen Funktion einfügen“ aktiviert ist.

Wie Sie sehen können, sind Stubs, die mit der neuen Option hinzugefügt wurden, für den getesteten Code transparent. Sie führen einfach den Proxy-Aufruf an die ursprüngliche Definition durch, es sei denn, jemand stellt einen Rückruf bereit, der die gewünschte alternative Aktion implementiert.

Unterschiede zwischen Stubs, Mocks, Spies, Treibern und Dummies

Es gibt verschiedene Testdoubles, die Sie beim Testen von Software auf Unit-Testfälle anwenden können. Beim Echtzeit-Embedded-Testing von C- und C++-Code, wie in diesem Blogbeitrag gezeigt, verwenden Teams Stubs und Mocks als Test-Double-Mechanismen.

Zum Testen von Cloud- und Webanwendungen, die Java, C#, VB.NET oder andere Sprachen verwenden, können Teams viele Arten von Testdoubles anwenden, darunter Stubs, Mocks, Spies, Dummies und Treiber.

  • Stummel sind kleine Codeteile, die beim Testen den Platz einer anderen Komponente einnehmen. Der Vorteil der Verwendung eines Stubs ist, dass es vorgefertigte Ergebnisse und Antworten zurückgibt, was das Schreiben des Tests erleichtert. Sie können Ihre Tests auch dann ausführen, wenn die andere Komponente noch nicht funktioniert.
  • Verspottet sind ein Stück Code mit programmiertem Verhalten, das beim Testen den Platz einer anderen Codekomponente einnimmt. Ein Mock ist ein klügerer Stummel. Mocks werden in gewisser Weise zur Laufzeit bestimmt, da der Code, der die Erwartungen festlegt, ausgeführt werden muss, bevor er irgendetwas tut.
  • Spies, manchmal auch als partielle Mocks bezeichnet, zeichnen Informationen basierend auf ihrem Namen auf. Beispielsweise ein E-Mail-Dienst, der die Anzahl der gesendeten Nachrichten protokolliert.
  • Dummies sind Gegenstände, die herumgereicht, aber nie benutzt werden. Sie helfen beim Ausfüllen obligatorischer Parameter, wie in einem Konstruktor, haben aber keine Auswirkungen auf Ihren Test.
  • Treiber sind komplex in der Implementierung und werden verwendet, wenn die Software mit einem externen System interagieren muss. Sie werden am häufigsten für Integrationstests verwendet.

Was sind Stub-Einschränkungen und -Herausforderungen?

Was passiert in Fällen, in denen keine Originaldefinition für eine Stub-Funktion verfügbar ist? Wie verhält sich der Stub ohne einen Callback, der das alternative Verhalten definiert?

Das Schöne an C/C++test ist, dass es diese Art von Situation automatisch erkennt. Der Stub wird sich während der Bauzeit des Testrahmens neu konfigurieren. Es ruft die ursprüngliche Definition nicht auf, wenn kein Callback installiert ist, und gibt einen sicheren Standardwert zurück.

Stubs beim Integrationstest: Ein Beispiel und Zusammenfassung

C/C++test reduziert die Interferenzen zwischen verschiedenen Teammitgliedern bei der gleichzeitigen Arbeit an den Testfällen bei dieser Art von Semi-Integrationstests erheblich. Ein von Entwickler A hinzugefügter Stub ändert das Verhalten des getesteten Codes für die von Entwickler B hinzugefügten Testfälle nicht.

Wenn Entwickler B entscheidet, dass er eine alternative Aktion für die Stub-Funktion für einen der Testfälle konfigurieren muss, kann er eine testfallspezifische Rückruffunktion erstellen, die die gewünschte alternative Logik für die Stub-Funktion implementiert, und diesen Rückruf in den vorhandenen Stub als installieren Teil der Testfallkonfiguration.

Erfahren Sie, wie Sie Unit-Tests für eingebettete und sicherheitskritische Systeme optimieren.