[英]Constructor for a test class in Google Test
namespace {
using namespace std;
// Declare the google test case
class InjectorTest : public ::testing::Test {
std::shared_ptr<MyData>> m_reader;
public:
static void SetUpTestCase() {
}
static void TearDownTestCase() {
}
InjectorTest()
{
//Create Reader code here !!!!
m_reader = CreateReader();
}
std::shared_ptr<DDSTopicReader<MyData>> getXMLReader() {
return m_reader;
}
};
TEST_F(InjectorTest, CreateReaderAndGetTopic) {
auto reader = getXMLReader();
std::string topic_name = reader->getTopicName();
EXPECT_EQ(topic_name, "test_topic");
}
}; // anonymous namespace
My questions is我的问题是
1) When I run the test case CreateReaderAndGetTopic
does the Constructor
of InjectorTest gets called before executing the test case? 1) 当我运行测试用例
CreateReaderAndGetTopic
,InjectorTest 的Constructor
在执行测试用例之前被调用了吗? Or should it be called explictly ?还是应该明确调用?
2) Should my class InjectorTest
have a constructor or should the code inside the constructor be moved to SetUpTestCase
. 2) 我的类
InjectorTest
应该有一个构造函数还是应该将构造函数中的代码移到SetUpTestCase
。
Let's mention first that the static class members SetUpTestCase
and TearDownTestCase
have been renamed respectively to SetUpTestSuite
and TearDownTestSuite
since googletest v1.8.让我们首先提到的静态类成员
SetUpTestCase
和TearDownTestCase
已分别更名为SetUpTestSuite
和TearDownTestSuite
自googletest V1.8。 See Beware of the nomenclature请参阅注意命名法
They did that because the names SetUpTestCase
and TearDownTestCase
were grossly misleading.他们这样做是因为名称
SetUpTestCase
和TearDownTestCase
具有严重的误导性。 They suggest functions that will be run in every case of a test that is derived from the fixture class in which they are defined, which they weren't.他们建议在从定义它们的夹具类派生的测试的每种情况下运行的函数,它们不是。
SetUpTestCase
was in fact run before the first of all tests derived from the fixture (and still is, if you have an older googletest installation), and TearDownTestCase
was run after the last of all tests derived from the fixture.实际上,
SetUpTestCase
是在从夹具派生的所有测试中的第一个之前运行的(如果您安装了较旧的 googletest,仍然如此),并且TearDownTestCase
是在从夹具派生的所有测试中的最后一个之后运行的。
As of googletest 1.8, all of the tests that derived from a fixture - which we'd naturally call its test cases - are collectively regarded as a test suite ;从 googletest 1.8 开始,所有源自夹具的测试——我们自然称之为测试用例——统称为测试套件; so the set-up function that runs before all of them is now called
SetUpTestSuite
and the tear-down function that runs after of them is called TearDownTestSuite
.因此,在所有这些之前运行的设置函数现在称为
SetUpTestSuite
而在它们之后运行的拆卸函数称为TearDownTestSuite
。 I will stick with the new improved names as I have the latest rev of googletest.我将坚持使用新的改进名称,因为我拥有 googletest 的最新版本。
Look at this gtest code that demonstrates the calling order of a fixture's constructor and destructor, SetUp
and TearDown
, SetUpTestSuite
and TearDownTestSuite
:看看这个 gtest 代码,它演示了夹具的构造函数和析构函数、
SetUp
和TearDown
、 SetUpTestSuite
和TearDownTestSuite
的调用顺序:
gtester.cpp文件
#include <gtest/gtest.h>
#include <iostream>
struct fixture : ::testing::Test
{
fixture() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
~fixture() override {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
void SetUp() override {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
void TearDown() override {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
static void SetUpTestSuite() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
static void TearDownTestSuite() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
TEST_F(fixture, One) {
ASSERT_EQ(1,1);
}
TEST_F(fixture, Two) {
ASSERT_NE(1,0);
}
TEST_F(fixture, Three) {
ASSERT_LT(1,2);
}
You can get a useful peek under the hood if you just preprocess this file (and preferably, pipe through a pretty-printer) and look at what comes out:如果你只是预处理这个文件(最好是通过一个漂亮的打印机)并查看结果,你可以在引擎盖下获得有用的窥视:
$ g++ -E -P gtester.cpp | clang-format > gtester.ii
In gtester.ii
you'll be able to find:在
gtester.ii
您将能够找到:
...
class fixture_One_Test : public fixture {
public:
fixture_One_Test() {}
private:
virtual void TestBody();
static ::testing::TestInfo *const test_info_ __attribute__((unused));
fixture_One_Test(fixture_One_Test const &) = delete;
void operator=(fixture_One_Test const &) = delete;
};
::testing::TestInfo *const fixture_One_Test::test_info_ =
::testing::internal::MakeAndRegisterTestInfo(
"fixture", "One", nullptr, nullptr,
::testing::internal::CodeLocation("gtester.cpp", 31),
(::testing::internal::GetTypeId<fixture>()),
::testing::internal::SuiteApiResolver<fixture>::GetSetUpCaseOrSuite(),
::testing::internal::SuiteApiResolver<
fixture>::GetTearDownCaseOrSuite(),
new ::testing::internal::TestFactoryImpl<fixture_One_Test>);
void fixture_One_Test::TestBody() {
switch (0)
case 0:
default:
if (const ::testing::AssertionResult gtest_ar =
(::testing::internal::EqHelper<
decltype(::testing::internal::IsNullLiteralHelper(
1, ::testing::internal::TypeIsValidNullptrConstant<decltype(
1)>()))::value>::Compare("1", "1", 1, 1)))
;
else
return ::testing::internal::AssertHelper(
::testing::TestPartResult::kFatalFailure, "gtester.cpp", 32,
gtest_ar.failure_message()) = ::testing::Message();
}
...
That is what the test case:这就是测试用例:
TEST_F(fixture, One) {
ASSERT_EQ(1,1);
}
expands to after preprocessing.扩展为预处理后。 When googletest runs test case
fixture.One
:当googletest运行测试用例
fixture.One
:
fixture_One_Test
- which by inheritance, is a new instance of fixture
.fixture_One_Test
实例——通过继承,它是一个新的fixture
实例。fixture
constructor is called.fixture
构造函数。fixture_One_Test
constructor is called.fixture_One_Test
构造函数。 (But it's empty.) fixture::Setup()
through the fixture_One_Test
instance. fixture_One_Test
实例调用fixture::Setup()
。fixture_One_Test::TestBody()
through the fixture_One_Test
instance, which executes the payload of the test case.fixture_One_Test
实例调用fixture_One_Test::TestBody()
,该实例执行测试用例的payload。fixture::TearDown()
through the fixture_One_Test
instance.fixture_One_Test
实例调用调用fixture::TearDown()
。fixture_One_Test
instance, which -fixture_One_Test
实例,其中 -fixture_One_Test
destructor, which simply -fixture_One_Test
析构函数,它只是 -fixture
destructor.fixture
析构函数。 Similarly for fixture_Two_Test
and fixture_Three_Test
.类似的
fixture_Two_Test
和fixture_Three_Test
。
And just before all of that, googletest calls fixture::SetupTestSuite
, if it's is defined.就在这之前,googletest 调用
fixture::SetupTestSuite
,如果它被定义了。
And just after all of that, googletest calls fixture::TearDownTestSuite
, if it's is defined.就在这一切之后, googletest 调用
fixture::TearDownTestSuite
,如果它被定义了。
Now let's see that in action:现在让我们看看它的实际效果:
$ g++ -Wall -Wextra -o gtester gtester.cpp -lgtest_main -lgtest -pthread
$ ./gtester
Running main() from /home/imk/Downloads/googletest-master/googletest/src/gtest_main.cc
[==========] Running 3 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 3 tests from fixture
static void fixture::SetUpTestSuite()
[ RUN ] fixture.One
fixture::fixture()
virtual void fixture::SetUp()
virtual void fixture::TearDown()
virtual fixture::~fixture()
[ OK ] fixture.One (0 ms)
[ RUN ] fixture.Two
fixture::fixture()
virtual void fixture::SetUp()
virtual void fixture::TearDown()
virtual fixture::~fixture()
[ OK ] fixture.Two (0 ms)
[ RUN ] fixture.Three
fixture::fixture()
virtual void fixture::SetUp()
virtual void fixture::TearDown()
virtual fixture::~fixture()
[ OK ] fixture.Three (0 ms)
static void fixture::TearDownTestSuite()
[----------] 3 tests from fixture (0 ms total)
[----------] Global test environment tear-down
[==========] 3 tests from 1 test case ran. (0 ms total)
[ PASSED ] 3 tests.
SetUpTestSuite()
and TearDownTestSuite()
each run just once. SetUpTestSuite()
和TearDownTestSuite()
每个只运行一次。 The constructor, destructor, SetUp()
and TearDown()
each run 3 times = the number of test cases in the test suite.构造函数、析构函数、
SetUp()
和TearDown()
各运行 3 次 = 测试套件中的测试用例数。
So to your two questions:所以你的两个问题:
When I run the test case CreateReaderAndGetTopic does the Constructor of InjectorTest gets called before executing the test case?
当我运行测试用例 CreateReaderAndGetTopic 时,是否在执行测试用例之前调用了 InjectorTest 的构造函数? Or should it be called explictly ?
还是应该明确调用?
The InjectorTest
constructor is necessarily called to construct an instance of the class CreateReaderAndGetTopic_InjectorTest_Test
, which Googletest does for you.必须调用
InjectorTest
构造函数来构造类CreateReaderAndGetTopic_InjectorTest_Test
的实例,Googletest 会为您完成该实例。 It is called before SetUp()
, which is called before TestBody()
, which is the payload of the test case.它在
SetUp()
之前调用,后者在TestBody()
之前TestBody()
,后者是测试用例的有效载荷。
Should my class InjectorTest have a constructor...
我的类 InjectorTest 是否应该有一个构造函数...
InjectorTest
will have a constructor, either by default or as defined by you; InjectorTest
将有一个构造函数,默认情况下或由您定义; so you're wondering whether you should define one.所以你想知道是否应该定义一个。
You should define one if you have something to do that needs to be done anew in preparation for each test case, and that had better be done before the SetUp()
for each test case.如果您有某事需要为每个测试用例重新做准备,那么您应该定义一个,并且最好在每个测试用例的
SetUp()
之前完成。
... or should the code inside the constructor be moved to SetUpTestCase?
...还是应该将构造函数中的代码移至 SetUpTestCase?
The code you have inside the constructor:您在构造函数中的代码:
m_reader = CreateReader();
should be moved out to SetUpTestCase
- aka SetUpTestSuite
- if it is something that does not need to be done anew in preparation for each test case but needs to be done once just before all test cases of InjectorTest
.应该搬出来
SetUpTestCase
-又名SetUpTestSuite
-如果它是什么并不需要在所有的测试案例,但需要准备重新做只是所有测试用例之前进行一次InjectorTest
。
As it stands, you cannot move that constructor code into SetUpTestSuite
because it initializes a non-static class member of InjectorTest
, m_reader
.就目前而言,您不能将该构造函数代码移动到
SetUpTestSuite
因为它初始化了InjectorTest
的非静态类成员m_reader
。 But do you in fact need or want a new XMLReader
to be created by CreateReader()
for each test case?但是您实际上是否需要或希望
CreateReader()
为每个测试用例创建一个新的XMLReader
? Only you can decide.只有你能决定。
If you do want to create a new reader for each test case, then you face the choice of creating it in the constructor or in SetUp()
.如果您确实想为每个测试用例创建一个新的阅读器,那么您将面临在构造函数或
SetUp()
中创建它的选择。 Here you can be guided by the Googletest FAQ Should I use the constructor/destructor of the test fixture or SetUp()/TearDown()?这里可以参考Googletest FAQ的指导, 我应该使用测试夹具的构造函数/析构函数还是SetUp()/TearDown()?
If you want to make sure your test cases in a fixture have the same setup, you should implement the SetUp
and TearDown
methods (notice the case)如果您想确保夹具中的测试用例具有相同的设置,您应该实现
SetUp
和TearDown
方法(注意案例)
Your InjectorTest
fixture only gets constructed once, but the SetUp
step (resp. the TearDown
step) will be run before (resp. after) your test case is executed.您的
InjectorTest
夹具仅构建一次,但SetUp
步骤(或TearDown
步骤)将在您的测试用例执行之前(或之后)运行。
The constructor should only deal with things that should be only done once (if any), any behavior you want to enforce for your test cases should go in these 2 methods.构造函数应该只处理应该只做一次的事情(如果有的话),你想为你的测试用例强制执行的任何行为都应该在这两种方法中。 In your example, if the
m_reader
member can be shared across all your test cases, you can initialize it in the constructor like you did.在您的示例中,如果
m_reader
成员可以在您的所有测试用例之间共享,您可以像您一样在构造函数中对其进行初始化。
To sumup, here is the sequence of operations that will be run:总而言之,这是将要运行的操作序列:
InjectorTest::InjectorTest()
: test fixture is constructed InjectorTest::InjectorTest()
:构建测试夹具InjectorTest::SetUp()
: setup for test case InjectorTest::SetUp()
: 测试用例的设置InjectorTest::CreateReaderAndGetTopic
)InjectorTest::CreateReaderAndGetTopic
)InjectorTest::TearDown()
: setup is undone for next case InjectorTest::TearDown()
:为下一个案例撤消设置InjectorTest::~InjectorTest()
: destruction of the fixture object InjectorTest::~InjectorTest()
: 销毁夹具对象
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.