Unit-Tests nicht exportierte Klassen in einer DLL
Entwickeln wir eine C++ - Anwendung mithilfe von Visual Studio 2008 und unit-test mit Boost.Test. Im moment haben wir eine separate Lösung, die enthält unsere unit-tests.
Viele unserer Projekte in die core-Lösung produzieren DLL. Wir sind begrenzte Testabdeckung, weil wir Sie nicht testen, nicht exportierte Klassen.
Ich habe zwei Ideen, wie diese getestet werden konnte:
- Export alles
- Setzen Sie die tests in der DLL (gleiche Projekt und Lösung) und die Verwendung von Boost.Test externe Läufer
Ich bin mir nicht ganz sicher, was die Nachteile sein würde. Nummer 1 oben Pausen von Modul-level-Kapselung, und die Nummer 2 könnte in eine viel größere DLL, es sei denn, es ist möglich, um nur den test-code in bestimmten Konfigurationen.
So, gibt es irgendwelche gravierenden Nachteile zu den oben genannten Methoden, oder können Sie sich andere Lösungen überlegen?
- Ich würde gerne der Hinweis auf CMake bietet eine Funktion namens "Objekt-Bibliotheken". (
add_library( foo_obj OBJECT ... )
) In meinen Projekten Baue ich die Quellen in Objekt-Bibliotheken, die ich dann den link in die DLL (add_library( foo SHARED ... $<TARGET_OBJECTS:foo_obj> )
) und seine test-Treiber (add_executable( foo_test ... $<TARGET_OBJECTS:foo_obj> )
). Es ist eine Variante von den Antworten, die unten mit einem anderen build-system (das ist, warum ich fügte hinzu, diese als Kommentar, keine Antwort), aber es ist die Lösung des gleichen Problems.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Erweiterung auf Tom Quarendon Antwort auf diese Frage, ich habe eine leichte Variante von Simon Steele Antwort:
#include <header/in/source/project.h>
.$(IntDir)
um die Zusätzliche Bibliothek-Verzeichnisse..obj
- Dateien, um die Zusätzlichen Abhängigkeiten.Wieder, der einzige Wartungsaufwand ist der standard für unit-tests zu erstellen, die die Abhängigkeit der Einheit(en), die Sie testen möchten.
$(SolutionDir)\<project_name>t\$(Platform)\$(Configuration)\<object_name>.obj
zwischen Ihnen zu unterscheiden.Die Lösung, die ich für das ist zu bauen, die die gleichen nicht-exportierten code in meine tests-DLL. Diesen nicht zu erhöhen, bauen Zeit und bedeutet alles hinzuzufügen, um beide Projekte, sondern spart auch exportieren alles oder setzen Sie die tests in der Haupt-Produkt-code.
Andere Möglichkeit wäre zum kompilieren des nicht-exportierten code in eine lib, die verwendet wird, die mit DLL-Exporten und der unit-test-Projekt.
War auf der Suche einer Lösung, vielleicht sind die folgenden leichter zu pflegen.
Fügen Sie eine neue build-Konfiguration, z.B. "Unit-testing, Debug", um die DLL-Projekt, und ändern Sie die Konfiguration Typ "Static Library .lib" ("allgemein"->"Konfiguration").
Dann fügen Sie einfach eine Abhängigkeit von Ihrer unit-tests auf dieses Projekt, jetzt sollte alles miteinander verknüpfen, wenn Sie neue build-Konfiguration "Unit-testing, Debug".
Wenn Sie mit release-builds für unit-tests, dann müssen Sie eine andere Konfiguration mit dem release Optimierungen.
So die Vorteile dieser Lösung sind:
Nachteile:
Update:
Wir tatsächlich am Ende mit einem anderen Ansatz.
Wir neue "Test-debug"/"Test-release' - Konfigurationen für jedes vorhandene Projekt, das wir haben.
Für .exe/.dll Projekte, die wir deaktivieren das original main.cpp kompilieren und ersetzt es mit dem, instanziiert der test-Frameworks (z.B. gtest) und führt alle tests, die tests werden in separaten .cpp-Dateien, die ausgeschlossen sind auch aus der Zusammenstellung in der regulären Konfiguration (Release/Debug) und aktiviert nur im-Test-Konfigurationen.
Für .lib-Projekte wir haben auch neue "Test-debug"/"Test-release" - Konfiguration und wir konvertieren Sie die statische Bibliothek ein .exe-Datei und stellen Sie ein main.cpp die instanziiert der Test-Frameworks und führt die tests und die tests selbst. Testen Sie die zugehörigen Dateien werden ausgeschlossen aus der Zusammenstellung auf Release/Debug-Konfigurationen.
Versuchen Sie es mit einer Definition wie der folgenden, die irgendwo alle Dateien enthalten:
Und verwenden Sie es anstelle des dllexport, wie diese:
Dann werden Sie in der Lage sein zu deaktivieren das flag für den Aufbau einer release DLL, aber halten es für eine unit-testbar DLL.