2016-04-29 9 views
0

Derzeit habe ich eine Menge Unit-Tests für mein C++ - Projekt, aber ich teste (noch) nicht die Code-Abdeckung. Ich kompiliere die Tests mit -O3 Optimierungsflagge, um mögliche subtile Fehler zu entlarven, aber es scheint, wenn ich Abdeckungsinformationen mit Werkzeugen wie gcov sammeln möchte, muss jedes Optimierungsflag deaktiviert werden. Sollte ich die Tests zweimal bauen (eins mit -O3, das andere ohne)? Wie wird dieses Problem normalerweise behandelt?Code-Coverage mit Optimierung

+0

'Wie wird dieses Problem normalerweise behandelt?' Ich kompiliere Tests mit '-O0'. Um potentielle Fehler zu finden, ist es besser, Profiler wie Valgrind (oder einige "sanitize" -Flags des gcc) zu benutzen. '-O3' ist für Performance-Benchmarks geeignet. – Gluttton

+0

@Gluttton Ja, ich verwende Valgrind, um meine Tests durchzuführen. Ist '-O0 'genau so wie keine Optimierungsflags? Da es die Standardoption ist. –

+0

'Ist -O0 genau so wie keine Optimierungsflags?' Yep. – Gluttton

Antwort

1

Es gibt typischerweise viele Arten von Tests, die durchgeführt werden, um die Qualität der Software sicherzustellen, und verschiedene Kriterien für die Compileroptionen.

Typischerweise bietet ein Build-System zwei oder mehr Möglichkeiten der Builds, zum Beispiel:

Debug: -O0 (keine Optimierung) mit behauptet

Veröffentlichung: "höhere Optimierung" (- O2, -Os oder -O3 hängt davon ab, was für Ihr Projekt "am besten" ist, ohne dass dies behauptet wird. Dies ist normalerweise der Modus, in dem Sie den Code an Kunden übermitteln.

Manchmal gibt es "Release + Asserts", so dass Sie immer noch die Korrektheit im Code überprüfen können, während Sie mit etwas Leistung laufen.

Hier sind einige Kategorien, die ich denken kann Tests in eingestuft werden:

  1. Funktionale Korrektheit (auch bekannt als "positive Tests"). Hier überprüfen Sie, ob "der Code unter normalen Umständen korrekt funktioniert". Führen Sie sowohl Debug als auch Release aus.

  2. Negative Tests. Überprüfen Sie, ob die Fehlerbedingungen korrekt funktionieren - übergeben Sie die fehlerhaften Werte, die Fehler verursachen sollten ("Datei, die nicht existiert" sollte E_NO_SUCH_FILE ergeben). Typisch sowohl Debug als auch Release.

  3. Stresstests - Ausführen von harschen Tests, die überprüfen, ob sich die Software korrekt verhält, wenn Sie sie lange, mit vielen Threads usw. ausführen. Normalerweise Debug-Modus - möglicherweise beides.

  4. Abdeckung. Führen Sie eine Reihe von Tests durch, um sicherzustellen, dass Sie "alle Pfade abdecken" (oft mit einem Grad "nicht abgedeckt", z. B. 95% der Funktionen und 85% der Zweige), da einige Bedingungen extrem schwierig zu erreichen sind ohne den Code manuell zu instrumentieren - es gibt Fehler, die nur auftreten, wenn der Datenträger vollständig voll ist oder wenn das Betriebssystem keinen neuen Prozess erstellen kann. In der Regel als Debug kompiliert.

  5. Fehlertoleranztests. Eine Form von "negativen Tests", bei denen Sie eine "Mock" -Funktionalität für die Speicherzuordnungen und Ähnliches einfügen, die Fehler sequentiell oder zufällig simuliert, um Fälle zu entdecken, in denen Fehler nicht erkannt werden und der Code als Folge von ein früherer Fehler, anstatt den korrekten Fehler an der richtigen Stelle zu erzeugen. Auch hier läuft es normalerweise mit Debug - aber es lohnt sich auch, es in Release auszuführen.

  6. Leistungsprüfung. Wo messen Sie die Leistung Ihres Programms - Frames pro Sekunde generiert, Zeilen pro Sekunde in einem Compiler oder Gigabyte pro Stunde in einem Datei-Download-System, etc. Dies sollte wie Release kompiliert werden, als laufende Leistung in "nicht optimiert" -Code ist fast immer sinnlos.

Für komplexe Software-Produkte, haben Sie oft zwischen „läuft alles“ zu gefährden und „die Zeit es braucht“ - zum Beispiel Modus ALL 4000 Funktionstests in beide Debug- und Release läuft 12 Stunden dauern kann, laufen nur Debug-Modus dauert 7 Stunden, also vorzuziehen. Dieser Kompromiss ist die übliche "technische Entscheidung" - "In einer idealen Welt würden Sie das tun, aber in der realen Welt müssen wir Kompromisse eingehen, und deshalb denke ich, dass diese Konfiguration von Tests richtig ist".

Viele Testsysteme laufen mit Lichttests bei jeder Änderung des Quellcodes [nach "Ich denke, das funktioniert" vom Ingenieur selbst], schwereren Tests jede Nacht und mehr Tests über ein Wochenende, zum Beispiel. Dies ermöglicht einen Kompromiss zwischen der Zeit, die benötigt wird, um ALLE Tests auszuführen, und der Zeit, die ein Techniker benötigt, um eine kleine Änderung vorzunehmen.