From: Manuel Nickschas Date: Mon, 24 Sep 2018 18:36:21 +0000 (+0200) Subject: test: Add build system support and a main function for unit tests X-Git-Tag: test-travis-01~121 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=8f2ee00f4edef1693628d3af0bdee84d725eb754 test: Add build system support and a main function for unit tests Add a new CMake option BUILD_TESTING (defaults to OFF) that, if enabled, will build unit tests and related requirements. Add a new library Quassel::Test::Main that provides a main function for test cases. Add a new CMake macro quassel_add_test for making the adding of test cases convenient by hiding most of the boilerplate. Test cases should #include "testglobal.h", so they automatically have access to GTest/GMock macros as well as the imported main function. --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 8af98b10..413c46d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -338,7 +338,30 @@ if (NOT WIN32) ) endif() +# Setup unit testing +##################################################################### + +option(BUILD_TESTING "Enable unit tests" OFF) +add_feature_info(BUILD_TESTING BUILD_TESTING "Build unit tests") + +if (BUILD_TESTING) + find_package(GTest QUIET) + set_package_properties(GTest PROPERTIES TYPE REQUIRED + DESCRIPTION "Google's unit testing framework" + PURPOSE "Required for building unit tests" + ) + + find_package(Qt5Test QUIET) + set_package_properties(Qt5Test PROPERTIES TYPE REQUIRED + DESCRIPTION "unit testing library for the Qt5 framework" + PURPOSE "Required for building unit tests" + ) + enable_testing() +endif() + # Check for SSL support in Qt +##################################################################### + cmake_push_check_state(RESET) set(CMAKE_REQUIRED_LIBRARIES Qt5::Core) check_cxx_source_compiles(" diff --git a/cmake/QuasselMacros.cmake b/cmake/QuasselMacros.cmake index 3af589af..62ad20c7 100644 --- a/cmake/QuasselMacros.cmake +++ b/cmake/QuasselMacros.cmake @@ -33,7 +33,7 @@ include(QuasselCompileFeatures) # the alias name. # function(quassel_add_module _module) - set(options EXPORT STATIC) + set(options EXPORT STATIC NOINSTALL) set(oneValueArgs ) set(multiValueArgs ) cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) @@ -66,7 +66,7 @@ function(quassel_add_module _module) VERSION ${QUASSEL_MAJOR}.${QUASSEL_MINOR}.${QUASSEL_PATCH} ) - if (buildmode STREQUAL "SHARED") + if (buildmode STREQUAL "SHARED" AND NOT ${ARG_NOINSTALL}) install(TARGETS ${target} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} @@ -168,6 +168,63 @@ function(quassel_add_resource _name) set(RESOURCE_TARGET ${TARGET} PARENT_SCOPE) endfunction() +################################################################################################### +# Adds a unit test case +# +# quassel_add_test(TestName +# [LIBRARIES lib1 lib2...] +# ) +# +# The test name is given in CamelCase as first and mandatory parameter. The corresponding source file +# is expected the lower-cased test name plus the .cpp extension. +# The test case is automatically linked against Qt5::Test, GMock, Quassel::Common and +# Quassel::Test::Main, which contains the main function. This main function also instantiates a +# QCoreApplication, so the event loop can be used in test cases. +# +# Additional libraries can be given using the LIBRARIES argument. +# +# Test cases should include testglobal.h, which transitively includes the GTest/GMock headers and +# exports the main function. +# +# The compiled test case binary is located in the unit/ directory in the build directory. +# +function(quassel_add_test _target) + set(options ) + set(oneValueArgs ) + set(multiValueArgs LIBRARIES) + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + string(TOLOWER ${_target} lower_target) + set(srcfile ${lower_target}.cpp) + + list(APPEND ARG_LIBRARIES + Qt5::Test + Quassel::Common + Quassel::Test::Main + ) + + if (WIN32) + # On Windows, tests need to be built in the same directory that contains the libraries + set(output_dir "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") + else() + # On other platforms, separate the test cases out + set(output_dir "${CMAKE_BINARY_DIR}/unit") + endif() + + add_executable(${_target} ${srcfile}) + set_target_properties(${_target} PROPERTIES + OUTPUT_NAME ${_target} + RUNTIME_OUTPUT_DIRECTORY "${output_dir}" + ) + target_link_libraries(${_target} PUBLIC ${ARG_LIBRARIES}) + + add_test( + NAME ${_target} + COMMAND $ + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + ) +endfunction() + ################################################################################################### # target_link_if_exists(Target # [PUBLIC dep1 dep2...] diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7b2a5125..130144b5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,3 +8,7 @@ if (BUILD_GUI) add_subdirectory(uisupport) add_subdirectory(qtui) endif() + +if (BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt new file mode 100644 index 00000000..9a263aae --- /dev/null +++ b/src/test/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(main) diff --git a/src/test/main/CMakeLists.txt b/src/test/main/CMakeLists.txt new file mode 100644 index 00000000..6d6993f8 --- /dev/null +++ b/src/test/main/CMakeLists.txt @@ -0,0 +1,13 @@ +quassel_add_module(Test::Main EXPORT NOINSTALL) + +target_sources(${TARGET} PRIVATE + main.cpp + testglobal.h +) + +target_link_libraries(${TARGET} + PUBLIC + GTest::GTest + Qt5::Core + Quassel::Common +) diff --git a/src/test/main/main.cpp b/src/test/main/main.cpp new file mode 100644 index 00000000..08adf103 --- /dev/null +++ b/src/test/main/main.cpp @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (C) 2005-2018 by the Quassel Project * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) version 3. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "test-main-export.h" + +#include + +#include + +TEST_MAIN_EXPORT int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + QCoreApplication app(argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/src/test/main/testglobal.h b/src/test/main/testglobal.h new file mode 100644 index 00000000..32763771 --- /dev/null +++ b/src/test/main/testglobal.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * Copyright (C) 2005-2018 by the Quassel Project * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) version 3. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#pragma once + +#include + +#include "test-main-export.h"