Estou tentando estruturar meu projeto para incluir as fontes de produção (na src
subpasta) e testes (na test
subpasta). Estou usando o CMake para criar isso. Como um exemplo mínimo, tenho os seguintes arquivos:
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 - usa sqr, realmente não importa
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));
}
Algumas questões:
- Essa estrutura faz sentido? Quais são as melhores práticas ao estruturar este código? (Eu estou vindo de c # e java, e aí é mais fácil em um sentido)
- Não gosto do fato de precisar listar todos os arquivos da
src
pasta notest/CMakeLists.txt
arquivo. Se este fosse um projeto de biblioteca, eu apenas vincularia a biblioteca. Existe uma maneira de evitar listar todos os arquivos cpp do outro projeto? - Quais são as linhas
enable_testing()
eadd_test(MyTest test)
fazendo? Eu não vi nenhum efeito. Como posso executar os testes do CMake (ou CTest)? - Até agora, eu apenas corri
cmake .
na pasta raiz, mas isso criou uma confusão com arquivos temporários em todos os lugares. Como posso obter os resultados da compilação em uma estrutura razoável?
c++
unit-testing
boost
cmake
boost-test
Grzenio
fonte
fonte
Respostas:
Para as perguntas 1 e 2, eu recomendaria criar uma biblioteca a partir dos arquivos que não são de teste, excluindo main.cpp (neste caso, apenas src / sqr.cpp e src / sqr.h) e, em seguida, evite listar (e mais importante) recompilação) todas as fontes duas vezes.
Para a pergunta 3, esses comandos adicionam um teste chamado "MyTest", que chama seu "teste" executável sem argumentos. No entanto, desde que você adicionou esses comandos ao test / CMakeLists.txt e não ao seu CMakeLists.txt de nível superior, você pode invocar o teste apenas dentro do subdiretório "test" da sua árvore de construção (try
cd test && ctest -N
). Se você deseja que o teste possa ser executado a partir do diretório de compilação de nível superior, é necessário chamar aadd_test
partir do CMakeLists.txt de nível superior. Isso também significa que você precisa usar a forma mais detalhada,add_test
já que o exe de teste não está definido no mesmo arquivo CMakeLists.txtNo seu caso, como você está executando o cmake na pasta raiz, sua árvore de construção e sua árvore de origem são uma e a mesma. Isso é conhecido como uma compilação na fonte e não é o ideal, o que leva à pergunta 4.
O método preferido para gerar a árvore de construção é fazer uma construção fora da fonte, ou seja, criar um diretório em algum lugar fora da árvore de origem e executar cmake a partir daí. Mesmo a criação de um diretório "build" na raiz do seu projeto e a execução
cmake ..
forneceriam uma estrutura limpa que não interferirá na sua árvore de origem.Um ponto final é evitar chamar os executáveis de "teste" (diferencia maiúsculas de minúsculas). Por razões, veja esta resposta .
Para conseguir essas alterações, eu faria o seguinte:
CMakeLists.txt:
src / CMakeLists.txt:
test / CMakeLists.txt:
fonte
project (TEST)
- ver cmake.org/cmake/help/v3.6/variable/PROJECT-NAME_SOURCE_DIR.htmlEu gosto do exemplo do @Fraser, mas usaria o comando add_test no test / CMakeLists.txt e use enable_testing antes do add_subdirectory (test).
Dessa forma, você pode executar seus testes no diretório de compilação de nível superior enquanto especifica seus testes em test / CMakeLists.txt.
O resultado ficaria assim (reutilizei o exemplo do @Fraser):
CMakeLists.txt
src / CMakeLists.txt
test / CMakeLists.txt
fonte
ctest -N
até você receber a dica sobre como ativar o teste antes de adicionar o subdir.