CTest can not find tests in simple test setup - c++

I am adding unit tests to my library but ctest always says No tests were found!!!.
In my top level CMakeLists.txt I have the following
option(BUILD_TESTS OFF)
if (${BUILD_TESTS})
enable_testing()
add_subdirectory(tests)
endif()
and int test/CMakeLists.txt
enable_testing()
project(test CXX)
add_executable(${PROJECT_NAME})
add_test(my_test ${PROJECT_NAME})
target_sources(
${PROJECT_NAME}
PRIVATE
test.cpp
)
My test.cpp just has a simple main()
bool test() {
return true;
}
int main(int, char**) {
return test() ? 0 : 1;
}
When I build with cmake --build build/ it even generates a CTestTestfile.cmake file in the build directory.
But when I now run ctest -C Debug I get the No tests were found!!! message.
How can I get this basic test to work?

Related

cmake: build dependency downloaded with ExternalProject_Add before hand

I'm trying to get my test program main.cpp to link against a an externally downloaded library (in this case fmt 8.1.1) via cmake's 'ExternalProject_Add' function as follows
CMakeLists.txt
cmake_minimum_required(VERSION 3.23)
project(test)
set(CMAKE_CXX_STANDARD 20)
include(ExternalProject)
ExternalProject_Add(fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
GIT_TAG 8.1.1
CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=20 -DFMT_TEST=OFF -DFMT_DOC=OFF -DFMT_INSTALL=ON -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/fmt-build
STEP_TARGETS build
)
set(fmt_BINARY_DIR "${CMAKE_BINARY_DIR}/fmt-prefix/src/fmt-build")
set(fmt_SOURCE_DIR "${CMAKE_BINARY_DIR}/fmt-prefix/src/fmt/include")
add_executable(${PROJECT_NAME} main.cpp)
add_dependencies(${PROJECT_NAME} fmt-build) # does not have an effect
target_link_libraries(${PROJECT_NAME} PRIVATE ${fmt_BINARY_DIR}/libfmt.a)
target_include_directories(${PROJECT_NAME} PUBLIC ${fmt_SOURCE_DIR})
main.cpp
#include <chrono>
#include <fmt/core.h>
#include <fmt/chrono.h>
int main() {
const auto now = std::chrono::system_clock::now();
fmt::print("The time is {}", now);
return 0;
}
The test program main.cpp runs OK if I build the target fmt-build before hand, but complains that
ninja: error: 'fmt-prefix/src/fmt-build/libfmt.a', needed by 'test', missing and no known rule to make it
indicating that the dependency fmt-build must be built before hand. While that's doable, how do I get cmake to autmoatically build fmt-build as a dependency for test without haing to run it manually first? I thought the line add_dependencies(${PROJECT_NAME} fmt-build) should take care of that but evidently it does not.
Based on what #Tsyvarev commented, simply adding the line
BUILD_BYPRODUCTS ${CMAKE_BINARY_DIR}/fmt-prefix/src/fmt-build/libfmt.a
to the ExternalProject_Add call does the trick, and one does not have to manually build fmt-build before hand.

No tests found while running gtest

I was making use of gtest to test my c++ project. I followed the steps from here
Everything went well but when I ran the cd build && ctest command i'm getting the output as Test project C:/Users/admin/Desktop/last/build No tests were found!!!
My CMakeLists.txt file
cmake_minimum_required(VERSION 3.14)
project(last)
# GoogleTest requires at least C++11
set(CMAKE_CXX_STANDARD 11)
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
enable_testing()
add_executable(
hello_test
fact.cpp
header.h
main.cpp
testt.cpp
)
target_link_libraries(
hello_test
gtest_main
)
include(GoogleTest)
gtest_discover_tests(hello_test)
I changed a line in my CMakeLists file
add_executable(
hello_test
header.h
main.cpp
)
And added a line
add_test(testt.cpp hello_test)
This gave me the output correctly and ran the tests

Error running google test on default in CLion

So, unfortunatly I am unsure how to properly describe the error message.
Essentially I am trying to get used to google test, - I want to use it to test my C++ project in CLion. I create a new library project, with the following classes:
#include "gtest/gtest.h"
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
and also:
#include "gtest/gtest.h"
TEST(MyTestCategory, Vec2DAdditionTest){
EXPECT_EQ(1, 1);
}
Of course these tests are not useful at all - but its just to see if everything works the way it should.
Now when I tried to run them, I am prompted the following error:
6:46 PM Error running 'MyTestCategory.Vec2DAdditionTest': Cannot run 'MyTestCategory.Vec2DAdditionTest' on '<default>'
6:47 PM Error running 'All in main.cpp': Cannot run 'All in main.cpp' on '<default>'
What am I missing? I can't get the tests to run, - neither individually, nor directly over the main function?
Also after this, the build/run button gets greyed out in CLion and I have to right click on the main.cpp to force it to run/compile..
Essential I have a project structure like so:
src/
a.cpp
b.cpp
CMakeLists.txt
test/
main.cpp
atests.cpp
CmakeLists.txt
CMakeLists.txt
My run configuration for the test project looks like so:
Here is an example on how you can add GTests in your CLion project:
Consider a project structure very similar to what you have presented, however, with an additional file CMakeLists.txt.in in the test folder.:
src/
a.cpp
b.cpp
CMakeLists.txt
test/
main.cpp
atests.cpp
CMakeLists.txt
CMakeLists.txt.in
CMakeLists.txt
The CMakeLists.txt.in helps to download and add the GTest libraries to your project while building your project.
The content of CMakeLists.txt.in looks as below:
cmake_minimum_required(VERSION 2.8.2)
project(googletest-download NONE)
include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG master
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
The test/CMakeLists.txt file looks as below:
cmake_minimum_required(VERSION 3.10)
### START OF CONFIGURING GTEST
configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
# Add googletest directly to our build. This defines
# the gtest and gtest_main targets.
add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src
${CMAKE_CURRENT_BINARY_DIR}/googletest-build
EXCLUDE_FROM_ALL)
### END OF CONFIGURING GTEST
# Now simply link against gtest or gtest_main as needed. Eg
add_executable(test_${PROJECT_NAME} main.cpp atest.cpp)
target_link_libraries(test_${PROJECT_NAME} ${PROJECT_NAME} gtest gtest_main)
add_test(NAME test_PROJECT_NAME COMMAND test_${PROJECT_NAME})
CMakeLists.txt in the root folder has the following content:
cmake_minimum_required(VERSION 3.10)
project(gtestTest)
set(CMAKE_CXX_STANDARD 14)
add_subdirectory(src)
add_subdirectory(test)
Now reload the CMake configuration and try running the test_gtestTest target to run the unit tests.
You can also create custom run configurations using gtest template of CLion to get user friendly test reports.
For more information on GTests with CLion, please refer to:
Google Test Support in Clion
Building Google Tests with CMake

GTest CMake multiple definition of main

I am trying to learn how to use gtest for creating unit testing in c++. I wrote a simple library to test, where I created a factorial function
src/main.cpp
#include <iostream>
int factorial(int n) {
if (n == 1)
return 1;
return n * factorial(n - 1);
}
// Default main function
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
src/main.h
#ifndef GTEST_LEARN_MAIN_H
#define GTEST_LEARN_MAIN_H
int factorial(int n);
#endif //GTEST_LEARN_MAIN_H
src/CMakeLists.txt
add_executable(gtest_learn main.cpp main.h)
add_library(factorial_lib STATIC main.cpp main.h)
Then I created a unit test where I am testing the factorial function
test/main.cpp
#include "main.h"
#include "gtest/gtest.h"
TEST(MyTestSuite,MyTest){
EXPECT_EQ(factorial(4),24);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
I added gtest to my project following the docs on the github page
test/CMakeLists.txt.in
cmake_minimum_required(VERSION 2.8.2)
project(googletest-download NONE)
include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG master
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
test/CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(tests)
# Download and unpack googletest at configure time
configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
if(result)
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
if(result)
message(FATAL_ERROR "Build step for googletest failed: ${result}")
endif()
# Prevent overriding the parent project's compiler/linker
# settings on Windows
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
# Add googletest directly to our build. This defines
# the gtest and gtest_main targets.
add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src
${CMAKE_CURRENT_BINARY_DIR}/googletest-build
EXCLUDE_FROM_ALL)
# The gtest/gtest_main targets carry header search path
# dependencies automatically when using CMake 2.8.11 or
# later. Otherwise we have to add them here ourselves.
if (CMAKE_VERSION VERSION_LESS 2.8.11)
include_directories("${gtest_SOURCE_DIR}/include")
endif()
add_executable(tests main.cpp)
target_link_libraries(tests gtest_main)
target_link_libraries(tests factorial_lib)
add_test(NAME example_test COMMAND tests)
When I am trying to run my test, I get an error saying multiple definition of 'main'. It also says the first definition of main was in test/main.cpp, but before I added the main function in this file, it said that main was first declared in googletest-src/googletest/src/gtest_main.cc, which is the gtest library. For this project I could remove the main from src/main since it serves no purpose, but in a real application that wouldn't be an option. I assume I have to make some CMake config to ignore the gtest main or something like that, but I don't know how. Can anyone help me out? Thanks in advance!
Here is my project-level CMakeLists
cmake_minimum_required(VERSION 3.15)
project(gtest_learn)
set(CMAKE_CXX_STANDARD 14)
include_directories(src)
add_subdirectory(src)
add_subdirectory(test)
You have two main functions declared, what I do is:
#ifndef TESTING
// Default main function
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
#endif
#ifdef TESTING
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
#endif
For test compilation I declare a TESTING macro, which then ensures, that the compiler sees only one main function. For compiling the application, it does not see the test main.

GoogleTest fails to run with 0xc0000135 when building with CMake under "WindowsStore" (UWP)

I'm trying to add gtest to an existing UWP project that is being built by CMake.
The build process seems fine and I'm able to create and build the project using:
cmake ../ -G "Visual Studio 15 2017 Win64" -T v141 -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0.14393.0 -Dgtest_disable_pthreads=ON -DCMAKE_USE_WIN32_THREADS_INIT=ON
However when I run the test I get:
E:\Test-Gtest\build>ctest -C Debug
Test project E:/Test-Gtest/build
Start 1: example_test
1/1 Test #1: example_test .....................Exit code 0xc0000135
***Exception: 0.03 sec
0% tests passed, 1 tests failed out of 1
Total Test time (real) = 0.05 sec
The following tests FAILED:
1 - example_test (Exit code 0xc0000135
)
Errors while running CTest
Trying to run the executable example.exe results in:
VCRUNTIME140D_APP.dll was not found
followed by
MSVCP140D_APP.dll was not found
This is a link to a MCVE on github for convenience which has the following structure (mostly based on the guidelines in the docs):
│ CMakeLists.txt
│
└───src-test
│ CMakeLists.txt
│ CMakeLists.txt.in
│
└───src-integration
basic_logon.cpp
main CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
project(TestGtest CXX C)
set (CMAKE_CXX_STANDARD 14)
enable_testing()
add_subdirectory(src-test)
src-test CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
# Download and unpack googletest at configure time
configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
if(result)
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
if(result)
message(FATAL_ERROR "Build step for googletest failed: ${result}")
endif()
# Prevent overriding the parent project's compiler/linker
# settings on Windows
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
# Add googletest directly to our build. This defines
# the gtest and gtest_main targets.
add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src
${CMAKE_CURRENT_BINARY_DIR}/googletest-build
EXCLUDE_FROM_ALL)
# Now simply link against gtest or gtest_main as needed. Eg
message(STATUS "CMAKE_CURRENT_LIST_DIR: ${CMAKE_CURRENT_LIST_DIR}")
file(GLOB SRC_TEST_INTEGRATION_FILES ${CMAKE_CURRENT_LIST_DIR}/src-integration/*.cpp)
add_executable(example ${SRC_TEST_INTEGRATION_FILES})
target_link_libraries(example gtest_main)
add_test(NAME example_test COMMAND example)
CMakeLists.txt.in
cmake_minimum_required(VERSION 3.12)
project(googletest-download NONE)
include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.8.1
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
basic_logon.cpp
#include "gtest/gtest.h"
#include <cmath>
TEST(Pow, Two)
{
EXPECT_EQ(4, std::pow(2,2));
}