CMake: struktura projektu z testami jednostkowymi

Próbuję uporządkować swój projekt tak, aby zawierał źródła produkcji (w podfolderze src) i testy (w podfolderze test). Używam CMake do zbudowania tego. Jako minimalny przykład mam następujące pliki:

Cmakeliści.txt:

cmake_minimum_required (VERSION 2.8) 
project (TEST) 

add_subdirectory (src) 
add_subdirectory (test) 

Src / Cmakelisty.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, nie do końca Materia

Test / Cmakelisty.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 strukturyzacji tego kodu? Nie jest to jednak żaden problem, ponieważ nie jest to możliwe.]}
  1. nie podoba mi się to, że muszę wypisać wszystkie pliki z folderu src w pliku test/CMakeLists.txt. Gdyby to był projekt biblioteczny, po prostu połączyłbym bibliotekę. Czy istnieje sposób, aby uniknąć wymieniania wszystkich pliki cpp z innego projektu?
  2. co robią linie enable_testing() i add_test(MyTest test)? Nie widzę żadnego efektu. Jak mogę uruchomić testy z CMake (lub CTest)?
  3. do tej pory pobiegłem cmake . w folderze głównym, ale to spowodowało bałagan z plikami tymczasowymi wszędzie. Jak Mogę uzyskać wyniki kompilacji w rozsądnej strukturze?
Author: GhostGambler, 2013-01-22

2 answers

W przypadku pytań 1 i 2, polecam stworzenie biblioteki z plików nie testowych z wyłączeniem main.cpp (w tym przypadku tylko src/SQR.cpp i src/SQR.h), a następnie można uniknąć dwukrotnego wypisywania (i co ważniejsze ponownej kompilacji) wszystkich źródeł.

Dla pytania 3, te polecenia dodają test o nazwie "MyTest", który wywołuje Twój plik wykonywalny "test" bez żadnych argumentów. Jednak, ponieważ dodałeś te polecenia do test/CMakeLists.txt, a nie twoje topowe Cmakelisty.txt, można wywoływać tylko test z podkatalogu "test" w drzewie kompilacji (try cd test && ctest -N). Jeśli chcesz, aby test był uruchamiany z katalogu najwyższego poziomu, musisz wywołać add_test z najwyższego poziomu CMakeLists.txt. Oznacza to również, że musisz użyć bardziej wyrazistej formy add_test ponieważ twój test exe nie jest zdefiniowany w tych samych Cmakelistach.txt

W Twoim przypadku, ponieważ używasz cmake w folderze głównym, twoje drzewo kompilacji i drzewo źródłowe są jednym i tym samym. Jest to znane jako in-source build i nie jest idealny, co prowadzi do pytania 4.

Preferowaną metodą generowania drzewa kompilacji jest wykonanie kompilacji poza źródłem, tzn. utworzenie katalogu gdzieś poza drzewem źródłowym i stamtąd wykonanie cmake. Nawet utworzenie katalogu" build " w katalogu głównym projektu i wykonanie cmake .. zapewniłoby czystą strukturę, która nie będzie kolidować z Twoim drzewem źródłowym.

Ostatnim punktem jest uniknięcie wywoływania plików wykonywalnych "test" (rozróżnianie wielkości liter). Na powody dlaczego, zobacz ta odpowiedź .

Aby osiągnąć te zmiany, wykonałbym następujące czynności:

Cmakeliści.txt:

cmake_minimum_required (VERSION 2.8)
project (TEST)
add_subdirectory (src) 
add_subdirectory (test)
enable_testing ()
add_test (NAME MyTest COMMAND Test)


src / Cmakeliści.txt:

add_library (Sqr sqr.cpp sqr.h)
add_executable (demo main.cpp)
target_link_libraries (demo Sqr)


test / Cmakelisty.txt:

find_package (Boost COMPONENTS system filesystem unit_test_framework REQUIRED)
include_directories (${TEST_SOURCE_DIR}/src
                     ${Boost_INCLUDE_DIRS}
                     )
add_definitions (-DBOOST_TEST_DYN_LINK)
add_executable (Test test.cpp)
target_link_libraries (Test
                       Sqr
                       ${Boost_FILESYSTEM_LIBRARY}
                       ${Boost_SYSTEM_LIBRARY}
                       ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
                       )
 93
Author: Fraser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:26

Podoba mi się przykład @Fraser, ale użyłbym polecenia add_test w teście/CMakeLists.txt i użyj enable_testing przed add_subdirectory (test).

W ten sposób możesz uruchamiać swoje testy z katalogu kompilacji najwyższego poziomu, określając swoje testy w test/CMakeLists.txt.

Wynik wyglądałby tak (użyłem ponownie przykładu @Fraser):

Cmakeliści.txt

cmake_minimum_required (VERSION 2.8)
project (TEST)
add_subdirectory (src)

enable_testing ()
add_subdirectory (test)

Src / Cmakelisty.txt

add_library (Sqr sqr.cpp sqr.h)
add_executable (demo main.cpp)
target_link_libraries (demo Sqr)

Test / Cmakelisty.txt

find_package (Boost COMPONENTS system filesystem unit_test_framework REQUIRED)
include_directories (${TEST_SOURCE_DIR}/src
                     ${Boost_INCLUDE_DIRS}
                     )
add_definitions (-DBOOST_TEST_DYN_LINK)
add_executable (Test test.cpp)
target_link_libraries (Test
                       Sqr
                       ${Boost_FILESYSTEM_LIBRARY}
                       ${Boost_SYSTEM_LIBRARY}
                       ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
                       )
add_test (NAME MyTest COMMAND Test)
 35
Author: Mathias,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-09 02:45:16