C++ 如何在具有多个TEST.cpp的头文件中使用实例化_TEST_CASE_P?
假设我在头文件fixtures.h中定义了一个GTest fixture:C++ 如何在具有多个TEST.cpp的头文件中使用实例化_TEST_CASE_P?,c++,googletest,C++,Googletest,假设我在头文件fixtures.h中定义了一个GTest fixture: class baseFixture : public ::testing::Test{ // some shared functionality among tests } 以及允许某些参数化的衍生夹具: class derivedFixture: public baseFixture, public ::testing::WithParamInterface<std::tuple<bool
class baseFixture : public ::testing::Test{
// some shared functionality among tests
}
以及允许某些参数化的衍生夹具:
class derivedFixture: public baseFixture,
public ::testing::WithParamInterface<std::tuple<bool, int>>{};
为了运行{true,false}和{1}的叉积的测试集。当我只编译一个cpp文件,将其命名为N1.cpp并运行可执行文件时,我通过
TEST\P获得了正确的行为(derivedFixture*
测试-每个测试运行两次。但是,当我构建整个项目并执行测试时,每个测试都会运行2*N次。我在头文件中使用了include-guard来防止实例化宏被调用两次,我确信我不会在其他任何地方调用它。您所做的基本上是这样的:
fixture.hpp(1)
当您期望4个测试时,您会看到8个测试,每个实例化一个/fixture.test\u a/N
在{0,1}中运行两次
错误在于:我们做:
INSTANTIATE_TEST_CASE_P(instantiation_one, fixture,
::testing::Combine(::testing::Bool(), ::testing::Values(1)));
在fixture.hpp
,即#包括-ed,因此在每个
翻译单元tN.cpp
,导致注册的2个参数化测试
通过此代码,可以在运行时注册N次
,从而运行N次
我们应该编译一个值参数化装置的每个实例
对于给定的一组值,只需执行一次,因此只需在一个源文件中执行该操作,例如
fixture.hpp(2)
也许我对翻译单位有误解。我认为fixture.hpp中的#ifndef卫士会导致宏只运行一次。既然不是这样,为什么它会运行多次?@PhilipDakin Hi。头卫士会阻止foo.h
的内容被预处理和编译多次,不管它被预处理和编译多少次#include
sfoo.h
。如果您编译了N个翻译单元,每个#包含foo.h
,并成功地将N个目标文件链接到一个程序中,则编译foo.h
内容后在目标文件中生成的任何代码都将链接到该程序中N次。
#ifndef FIXTURE_HPP
#define FIXTURE_HPP
#include <gtest/gtest.h>
struct fixture: ::testing::TestWithParam<std::tuple<bool, int>>
{};
INSTANTIATE_TEST_CASE_P(instantiation_one, fixture,
::testing::Combine(::testing::Bool(), ::testing::Values(1)));
#endif
#include "fixture.hpp"
#include <tuple>
TEST_P(fixture, test_a)
{
auto const & param = GetParam();
std::cout << "param 0 = " << std::get<0>(param) << std::endl;
std::cout << "param 1 = " << std::get<1>(param) << std::endl;
SUCCEED();
}
#include "fixture.hpp"
#include <tuple>
TEST_P(fixture, test_b)
{
auto const & param = GetParam();
std::cout << "param 0 = " << std::get<0>(param) << std::endl;
std::cout << "param 1 = " << std::get<1>(param) << std::endl;
SUCCEED();
}
#include <gtest/gtest.h>
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
$ ./gtester
[==========] Running 8 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 8 tests from instantiation_one/fixture
[ RUN ] instantiation_one/fixture.test_a/0
param 0 = 0
param 1 = 1
[ OK ] instantiation_one/fixture.test_a/0 (0 ms)
[ RUN ] instantiation_one/fixture.test_a/1
param 0 = 1
param 1 = 1
[ OK ] instantiation_one/fixture.test_a/1 (0 ms)
[ RUN ] instantiation_one/fixture.test_a/0
param 0 = 0
param 1 = 1
[ OK ] instantiation_one/fixture.test_a/0 (0 ms)
[ RUN ] instantiation_one/fixture.test_a/1
param 0 = 1
param 1 = 1
[ OK ] instantiation_one/fixture.test_a/1 (0 ms)
[ RUN ] instantiation_one/fixture.test_b/0
param 0 = 0
param 1 = 1
[ OK ] instantiation_one/fixture.test_b/0 (0 ms)
[ RUN ] instantiation_one/fixture.test_b/1
param 0 = 1
param 1 = 1
[ OK ] instantiation_one/fixture.test_b/1 (0 ms)
[ RUN ] instantiation_one/fixture.test_b/0
param 0 = 0
param 1 = 1
[ OK ] instantiation_one/fixture.test_b/0 (0 ms)
[ RUN ] instantiation_one/fixture.test_b/1
param 0 = 1
param 1 = 1
[ OK ] instantiation_one/fixture.test_b/1 (0 ms)
[----------] 8 tests from instantiation_one/fixture (0 ms total)
[----------] Global test environment tear-down
[==========] 8 tests from 1 test case ran. (1 ms total)
[ PASSED ] 8 tests.
INSTANTIATE_TEST_CASE_P(instantiation_one, fixture,
::testing::Combine(::testing::Bool(), ::testing::Values(1)));
#ifndef FIXTURE_HPP
#define FIXTURE_HPP
#include <gtest/gtest.h>
struct fixture: ::testing::TestWithParam<std::tuple<bool, int>>
{};
#endif
#include <gtest/gtest.h>
#include "fixture.hpp"
INSTANTIATE_TEST_CASE_P(instantiation_one, fixture,
::testing::Combine(::testing::Bool(), ::testing::Values(1)));
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
$ g++ -Wall -Wextra -c main.cpp t1.cpp t2.cpp
$ g++ -o gtester main.o t1.o t2.o -lgtest -pthread
$ ./gtester
[==========] Running 4 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 4 tests from instantiation_one/fixture
[ RUN ] instantiation_one/fixture.test_a/0
param 0 = 0
param 1 = 1
[ OK ] instantiation_one/fixture.test_a/0 (0 ms)
[ RUN ] instantiation_one/fixture.test_a/1
param 0 = 1
param 1 = 1
[ OK ] instantiation_one/fixture.test_a/1 (0 ms)
[ RUN ] instantiation_one/fixture.test_b/0
param 0 = 0
param 1 = 1
[ OK ] instantiation_one/fixture.test_b/0 (1 ms)
[ RUN ] instantiation_one/fixture.test_b/1
param 0 = 1
param 1 = 1
[ OK ] instantiation_one/fixture.test_b/1 (0 ms)
[----------] 4 tests from instantiation_one/fixture (1 ms total)
[----------] Global test environment tear-down
[==========] 4 tests from 1 test case ran. (1 ms total)
[ PASSED ] 4 tests.