GTest源码剖析——传入参数分析及InitGoogleTest
1 InitGoogleTest()源码分析
InitGoogleTest接口如下,提供了对UNICODE的支持,两个接口后续的实现通过“***Impl”模版类进行统一。
本文以 InitGoogleTest(int* argc, char argv)
为例进行展开。
接口如下:
GTEST_API_ void InitGoogleTest(int* argc, char** argv);
// support UNICODE mode.
GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);
如果定义了宏GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_ , 则由使用者自行解析传入的参数。
void InitGoogleTest(int* argc, char** argv)
{
#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv);
#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
internal::InitGoogleTestImpl(argc, argv);
#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
}
1.1 InitGoogleTestImpl()
InitGoogleTest的实现是由InitGoogleTestImpl实现的,在test::internal命名空间下:
1. 判断是否初始化过以及参数是否为空;
2. 保存所有的传入参数到g_argvs中;
3. 检验参数的合法性及打印help信息;
4. 解析的参数对UnitTestImpl进行相关初始化操作。
template <typename CharType>
void InitGoogleTestImpl(int* argc, CharType** argv)
{
// We don't want to run the initialization code twice.
if (GTestIsInitialized()) return;
if (*argc <= 0) return;
g_argvs.clear();
for (int i = 0; i != *argc; i++)
{
//把传入的参数转化为字符串保存在g_argvs中
g_argvs.push_back(StreamableToString(argv[i]));
}
ParseGoogleTestFlagsOnly(argc, argv);
GetUnitTestImpl()->PostFlagParsingInit();
}
1.2 ParseGoogleTestFlagsOnly
- 其目的仅仅是为检验传入参数的合法性以及打印help信息。
void ParseGoogleTestFlagsOnly(int* argc, char** argv)
{
ParseGoogleTestFlagsOnlyImpl(argc, argv);
}
- ParseGoogleTestFlagsOnlyImpl源码如下:
template <typename CharType>
void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv)
{
for (int i = 1; i < *argc; i++)
{
const std::string arg_string = StreamableToString(argv[i]);
const char* const arg = arg_string.c_str();
using internal::ParseBoolFlag;
using internal::ParseInt32Flag;
using internal::ParseStringFlag;
bool remove_flag = false;
if (ParseGoogleTestFlag(arg))
{
remove_flag = true;
}
#if GTEST_USE_OWN_FLAGFILE_FLAG_
else if (ParseStringFlag(arg, kFlagfileFlag, >EST_FLAG(flagfile)))
{
LoadFlagsFromFile(GTEST_FLAG(flagfile));
remove_flag = true;
}
#endif
else if (arg_string == "--help"
|| arg_string == "-h"
|| arg_string == "-?"
|| arg_string == "/?"
|| HasGoogleTestFlagPrefix(arg))
{
g_help_flag = true;
}
if (remove_flag)
{
for (int j = i; j != *argc; j++)
{
argv[j] = argv[j + 1];
}
(*argc)--;
i--;
}
}
if (g_help_flag)
{
PrintColorEncoded(kColorEncodedHelpMessage);
}
}
1.3 UnitTestImpl::PostFlagParsingInit()
- 添加事件监听器GTEST_CUSTOM_TEST_EVENT_LISTENER_()
- 死亡测试相关处理
- 通过RegisterParameterizedTests()真正注册TEST_P宏相关的测试用例信息,其分析见《GTest源码剖析——TEST_P宏》
- 通过ConfigureXmlOutput()配置相关的测试用例结果输出,*unit格式的XML文件
- 通过ConfigureStreamingOutput()配置相关的测试用例结果输出,
void UnitTestImpl::PostFlagParsingInit()
{
if (!post_flag_parse_init_performed_)
{
post_flag_parse_init_performed_ = true;
#if defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_)
listeners()->Append(new GTEST_CUSTOM_TEST_EVENT_LISTENER_());
#endif
#if GTEST_HAS_DEATH_TEST
InitDeathTestSubprocessControlInfo();
SuppressTestEventsIfInSubprocess();
#endif
RegisterParameterizedTests();
ConfigureXmlOutput();
#if GTEST_CAN_STREAM_RESULTS_
ConfigureStreamingOutput();
#endif
}
}
1.4 UnitTestImpl::ConfigureXmlOutput()
void UnitTestImpl::ConfigureXmlOutput()
{
const std::string& output_format = UnitTestOptions::GetOutputFormat();
if (output_format == "xml")
{
//输出*unit风格的XML文件。
listeners()->SetDefaultXmlGenerator(
new XmlUnitTestResultPrinter(UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
}
else if (output_format != "")
{
printf("WARNING: unrecognized output format \"%s\" ignored.\n",output_format.c_str());
fflush(stdout);
}
}
2 传入参数分析
2.1 传入参数分类
Type | Param | Value |
---|---|---|
Test Selection | –gtest_list_tests | NO value |
–gtest_filter | POSTIVE_PATTERNS[-NEGATIVE_PATTERNS] | |
–gtest_also_run_disabled_tests | NO value | |
Test Execution | –gtest_repeat | [COUNT] |
–gtest_shuffle | NO value | |
–gtest_random_seed | [NUMBER] | |
Test Output | –gtest_color | (yes |
–gtest_print_time | 0 | |
–gtest_output | xml[:DIRECTORY_PATH/ | |
Assertion Behavior | –gtest_death_test_style | (fast |
–gtest_break_on_failur | NO value | |
–gtest_throw_on_failure | NO value | |
–gtest_catch_exceptions | 0 | |
2.2 传入参数用处
输入 “--help”参数会打印出所有的参数信息
Test Selection:
--gtest_list_tests
List the names of all tests instead of running them. The name of
TEST(Foo, Bar) is "Foo.Bar".
--gtest_filter=POSTIVE_PATTERNS[-NEGATIVE_PATTERNS]
Run only the tests whose name matches one of the positive patterns but
none of the negative patterns. '?' matches any single character; '*'
matches any substring; ':' separates two patterns.
--gtest_also_run_disabled_tests
Run all disabled tests too.
Test Execution:
--gtest_repeat=[COUNT]
Run the tests repeatedly; use a negative count to repeat forever.
--gtest_shuffle
Randomize tests' orders on every iteration.
--gtest_random_seed=[NUMBER]
Random number seed to use for shuffling test orders (between 1 and
99999, or 0 to use a seed based on the current time).
Test Output:
--gtest_color=(yes|no|auto)
Enable/disable colored output. The default is auto.
--gtest_print_time=0
Don't print the elapsed time of each test.
--gtest_output=xml[:DIRECTORY_PATH/|:FILE_PATH]
Generate an XML report in the given directory or with the given file
name. FILE_PATH defaults to test_details.xml.
Assertion Behavior:
--gtest_death_test_style=(fast|threadsafe)
Set the default death test style.
--gtest_break_on_failure
Turn assertion failures into debugger break-points.
--gtest_throw_on_failure
Turn assertion failures into C++ exceptions.
--gtest_catch_exceptions=0
Do not report exceptions as test failures. Instead, allow them
to crash the program or throw a pop-up (on Windows).
2.3 参数定义及保存
参数定义如下:
const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests";
const char kBreakOnFailureFlag[] = "break_on_failure";
const char kCatchExceptionsFlag[] = "catch_exceptions";
const char kColorFlag[] = "color";
const char kFilterFlag[] = "filter";
const char kListTestsFlag[] = "list_tests";
const char kOutputFlag[] = "output";
const char kPrintTimeFlag[] = "print_time";
const char kRandomSeedFlag[] = "random_seed";
const char kRepeatFlag[] = "repeat";
const char kShuffleFlag[] = "shuffle";
const char kStackTraceDepthFlag[] = "stack_trace_depth";
const char kStreamResultToFlag[] = "stream_result_to";
const char kThrowOnFailureFlag[] = "throw_on_failure";
const char kFlagfileFlag[] = "flagfile";
定义了一个vector类型的全局变量g_argvs,用于保存传入的参数。
::std::vector<testing::internal::string> g_argvs;
同时定义了GetArgvs()接口用于获取传入的参数。
const ::std::vector<testing::internal::string>& GetArgvs()
{
#if defined(GTEST_CUSTOM_GET_ARGVS_)
return GTEST_CUSTOM_GET_ARGVS_();
#else // defined(GTEST_CUSTOM_GET_ARGVS_)
return g_argvs;
#endif // defined(GTEST_CUSTOM_GET_ARGVS_)
}
3 参考
ZhaiPillar
2017-09-17