Ich versuche, mein Projekt so zu strukturieren, dass es die Produktionsquellen (im src
Unterordner) und Tests (im test
Unterordner) enthält. Ich benutze CMake, um dies zu erstellen. Als minimales Beispiel habe ich die folgenden Dateien:
CMakeLists.txt:
cmake_minimum_required (VERSION 2.8)
project (TEST)
add_subdirectory (src)
add_subdirectory (test)
src / CMakeLists.txt:
add_executable (demo main.cpp sqr.cpp)
src / sqr.h.
#ifndef SQR_H
#define SQR_H
double sqr(double);
#endif // SQR_H
src / sqr.cpp
#include "sqr.h"
double sqr(double x) { return x*x; }
src / main.cpp - verwendet sqr, spielt keine Rolle
test / CMakeLists.txt:
find_package(Boost COMPONENTS system filesystem unit_test_framework REQUIRED)
include_directories (${TEST_SOURCE_DIR}/src)
ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK)
add_executable (test test.cpp ${TEST_SOURCE_DIR}/src/sqr.cpp)
target_link_libraries(test
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
)
enable_testing()
add_test(MyTest test)
test / test.cpp:
#define BOOST_TEST_MODULE SqrTests
#include <boost/test/unit_test.hpp>
#include "sqr.h"
BOOST_AUTO_TEST_CASE(FailTest)
{
BOOST_CHECK_EQUAL(5, sqr(2));
}
BOOST_AUTO_TEST_CASE(PassTest)
{
BOOST_CHECK_EQUAL(4, sqr(2));
}
Ein paar Fragen:
- Ist diese Struktur sinnvoll? Was sind die Best Practices bei der Strukturierung dieses Codes? (Ich komme aus C # und Java, und dort ist es in gewissem Sinne einfacher)
- Mir gefällt nicht, dass ich alle Dateien aus dem
src
Ordner in dertest/CMakeLists.txt
Datei auflisten muss. Wenn dies ein Bibliotheksprojekt wäre, würde ich einfach die Bibliothek verknüpfen. Gibt es eine Möglichkeit zu vermeiden, dass alle CPP-Dateien aus dem anderen Projekt aufgelistet werden? - Was sind die Zeilen
enable_testing()
undadd_test(MyTest test)
tun? Ich habe keinen Effekt gesehen. Wie kann ich die Tests von CMake (oder CTest) ausführen? - Bisher bin ich nur
cmake .
im Stammordner gelaufen , aber dies hat überall zu einem Durcheinander mit temporären Dateien geführt. Wie kann ich die Kompilierungsergebnisse in einer vernünftigen Struktur erhalten?
c++
unit-testing
boost
cmake
boost-test
Grzenio
quelle
quelle
Antworten:
Bei den Fragen 1 und 2 würde ich empfehlen, eine Bibliothek aus Ihren Nicht-Testdateien ohne main.cpp (in diesem Fall nur src / sqr.cpp und src / sqr.h) zu erstellen. Dann können Sie eine Auflistung vermeiden (und was noch wichtiger ist) alle Quellen zweimal neu kompilieren.
Für Frage 3 fügen diese Befehle einen Test namens "MyTest" hinzu, der Ihren ausführbaren "Test" ohne Argumente aufruft. Da Sie diese Befehle jedoch zu test / CMakeLists.txt und nicht zu CMakeLists.txt der obersten Ebene hinzugefügt haben, können Sie den Test nur aus dem Unterverzeichnis "test" Ihres Build-Baums aufrufen (try
cd test && ctest -N
). Wenn Sie möchten, dass der Test in Ihrem Build-Verzeichnisadd_test
der obersten Ebene ausgeführt werden kann, müssen Sie ihn über die CMakeLists.txt der obersten Ebene aufrufen. Dies bedeutet auch, dass Sie die ausführlichere Form von verwenden müssen,add_test
da Ihre Test-Exe nicht in derselben CMakeLists.txt definiert istIn Ihrem Fall sind Ihr Build-Baum und Ihr Quellbaum ein und dasselbe, da Sie cmake im Stammordner ausführen. Dies ist als In-Source-Build bekannt und nicht ideal, was zu Frage 4 führt.
Die bevorzugte Methode zum Generieren des Build-Baums besteht darin, einen Build außerhalb des Quellbaums durchzuführen, dh ein Verzeichnis außerhalb Ihres Quellbaums zu erstellen und cmake von dort aus auszuführen. Selbst wenn Sie ein "Build" -Verzeichnis im Stammverzeichnis Ihres Projekts erstellen und ausführen
cmake ..
, erhalten Sie eine saubere Struktur, die Ihren Quellbaum nicht beeinträchtigt.Ein letzter Punkt ist, zu vermeiden, dass ausführbare Dateien "test" genannt werden (Groß- und Kleinschreibung beachten). Gründe dafür finden Sie in dieser Antwort .
Um diese Änderungen zu erreichen, würde ich Folgendes tun:
CMakeLists.txt:
src / CMakeLists.txt:
test / CMakeLists.txt:
quelle
project (TEST)
- siehe cmake.org/cmake/help/v3.6/variable/PROJECT-NAME_SOURCE_DIR.htmlIch mag das Beispiel von @Fraser, würde aber den Befehl add_test in der Datei test / CMakeLists.txt verwenden und enable_testing vor add_subdirectory (test) verwenden.
Auf diese Weise können Sie Ihre Tests aus dem Build-Verzeichnis der obersten Ebene ausführen, während Sie Ihre Tests in der Datei test / CMakeLists.txt angeben.
Das Ergebnis würde so aussehen (ich habe das Beispiel von @Fraser wiederverwendet):
CMakeLists.txt
src / CMakeLists.txt
test / CMakeLists.txt
quelle
ctest -N
angezeigt, bis Sie den Tipp zum Aktivieren von Tests vor dem Hinzufügen des Unterverzeichnisses erhalten haben.