TEST(TestCaseName1, TestName1){
cout << "hello1" << endl;
}
int main(int argc,char* argv[])
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
分析:上述例子当中,看到RUN_ALL_TESTS()这个宏,从名字上来看,这是运行所有的测试用例,这才是我们运行测试用例的真正入口,下面来看一下具体的源码实现
RUN_ALL_TESTS()之前是一个宏,将其实现为函数,在这里,调用了UnitTest单例的Run函数
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_;
inline int RUN_ALL_TESTS() {
return ::testing::UnitTest::GetInstance()->Run();
}
接着去看调用过程,可以看到,依次调用的过程是:
1. UnitTest::Run()
2. UnitTestImpl::RunAllTests()
3. TestCase::Run()
4. TestInfo::Run()
5. Test::Run()
int UnitTest::Run() {
//关于死亡测试
const bool in_death_test_child_process =
internal::GTEST_FLAG(internal_run_death_test).length() > 0;
const internal::ScopedPrematureExitFile premature_exit_file(
in_death_test_child_process ?
NULL :internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE"));
impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); //捕获异常
#if GTEST_HAS_SEH
if (impl()->catch_exceptions() || in_death_test_child_process) {
# if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
# endif // !GTEST_OS_WINDOWS_MOBILE
# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE
_set_error_mode(_OUT_TO_STDERR);
# endif
# if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE
if (!GTEST_FLAG(break_on_failure))
_set_abort_behavior(
0x0, // Clear the following flags:
_WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump.
# endif
}
#endif // GTEST_HAS_SEH
//以上全是关于死亡测试和跨平台异常的的一些设定,下面才是真正实现其功能的地方
return internal::HandleExceptionsInMethodIfSupported(
impl(),
&internal::UnitTestImpl::RunAllTests,
"auxiliary test code (environments or event listeners)") ? 0 : 1;
}
如果不涉及源码中的死亡测试以及跨平台可能出现异常的一些问题,其简化为
int UnitTest::Run()
{
return internal::HandleExceptionsInMethodIfSupported(
impl(),
&internal::UnitTestImpl::RunAllTests,
"auxiliary test code (environments or event listeners)") ? 0 : 1;
}
在将其简化,可以发现由impl对象指针调用了RunAllTests();
int UnitTest::Run()
{
return impl->RunAllTests();
}
这里使用了impl()方法,该方法返回了一个UnitTestImpl对象指针impl_,由指针调用了RunAllTest,
UnitTest::UnitTest() {
impl_ = new internal::UnitTestImpl(this);
}
源码:
bool UnitTestImpl::RunAllTests() {
//准备工作
// Makes sure InitGoogleTest() was called.
if (!GTestIsInitialized()) {
printf("%s",
"\nThis test program did NOT call ::testing::InitGoogleTest "
"before calling RUN_ALL_TESTS(). Please fix it.\n");
return false;
}
// Do not run any test if the --help flag was specified.
if (g_help_flag)
return true;
//重复对后标记解析初始化的调用,以防万一用户没有调用InitGoogleTest。
PostFlagParsingInit();
//关于对用户提供的设计
internal::WriteToShardStatusFileIfNeeded();
//对死亡测试线程安全方面的检测
bool in_subprocess_for_death_test = false;
#if GTEST_HAS_DEATH_TEST
in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL);
# if defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_)
if (in_subprocess_for_death_test) {
GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_();
}
# endif // defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_)
#endif // GTEST_HAS_DEATH_TEST
//与环境相关的设置,暂时不关心
const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,
in_subprocess_for_death_test);
// 匹配测试用例,对所有的测试用例进行匹配,决定要执行哪一个测试用例
const bool has_tests_to_run = FilterTests(should_shard
? HONOR_SHARDING_PROTOCOL
: IGNORE_SHARDING_PROTOCOL) > 0;
//如果指定了gtestlisttest标志,则列出测试和出口。
if (GTEST_FLAG(list_tests)) {
// This must be called *after* FilterTests() has been called.
ListTestsMatchingFilter();
return true;
}
//生成随机测试用例
random_seed_ = GTEST_FLAG(shuffle) ?
GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0;
// True iff at least one test has failed.
bool failed = false;
//获取事件监听器,如果用户订阅了某事件,则在适当的时间点上报该事件,让用户进行额外的操作
TestEventListener* repeater = listeners()->repeater();
//上报事件OnTestProgramStart
start_timestamp_ = GetTimeInMillis();
repeater->OnTestProgramStart(*parent_);
const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat);
const bool forever = repeat < 0;
for (int i = 0; forever || i != repeat; i++) {
//清除所有非AddHoc的测试结果,为后续运行做准备。
ClearNonAdHocTestResult();
const TimeInMillis start = GetTimeInMillis();
if (has_tests_to_run && GTEST_FLAG(shuffle)) {
random()->Reseed(random_seed_);
ShuffleTests();
}
repeater->OnTestIterationStart(*parent_, i);
if (has_tests_to_run) {
repeater->OnEnvironmentsSetUpStart(*parent_);
ForEach(environments_, SetUpEnvironment);
repeater->OnEnvironmentsSetUpEnd(*parent_);
if (!Test::HasFatalFailure()) { //核心代码
for (int test_index = 0; test_index < total_test_case_count();
test_index++) {
GetMutableTestCase(test_index)->Run(); //逐个运行测试用例,执行后面的TestBody()
}
}
repeater->OnEnvironmentsTearDownStart(*parent_);
std::for_each(environments_.rbegin(), environments_.rend(),
TearDownEnvironment);
repeater->OnEnvironmentsTearDownEnd(*parent_);
}
elapsed_time_ = GetTimeInMillis() - start;
repeater->OnTestIterationEnd(*parent_, i);
if (!Passed()) {
failed = true;
}
UnshuffleTests();
if (GTEST_FLAG(shuffle)) {
// Picks a new random seed for each iteration.
random_seed_ = GetNextRandomSeed(random_seed_);
}
}
repeater->OnTestProgramEnd(*parent_);
return !failed;
}
上述源码中,提取出最核心的代码,如下:
for (int test_index = 0; test_index < total_test_case_count();
test_index++) {
GetMutableTestCase(test_index)->Run(); //逐个运行测试用例,执行后面的TestBody()
}
分析:上一篇看TEST宏的源码中,我们看到所有的测试用例都存放在一个数组当中,这里就利用这一特点,通过返回UnitTestImpl对象成员变量test_cases_中的元素——各个测试用例对象指针,然后调用测试用例的Run方法。
std::vector test_cases_;
void TestCase::Run() {
if (!should_run_) return;
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->set_current_test_case(this);
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
repeater->OnTestCaseStart(*this);
impl->os_stack_trace_getter()->UponLeavingGTest();
internal::HandleExceptionsInMethodIfSupported(
this, &TestCase::RunSetUpTestCase, "SetUpTestCase()");
const internal::TimeInMillis start = internal::GetTimeInMillis();
//核心代码
for (int i = 0; i < total_test_count(); i++) {
GetMutableTestInfo(i)->Run();
}
elapsed_time_ = internal::GetTimeInMillis() - start;
impl->os_stack_trace_getter()->UponLeavingGTest();
internal::HandleExceptionsInMethodIfSupported(
this, &TestCase::RunTearDownTestCase, "TearDownTestCase()");
repeater->OnTestCaseEnd(*this);
impl->set_current_test_case(NULL);
}
分析:和上面 UnitTestImpl::RunAllTests思想类似,其中核心的源码如下,这里还是获取特例信息,调用Run方法
for (int i = 0; i < total_test_count(); i++) {
GetMutableTestInfo(i)->Run();
}
源码:
void TestInfo::Run() {
if (!should_run_) return;
// Tells UnitTest where to store test result.
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->set_current_test_info(this);
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
// Notifies the unit test event listeners that a test is about to start.
repeater->OnTestStart(*this);
const TimeInMillis start = internal::GetTimeInMillis();
const TimeInMillis start = internal::GetTimeInMillis();
impl->os_stack_trace_getter()->UponLeavingGTest();
// Creates the test object. 核心代码,后面单独进行分析
Test* const test = internal::HandleExceptionsInMethodIfSupported(
factory_, &internal::TestFactoryBase::CreateTest,
"the test fixture's constructor");
if ((test != NULL) && !Test::HasFatalFailure()) {
test->Run();
}
// Deletes the test object.
impl->os_stack_trace_getter()->UponLeavingGTest();
internal::HandleExceptionsInMethodIfSupported(
test, &Test::DeleteSelf_, "the test fixture's destructor");
result_.set_elapsed_time(internal::GetTimeInMillis() - start);
// Notifies the unit test event listener that a test has just finished.
repeater->OnTestEnd(*this);
// Tells UnitTest to stop associating assertion results to this
// test.
impl->set_current_test_info(NULL);
}
核心源码分析:
Test* const test = internal::HandleExceptionsInMethodIfSupported(
factory_, &internal::TestFactoryBase::CreateTest,
"the test fixture's constructor");
if ((test != NULL) && !Test::HasFatalFailure()) {
test->Run();
}
这里是创造一个对象:将工厂类对象指针调用的Create Test方法传入构造函数,new出一个TEST宏的一个类对象的指针,用这个对象指针去调用父类的Run方法,从而去调用TestBody方法(注:TestBody是上一篇中提到的TEST当中的虚函数)