unitTest framework
ctest + manual test(no test suite)
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(recipe-01 LANGUAGES CXX)
# require C++11
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
#require bash and python
find_package(PythonInterp REQUIRED)
find_program(BASH_EXECUTABLE NAMES bash REQUIRED)
# example library
add_library(sum_integers sum_integers.cpp)
# main code
add_executable(sum_up main.cpp)
target_link_libraries(sum_up sum_integers)
# testing binary
add_executable(cpp_test test.cpp)
target_link_libraries(cpp_test sum_integers)
# enable testing functionality
enable_testing()
# define tests
add_test(
NAME bash_test
COMMAND ${BASH_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test.sh $<TARGET_FILE:sum_up>
)
add_test(
NAME cpp_test
COMMAND $<TARGET_FILE:cpp_test>
)
add_test(
NAME python_test_long #sum 1-1000
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test.py --executable $<TARGET_FILE:sum_up>
)
add_test(
NAME python_test_short: #sum 1-100
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test.py --short --executable $<TARGET_FILE:sum_up>
)
$ cmake .
-- The CXX compiler identification is GNU 9.3.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PythonInterp: /usr/bin/python3.8 (found version "3.8.5")
-- Configuring done
-- Generating done
$ make test
Running tests...
Test project /home/jianleya/trainning/cmake/cmake/cmake-cookbook/cmake-cookbook/chapter-04/build
Start 1: bash_test
1/4 Test
Start 2: cpp_test
2/4 Test
Start 3: python_test_long
3/4 Test
Start 4: python_test_short
4/4 Test
100% tests passed, 0 tests failed out of 4
Total Test time (real) = 0.26 sec
ctest + catch2 ut-fw
cmake_minimum_required(VERSION 3.5)
# Set the project name
project (catch2_unit_test)
set(CMAKE_CXX_STANDARD 11)
# add the CMakeFile that defines catch2
add_subdirectory(3rd_party/catch2)
# Add an library for the example classes
add_library(example_unit_test
Reverse.cpp
Palindrome.cpp
)
#############################################
# Unit tests
# enable CTest testing
enable_testing()
# Add a testing executable
add_executable(unit_tests unit_tests.cpp)
target_link_libraries(unit_tests
example_unit_test
Catch2::Test
)
add_test(test_all unit_tests)
# 3rd_party/catch2/CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(catch2)
# Prepare "Catch2" library for other executables
add_library(Catch2 INTERFACE)
add_library(Catch2::Test ALIAS Catch2)
target_include_directories(Catch2 INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
#include
#include "Reverse.h"
#include "Palindrome.h"
#define CATCH_CONFIG_MAIN
#include "catch2/catch.hpp"
TEST_CASE( "simple" )
{
std::string toRev = "Hello";
Reverse rev;
std::string res = rev.reverse(toRev);
REQUIRE( res == "olleH" );
}
TEST_CASE( "empty" )
{
std::string toRev;
Reverse rev;
std::string res = rev.reverse(toRev);
REQUIRE( res == "" );
}
TEST_CASE( "is_palindrome" )
{
std::string pal = "mom";
Palindrome pally;
REQUIRE( pally.isPalindrome(pal) == true );
}
ctest + googletest-fw
# top CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
# Set the project name
project (google_test_example)
add_library(example_google_test
Reverse.cpp
Palindrome.cpp
)
#############################################
# Unit tests
add_subdirectory(3rd_party/google-test)
# enable CTest testing
enable_testing()
# Add a testing executable
add_executable(unit_tests unit_tests.cpp)
target_link_libraries(unit_tests
example_google_test
GTest::GTest
GTest::Main
)
add_test(test_all unit_tests)
#3rd_party/google-test/CMakeLists.txt
# Download and unpack googletest at configure time
# See: http://crascit.com/2015/07/25/cmake-gtest/
configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
# Call CMake to download and Google Test
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()
# Build the downloaded google test
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)
# Prevent installation of GTest with your project
set(INSTALL_GTEST OFF CACHE BOOL "" FORCE)
set(INSTALL_GMOCK OFF 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)
# This is a bit of a hack that can be used to get gtest libraries to build in C++11 if you aren't using CMAKE_CXX_STANDARD
#
#set(CXX11_FEATURES
# cxx_nullptr
# cxx_auto_type
# cxx_delegating_constructors
#)
#target_compile_features(gtest
# PRIVATE
# ${CXX11_FEATURES}
#)
#
#target_compile_features(gmock_main
# PRIVATE
# ${CXX11_FEATURES}
#)
#
#target_compile_features(gmock
# PRIVATE
# ${CXX11_FEATURES}
#)
#
#target_compile_features(gmock_main
# PRIVATE
# ${CXX11_FEATURES}
#)
# Add aliases for GTest and GMock libraries
if(NOT TARGET GTest::GTest)
add_library(GTest::GTest ALIAS gtest)
add_library(GTest::Main ALIAS gtest_main)
endif()
if(NOT TARGET GTest::GMock)
add_library(GMock::GMock ALIAS gmock)
add_library(GMock::Main ALIAS gmock_main)
endif()
ctest + boostut-fw
make_minimum_required(VERSION 3.5)
# Set the project name
project (boost_unit_test)
# find a boost install with the libraries unit_test_framework
find_package(Boost 1.46.1 REQUIRED COMPONENTS unit_test_framework)
# Add an library for the example classes
add_library(example_boost_unit_test
Reverse.cpp
Palindrome.cpp
)
target_include_directories(example_boost_unit_test
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)
target_link_libraries(example_boost_unit_test
PUBLIC
Boost::boost
)
#############################################
# Unit tests
# enable CTest testing
enable_testing()
# Add a testing executable
add_executable(unit_tests unit_tests.cpp)
target_link_libraries(unit_tests
example_boost_unit_test
Boost::unit_test_framework
)
target_compile_definitions(unit_tests
PRIVATE
BOOST_TEST_DYN_LINK
)
add_test(test_all unit_tests)
unitTest Tips
time cost up
# set minimum cmake version
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
# project name
project(recipe-07 LANGUAGES NONE)
# detect python
find_package(PythonInterp REQUIRED)
# define tests
enable_testing()
# we expect this test to run for 2 seconds
add_test(example ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test.py)
# timeout for this test set to 10 seconds
set_tests_properties(example PROPERTIES TIMEOUT 10)
expect test failure
# set minimum cmake version
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
# project name
project(recipe-06 LANGUAGES NONE)
# detect python
find_package(PythonInterp REQUIRED)
# define tests
enable_testing()
add_test(example ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test.py)
# we expect this test to fail
set_tests_properties(example PROPERTIES WILL_FAIL true)
# not often used
test sequence
# with cost
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(recipe-08 LANGUAGES NONE)
find_package(PythonInterp REQUIRED)
# define tests
enable_testing()
add_test(a ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/a.py)
add_test(b ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/b.py)
add_test(c ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/c.py)
add_test(d ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/d.py)
set_tests_properties(a b c d PROPERTIES COST 0.5)
add_test(e ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/e.py)
add_test(f ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/f.py)
add_test(g ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/g.py)
set_tests_properties(e f g PROPERTIES COST 1.5)
add_test(h ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/h.py)
set_tests_properties(h PROPERTIES COST 2.5)
add_test(i ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/i.py)
set_tests_properties(i PROPERTIES COST 3.5)
add_test(j ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/j.py)
set_tests_properties(j PROPERTIES COST 4.5)
$ make test
Running tests...
Test project /home/jianleya/trainning/cmake/cmake/cmake-cookbook/cmake-cookbook/chapter-04/recipe-08/using-cost-example
Start 10: j
1/10 Test #10: j ................................ Passed 4.54 sec
Start 9: i
2/10 Test #9: i ................................ Passed 3.55 sec
Start 8: h
3/10 Test #8: h ................................ Passed 2.53 sec
Start 5: e
4/10 Test #5: e ................................ Passed 1.54 sec
Start 6: f
5/10 Test #6: f ................................ Passed 1.53 sec
Start 7: g
6/10 Test #7: g ................................ Passed 1.53 sec
Start 1: a
7/10 Test #1: a ................................ Passed 0.53 sec
Start 2: b
8/10 Test #2: b ................................ Passed 0.54 sec
Start 3: c
9/10 Test #3: c ................................ Passed 0.54 sec
Start 4: d
10/10 Test #4: d ................................ Passed 0.55 sec
100% tests passed, 0 tests failed out of 10
Total Test time (real) = 17.39 sec
# without cost
# set minimum cmake version
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
# project name
project(recipe-08 LANGUAGES NONE)
# detect python
find_package(PythonInterp REQUIRED)
# define tests
enable_testing()
add_test(a ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/a.py)
add_test(b ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/b.py)
add_test(c ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/c.py)
add_test(d ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/d.py)
add_test(e ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/e.py)
add_test(f ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/f.py)
add_test(g ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/g.py)
add_test(h ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/h.py)
add_test(i ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/i.py)
add_test(j ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/j.py)
$ make test
Running tests...
Test project /home/jianleya/trainning/cmake/cmake/cmake-cookbook/cmake-cookbook/chapter-04/recipe-08/without-cost-example
Start 1: a
1/10 Test #1: a ................................ Passed 0.54 sec
Start 2: b
2/10 Test #2: b ................................ Passed 0.53 sec
Start 3: c
3/10 Test #3: c ................................ Passed 0.53 sec
Start 4: d
4/10 Test #4: d ................................ Passed 0.52 sec
Start 5: e
5/10 Test #5: e ................................ Passed 1.53 sec
Start 6: f
6/10 Test #6: f ................................ Passed 1.63 sec
Start 7: g
7/10 Test #7: g ................................ Passed 1.53 sec
Start 8: h
8/10 Test #8: h ................................ Passed 2.53 sec
Start 9: i
9/10 Test #9: i ................................ Passed 3.53 sec
Start 10: j
10/10 Test #10: j ................................ Passed 4.54 sec
100% tests passed, 0 tests failed out of 10
Total Test time (real) = 17.43 sec
test summary (Label)
# set minimum cmake version
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
# project name
project(recipe-09 LANGUAGES NONE)
# detect python
find_package(PythonInterp REQUIRED)
# define tests
enable_testing()
add_test(
NAME feature-a
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/feature-a.py
)
add_test(
NAME feature-b
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/feature-b.py
)
add_test(
NAME feature-c
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/feature-c.py
)
add_test(
NAME feature-d
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/feature-d.py
)
add_test(
NAME benchmark-a
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/benchmark-a.py
)
add_test(
NAME benchmark-b
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/benchmark-b.py
)
set_tests_properties(
feature-a
feature-b
feature-c
PROPERTIES
LABELS "quick"
)
set_tests_properties(
feature-d
benchmark-a
benchmark-b
PROPERTIES
LABELS "long"
)
$ make test
Running tests...
Test project /home/jianleya/trainning/cmake/cmake/cmake-cookbook/cmake-cookbook/chapter-04/recipe-09/example
Start 1: feature-a
1/6 Test #1: feature-a ........................ Passed 0.13 sec
Start 2: feature-b
2/6 Test #2: feature-b ........................ Passed 0.13 sec
Start 3: feature-c
3/6 Test #3: feature-c ........................ Passed 0.21 sec
Start 4: feature-d
4/6 Test #4: feature-d ........................ Passed 0.55 sec
Start 5: benchmark-a
5/6 Test #5: benchmark-a ...................... Passed 0.54 sec
Start 6: benchmark-b
6/6 Test #6: benchmark-b ...................... Passed 0.56 sec
100% tests passed, 0 tests failed out of 6
Label Time Summary:
long = 1.66 sec*proc (3 tests)
quick = 0.47 sec*proc (3 tests)
Total Test time (real) = 2.14 sec