Recentemente, vendi o CMake para compilar meus projetos C ++ e agora gostaria de começar a escrever alguns testes de unidade para o meu código. Decidi usar o utilitário de teste do Google para ajudar com isso, mas preciso de ajuda para começar.
Durante todo o dia, li vários guias e exemplos incluem o Primer , uma introdução na IBM e algumas perguntas sobre SO ( aqui e aqui ), além de outras fontes que perdi de vista. Sei que há muito por aí, mas de alguma forma ainda estou tendo dificuldades.
Atualmente, estou tentando implementar o teste mais básico, para confirmar se compilei / instalei o gtest corretamente e não está funcionando. O único arquivo de origem (testgtest.cpp) é obtido quase exatamente nesta resposta anterior:
#include <iostream>
#include "gtest/gtest.h"
TEST(sample_test_case, sample_test)
{
EXPECT_EQ(1, 1);
}
e meu CMakeLists.txt associado é o seguinte:
cmake_minimum_required(VERSION 2.6)
project(basic_test)
# Setup testing
enable_testing()
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIR})
# Add test cpp file
add_executable(runUnitTests
testgtest.cpp
)
# Link test executable against gtest & gtest_main
target_link_libraries(runUnitTests ${GTEST_LIBRARY_DEBUG} ${GTEST_MAIN_LIBRARY_DEBUG})
add_test(
NAME runUnitTests
COMMAND runUnitTests
)
Observe que eu escolhi vincular o gtest_main em vez de fornecer o principal no final do arquivo cpp, pois acredito que isso me permitirá escalar os testes com mais facilidade para vários arquivos.
Ao criar o arquivo .sln gerado (no Visual C ++ 2010 Express), infelizmente, recebo uma longa lista de erros do formulário
2>msvcprtd.lib(MSVCP100D.dll) : error LNK2005: "public: virtual __thiscall std::basic_iostream<char,struct std::char_traits<char> >::~basic_iostream<char,struct std::char_traits<char> >(void)" (??1?$basic_iostream@DU?$char_traits@D@std@@@std@@UAE@XZ) already defined in gtestd.lib(gtest-all.obj)
o que acho que significa que não estou vinculando com êxito às bibliotecas gtest. Eu verifiquei que, ao vincular as bibliotecas de depuração, tentei criar no modo de depuração.
EDITAR
Depois de pesquisar um pouco mais, acho que meu problema está relacionado ao tipo de biblioteca na qual estou construindo o gtest. Ao criar o gtest com o CMake, seBUILD_SHARED_LIBS
estiver desmarcado, e vinculo meu programa a esses arquivos .lib, obtenho os erros mencionados acima. No entanto, se BUILD_SHARED_LIBS
estiver marcado, produzo um conjunto de arquivos .lib e .dll. Quando agora vincula esses arquivos .lib, o programa é compilado, mas quando executado reclama que não foi possível encontrar o gtest.dll.
Quais são as diferenças entre uma biblioteca SHARED
e uma não SHARED
e, se eu optar por não compartilhar, por que não funciona? Existe uma opção no CMakeLists.txt para o meu projeto que está faltando?
fonte
ExternalProject_Add
vez deadd_subdirectory
. Veja esta resposta para detalhes.enable_testing()
faz?Respostas:
A solução envolveu colocar o diretório de origem gtest como um subdiretório do seu projeto. Eu incluí o CMakeLists.txt que funciona abaixo, se for útil para qualquer pessoa.
fonte
pthread
às bibliotecas vinculadas, alterando o segundo última linha paratarget_link_libraries(runUnitTests gtest gtest_main pthread)
make test
para executar os testes ou executar actest
partir do diretório build. Corractest -V
para ver a saída do teste do google e também actest
saída.Aqui está um exemplo completo de trabalho que acabei de testar. Ele baixa diretamente da web, um tarball fixo ou o diretório mais recente do subversion.
fonte
https://github.com/google/googletest/archive/release-1.8.0.zip
GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG release-1.8.1
, em vez de URLhttps://github.com/google/googletest/archive/release-1.10.0.zip
Você pode obter o melhor dos dois mundos. É possível usar
ExternalProject
para baixar a fonte gtest e depoisadd_subdirectory()
adicioná-la à sua compilação. Isso tem as seguintes vantagens:Utilizado da maneira normal, o ExternalProject não faz o download e a descompactação no momento da configuração (ou seja, quando o CMake é executado), mas você pode fazê-lo com apenas um pouco de trabalho. Eu escrevi um post sobre como fazer isso, que também inclui uma implementação generalizada que funciona para qualquer projeto externo que use o CMake como seu sistema de construção, e não apenas o gtest. Você pode encontra-los aqui:
Atualização: agora, essa abordagem também faz parte da documentação do googletest .
fonte
Provavelmente, a diferença nas opções do compilador entre o binário de teste e a biblioteca de testes do Google é a responsável por esses erros. É por isso que é recomendável trazer o Google Test no formulário de origem e construí-lo junto com seus testes. É muito fácil de fazer no CMake. Você acabou de chamar
ADD_SUBDIRECTORY
com o caminho para a raiz gtest e, em seguida, pode usar os destinos (gtest
egtest_main
) da biblioteca pública definidos lá. Há mais informações básicas neste tópico do CMake no grupo googletestframework.[editar] A
BUILD_SHARED_LIBS
opção só é eficaz no Windows por enquanto. Ele especifica o tipo de bibliotecas que você deseja que o CMake crie. Se você configurá-lo comoON
, o CMake os criará como DLLs em vez de bibliotecas estáticas. Nesse caso, você deve criar seus testes com -DGTEST_LINKED_AS_SHARED_LIBRARY = 1 e copiar os arquivos DLL produzidos pelo CMake para o diretório com o binário de teste (o CMake os coloca em um diretório de saída separado por padrão). A menos que o gtest na biblioteca estática não funcione para você, é mais fácil não definir essa opção.fonte
Isso ocorre porque você precisa adicionar -DGTEST_LINKED_AS_SHARED_LIBRARY = 1 às definições do compilador em seu projeto, se desejar usar o gtest como uma biblioteca compartilhada.
Você também pode usar as bibliotecas estáticas, desde que a tenha compilado com a opção gtest_force_shared_crt para eliminar os erros que você viu.
Gosto da biblioteca, mas adicioná-la ao projeto é uma verdadeira dor. E você não tem chance de fazer o que é certo, a menos que cavar (e invadir) os arquivos gtest cmake. Vergonha. Em particular, não gosto da ideia de adicionar gtest como fonte. :)
fonte
O OP está usando o Windows, e uma maneira muito mais fácil de usar o GTest hoje é com o vcpkg + cmake.
Instale o vcpkg conforme https://github.com/microsoft/vcpkg e verifique se você pode executar a
vcpkg
partir da linha cmd. Anote a pasta de instalação do vcpkg, por exemplo.C:\bin\programs\vcpkg
.Instale o gtest usando
vcpkg install gtest
: isso fará o download, compilará e instalará o GTest.Use um CmakeLists.txt como abaixo: observe que podemos usar destinos vez de incluir pastas.
Execute cmake com: (edite a pasta vcpkg, se necessário, e verifique se o caminho para o arquivo de cadeia de ferramentas vcpkg.cmake está correto)
cmake -B build -DCMAKE_TOOLCHAIN_FILE=C:\bin\programs\vcpkg\scripts\buildsystems\vcpkg.cmake
e construa usando
cmake --build build
como de costume. Observe que o vcpkg também copiará o arquivo gtest (d) .dll / gtest (d) _main.dll necessário da pasta de instalação para as pastas Debug / Release.Teste com
cd build & ctest
.fonte
As suas e as soluções de VladLosevs são provavelmente melhores que as minhas. Se você deseja uma solução de força bruta, no entanto, tente o seguinte:
fonte
O CMakeLists.txt mais simples que eu destilou das respostas neste tópico e algumas tentativas e erros são:
O Gtest já deve estar instalado no seu sistema.
fonte
Assim como uma atualização do comentário de @ Patricia na resposta aceita e do comentário de Fraser para a pergunta original, se você tiver acesso ao CMake 3.11+, poderá usar a função FetchContent do CMake .
A página FetchContent do CMake usa googletest como exemplo!
Forneci uma pequena modificação da resposta aceita:
Você pode usar a
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
propriedade target dos destinos gtest e gtest_main, pois eles são definidos no script CMakeLists.txt do teste do google .fonte
target_include_directories
e usá-loFetchContent_MakeAvailable(googletest)
. Isso preencherá o conteúdo e o adicionará à compilação principal. CMake FetchContent - mais informaçõesDecidi juntar algo genérico rapidamente, demonstrando uma maneira diferente de fazê-lo do que as respostas postadas anteriormente, na esperança de que isso possa ajudar alguém. O seguinte funcionou para mim no meu mac. Primeiramente, executei os comandos de configuração para gtests. Acabei de usar um script que encontrei para configurar tudo.
Em seguida, criei uma estrutura de pastas simples e escrevi algumas aulas rápidas
Criei um CMakeLists.txt de nível superior para a pasta utils e um CMakeLists.txt para a pasta testing
Este é o CMakeLists.txt na pasta testes
Tudo o que resta é escrever uma amostra gtest e gtest main
amostra gtest
amostra gtest principal
Posso então compilar e executar gtests com os seguintes comandos da pasta utils
fonte