Skip to content

Instantly share code, notes, and snippets.

@phetdam
Last active September 7, 2022 05:05
Show Gist options
  • Save phetdam/9e4381312d95786718e31c15b7c51614 to your computer and use it in GitHub Desktop.
Save phetdam/9e4381312d95786718e31c15b7c51614 to your computer and use it in GitHub Desktop.
A way to use multiple types with the Google Test TYPED_TEST macro.
// `type_triple` specializations to use with TYPED_TEST for MultiTypedTest
using MultiTypedTestTypes = ::testing::Types<
type_triple<int, double, float>,
type_triple<char, std::string, size_t>,
type_triple<std::string, double, void *>
>;
// required macro to set up the typed test suite
TYPED_TEST_SUITE(MultiTypedTest, MultiTypedTestTypes);
# ignore build directories and build artifacts
build
build_win
multi_typed_test
*.exe
*.ilk
*.pdb

GNU/Linux:

cmake -S . -B build && cmake --build build -j && ./multi_typed_test

Windows:

cmake -S . -B build_win -G Ninja && cmake --build build_win && .\multi_typed_test

cmake_minimum_required(VERSION 3.20)
project(
multi_typed_test
VERSION 0.1.0
DESCRIPTION
"A way to use multiple types with the Google Test TYPED_TEST macro."
HOMEPAGE_URL
https://gist.github.com/phetdam/9e4381312d95786718e31c15b7c51614
LANGUAGES CXX
)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include(FetchContent)
# download Google Test from GitHub
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.12.1
)
# for Windows, forces use of the shared Windows C runtime library (CRT), as by
# default static Google Test links against the static Windows CRT.
set(gtest_force_shared_crt TRUE CACHE BOOL "" FORCE)
# build Google Test as static and make its targets available
FetchContent_MakeAvailable(googletest)
# we don't register this as a test with CMake
add_executable(multi_typed_test multi_typed_test.cc)
# GTest::Main target is only created if using find_package
target_link_libraries(multi_typed_test GTest::gtest_main)
set_property(
TARGET multi_typed_test
PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}
)
/**
* @file multi_typed_test.cc
* @author Derek Huang
* @brief A way to use multiple types with the Google Test TYPED_TEST macro.
* @copyright MIT License
*/
#include <iostream>
#include <string>
#include <gtest/gtest.h>
namespace {
/**
* A class with using-defs to its three types.
*/
template <typename T, typename U, typename V>
class type_triple {
public:
type_triple() = delete;
using type_a = T;
using type_b = U;
using type_c = V;
};
/**
* Return string indicating a generic template type.
*
* The specializations for this function return different string values.
*/
template <typename T>
std::string tstring() { return "T"; }
template <>
std::string tstring<int>() { return "int"; }
template <>
std::string tstring<double>() { return "double"; }
template <>
std::string tstring<char>() { return "char"; }
template <>
std::string tstring<std::string>() { return "std::string"; }
/**
* Google Test fixture intended for use with `type_triple<T, U, V>`.
*
* Each `type_info_string_[a-c]` static function returns a "type string" for
* `Tr_t::type_[a-c]` by using the `tstring` template function(s).
*/
template <typename Tr_t>
class MultiTypedTest : public ::testing::Test {
protected:
static std::string type_info_string_a()
{
return "A: " + tstring<typename Tr_t::type_a>();
}
static std::string type_info_string_b()
{
return "B: " + tstring<typename Tr_t::type_b>();
}
static std::string type_info_string_c()
{
return "C: " + tstring<typename Tr_t::type_c>();
}
};
// `type_triple` specializations to use with TYPED_TEST for MultiTypedTest
using MultiTypedTestTypes = ::testing::Types<
type_triple<int, double, float>,
type_triple<char, std::string, size_t>,
type_triple<std::string, double, void *>
>;
// required macro to set up the typed test suite
TYPED_TEST_SUITE(MultiTypedTest, MultiTypedTestTypes);
/**
* Test that `Tr_t::type_[a-c]` are the expected types.
*
* This test hardcodes the comparison for `Tr_t::type_c`, as `float`, `size_t`,
* `void *` will result in the `tstring` function simply returning `"T"`.
*/
TYPED_TEST(MultiTypedTest, TypesTest)
{
EXPECT_EQ(
"A: " + tstring<typename TypeParam::type_a>(),
TestFixture::type_info_string_a()
);
EXPECT_EQ(
"B: " + tstring<typename TypeParam::type_b>(),
TestFixture::type_info_string_b()
);
EXPECT_EQ("C: T", TestFixture::type_info_string_c());
}
} // namespace
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment