Nur weil es kompiliert bedeutet nicht, dass es läuft! Das ist die Essenz von Komponententests. Probieren Sie den Code aus.Stellen Sie sicher, dass es tut, was Sie dachten.
Lässt es sich, wenn Sie eine Matrix-Transformation von Matlab bringen, ist es leicht, ein Plus-oder Minuszeichen irgendwo zu vermasseln. So etwas ist schwer zu sehen. Ohne es auszuprobieren, wissen Sie einfach nicht, ob es richtig funktioniert. Das Debuggen von 100 Codezeilen ist viel einfacher als das Debuggen von 100.000 Codezeilen.
Einige Leute nehmen dies zu Extremen. Sie versuchen alles mögliche zu testen. Testen wird zum Selbstzweck.
Dies kann später während der Wartungsphasen nützlich sein. Sie können schnell überprüfen, ob Ihre Updates nichts beschädigt haben.
Aber der Overhead kann die Produktentwicklung behindern! Und zukünftige Änderungen, die die Funktionalität ändern, können einen umfangreichen Test-Update-Overhead erforderlich machen.
Letztes Ende (Es kann auch in Bezug auf Multi-Threading und willkürliche Ausführungsreihenfolge. Chaotisch), sofern nichts anderes angegeben, meine Tests versuchen, den Mittelweg zu schlagen.
Ich versuche, größere Granularitäten zu testen, um grundlegende grundlegende Funktionen zu überprüfen. Ich sorge mich nicht so sehr um jedes mögliche Szenario eines Zaunpfostens. (Das ist, was ASSERT-Makros sind.)
Zum Beispiel: Als ich Code zum Senden/Empfangen von Nachrichten über UDP schrieb, warf ich einen schnellen Test zum Senden/Empfangen von Daten mit dieser Klasse über die Loopback-Schnittstelle. Nichts Außergewöhnliches. Schnell, schnell, & schmutziger Code. Ich wollte es einfach ausprobieren. Um sicherzustellen, dass es tatsächlich funktionierte, bevor ich etwas aufbaute.
Ein anderes Beispiel: Einlesen von Kamerabildern von einer Firewirekamera. Ich warf eine schnelle & dreckige GTK-App zusammen, um die Bilder zu lesen, zu verarbeiten und in Echtzeit anzuzeigen. Andere Leute nennen das Integrationstests. Aber ich kann damit meine Firewire-Schnittstelle, meine Image-Klasse, meine Bayer RGGB-> RGB-Transformation, meine Bildausrichtung & Ausrichtung überprüfen, auch wenn die Kamera wieder kopfüber montiert wurde. Detailliertere Tests wären nur dann gerechtfertigt gewesen, wenn sich dies als unzureichend erwiesen hätte.
Auf der anderen Seite, auch für etwas so einfach wie:
template<class TYPE> inline TYPE MIN(const TYPE & x, const TYPE & y) { return x > y ? y : x; }
template<class TYPE> inline TYPE MAX(const TYPE & x, const TYPE & y) { return x < y ? y : x; }
ich eine 1 Zeile SHOW Makro, um sicherzustellen, schrieb ich hatte nicht das Zeichen verkorkst:
SHOW(MIN(3,4)); SHOW(MAX(3,4));
All Ich wollte überprüfen, ob es im allgemeinen Fall das tut, was es tun soll. Ich sorge mich weniger darum, wie es mit NaN/+ -Infinity/(double, int) umgeht, als ob einer der Kollegen sich dafür entschieden hat, die Reihenfolge der Argumente zu ändern und zu scheitern.
Werkzeug weise, es gibt eine Menge Unit-Test-Sachen da draußen. Wenn es dir hilft, mehr Kraft für dich. Wenn nicht, müssen Sie nicht wirklich zu extravagant werden.
Ich werde oft ein Testprogramm schreiben, die Daten in und aus einer Klasse-Dumps und druckt sie dann alle mit einem SHOW Makro aus:
#define SHOW(X) std::cout << # X " = " << (X) << std::endl
(Alternativ können viele meiner Klassen Selbst Drucke mit einem eingebauten Operator < < (ostream &) Methode. Es ist eine erstaunlich nützliche Technik für die Fehlersuche sowie zum Testen!)
Makefiles kann trivialerweise automatisch erweitert werden, um die Ausgabedateien von Testprogrammen zu erzeugen, und um automatisch vergleichen (diff) diese Ausgabedateien mit vorher bekannte (überprüfte) Ergebnisse.
Nicht schick, vielleicht etwas weniger als elegant, aber wie Techniken gehen, ist dies sehr effektiv, schnell zu implementieren und sehr geringen Overhead. (Was hat seine Vorteile, wenn Ihr Manager mißbilligt Zeit auf diesem Test Sachen verschwenden.)
Ein letzter Gedanke, den ich Ihnen verlassen werde. Das wird mich abschreiben lassen, also NICHT tun Sie es!
Vor einiger Zeit brauchte ich ein Testprogramm. Es war ein erforderliches Ergebnis. Das Programm selbst musste überprüfen, dass eine andere Klasse ordnungsgemäß funktionierte. Es konnte jedoch nicht auf externe Datendateien zugreifen. (Wir konnten uns nicht darauf verlassen, wo das Programm relativ zu irgendetwas anderem liegen würde. Auch keine absoluten Pfade.) Das Unit-Testing-Framework für das Projekt war nicht kompatibel mit dem Compiler, den ich verwenden musste. Es musste auch in einer Datei sein. Das Makefile-System des Projekts unterstützte das Verknüpfen mehrerer Dateien für ein Testprogramm nicht. (Anwendungsprogramme, sicher. Sie konnten Bibliotheken. Aber nur eine einzige Datei für jedes Testprogramm.)
Also, Gott verzeih mir, ich „brach die Regeln“ ...
<verlegen>
Ich habe Makros verwendet. Wenn ein #define-Makro festgelegt wurde, wurden die Daten in eine zweite .c-Datei als Initialisierer für ein struct-Array geschrieben. Anschließend, als die Software neu kompiliert wurde und die zweite .c-Datei (mit dem struct-Array) # eingeschlossen war und das #define-Makro nicht gesetzt war, wurden die neuen Ergebnisse mit den zuvor gespeicherten Daten verglichen. Ja, ich habe eine .c-Datei eingeschlossen. O die Verlegenheit von allem.
</verlegen >
Aber es kann getan werden ...