您的位置:首页 > 编程语言 > Go语言

GTest源码剖析(五)——传入参数分析及InitGoogleTest

2017-09-17 23:14 696 查看

GTest源码剖析——传入参数分析及InitGoogleTest

GTest源码剖析传入参数分析及InitGoogleTest
InitGoogleTest源码分析
1 InitGoogleTestImpl

2 ParseGoogleTestFlagsOnly
3 UnitTestImplPostFlagParsingInit

4 UnitTestImplConfigureXmlOutput

传入参数分析
1 传入参数分类

2 传入参数用处

3 参数定义及保存

参考

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 传入参数分类

TypeParamValue
Test Selection–gtest_list_testsNO value
–gtest_filterPOSTIVE_PATTERNS[-NEGATIVE_PATTERNS]
–gtest_also_run_disabled_testsNO value
Test Execution–gtest_repeat[COUNT]
–gtest_shuffleNO value
–gtest_random_seed[NUMBER]
Test Output–gtest_color(yes
–gtest_print_time0
–gtest_outputxml[:DIRECTORY_PATH/
Assertion Behavior–gtest_death_test_style(fast
–gtest_break_on_failurNO value
–gtest_throw_on_failureNO value
–gtest_catch_exceptions0

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 参考

github: googletest

ZhaiPillar

2017-09-17
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息