Próbuję ustrukturyzować mój projekt, aby uwzględnić źródła produkcji (w src
podfolderze) i testy (w test
podfolderze). Do zbudowania tego używam CMake. Jako minimalny przykład mam następujące pliki:
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 - używa sqr, tak naprawdę nie ma znaczenia
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));
}
Kilka pytań:
- Czy ta struktura ma sens? Jakie są najlepsze praktyki podczas tworzenia struktury tego kodu? (Pochodzę z C # i javy, a tam jest w pewnym sensie łatwiej)
- Nie podoba mi się fakt, że muszę wymieniać wszystkie pliki z
src
folderu wtest/CMakeLists.txt
pliku. Gdyby to był projekt biblioteki, po prostu podlinkowałbym bibliotekę. Czy istnieje sposób, aby uniknąć wyświetlania listy wszystkich plików cpp z innego projektu? - Jakie są linie
enable_testing()
i coadd_test(MyTest test)
robisz? Nie widziałem żadnego efektu. Jak mogę uruchomić testy z CMake (lub CTest)? - Do tej pory po prostu biegałem
cmake .
w folderze głównym, ale spowodowało to bałagan z plikami tymczasowymi wszędzie. Jak uzyskać wyniki kompilacji w rozsądnej strukturze?
c++
unit-testing
boost
cmake
boost-test
Grzenio
źródło
źródło
Odpowiedzi:
W przypadku pytań 1 i 2 zalecałbym utworzenie biblioteki z plików niebędących testami, z wyłączeniem main.cpp (w tym przypadku po prostu src / sqr.cpp i src / sqr.h), a następnie możesz uniknąć wyświetlania listy (i co ważniejsze ponowna kompilacja) wszystkie źródła dwukrotnie.
W przypadku pytania 3 polecenia te dodają test o nazwie „MyTest”, który wywołuje plik wykonywalny „test” bez żadnych argumentów. Jednakże, ponieważ dodałeś te polecenia do test / CMakeLists.txt, a nie do pliku CMakeLists.txt najwyższego poziomu, możesz wywołać test tylko z podkatalogu "test" twojego drzewa kompilacji (try
cd test && ctest -N
). Jeśli chcesz, aby test można było uruchomić z katalogu kompilacji najwyższego poziomu, musisz wywołaćadd_test
z pliku CMakeLists.txt najwyższego poziomu. Oznacza to również, że musisz użyć bardziej szczegółowej formy,add_test
ponieważ twój exe testowy nie jest zdefiniowany w tym samym CMakeLists.txtW twoim przypadku, ponieważ używasz cmake w folderze głównym, drzewo kompilacji i drzewo źródłowe są jednym i tym samym. Jest to znane jako kompilacja w źródle i nie jest idealne, co prowadzi do pytania 4.
Preferowaną metodą generowania drzewa kompilacji jest wykonanie kompilacji poza źródłem, tj. Utworzenie katalogu gdzieś poza drzewem źródłowym i wykonanie polecenia cmake z tego miejsca. Nawet utworzenie katalogu „build” w katalogu głównym projektu i wykonanie
cmake ..
zapewni czystą strukturę, która nie będzie kolidować z drzewem źródłowym.Ostatnim punktem jest uniknięcie wywoływania plików wykonywalnych „test” (z uwzględnieniem wielkości liter). Z powodów dlaczego, zobacz tę odpowiedź .
Aby osiągnąć te zmiany, zrobiłbym następujące rzeczy:
CMakeLists.txt:
src / CMakeLists.txt:
test / CMakeLists.txt:
źródło
project (TEST)
- patrz cmake.org/cmake/help/v3.6/variable/PROJECT-NAME_SOURCE_DIR.htmlPodoba mi się przykład @Fraser, ale użyłbym polecenia add_test w test / CMakeLists.txt i użyłbym enable_testing przed add_subdirectory (test).
W ten sposób możesz uruchamiać testy z katalogu kompilacji najwyższego poziomu, określając testy w pliku test / CMakeLists.txt.
Wynik wyglądałby tak (ponownie użyłem przykładu @Fraser):
CMakeLists.txt
src / CMakeLists.txt
test / CMakeLists.txt
źródło
ctest -N
dopóki nie otrzymałeś porady dotyczącej włączenia testowania przed dodaniem podkatalogu.