Adds type_param and value_param as <testcase> attributes to the XML

report; also removes the comment() and test_case_comment() fields of
TestInfo.  Proposed and initally implemented by Joey Oravec.
Re-implemented by Vlad Losev.
This commit is contained in:
zhanyong.wan 2011-02-02 00:49:33 +00:00
parent c8efea6705
commit 9bcf4d0a65
10 changed files with 199 additions and 103 deletions

View File

@ -634,11 +634,21 @@ class GTEST_API_ TestInfo {
// Returns the test name. // Returns the test name.
const char* name() const { return name_.c_str(); } const char* name() const { return name_.c_str(); }
// Returns the test case comment. // Returns the name of the parameter type, or NULL if this is not a typed
const char* test_case_comment() const { return test_case_comment_.c_str(); } // or a type-parameterized test.
const char* type_param() const {
if (type_param_.get() != NULL)
return type_param_->c_str();
return NULL;
}
// Returns the test comment. // Returns the text representation of the value parameter, or NULL if this
const char* comment() const { return comment_.c_str(); } // is not a value-parameterized test.
const char* value_param() const {
if (value_param_.get() != NULL)
return value_param_->c_str();
return NULL;
}
// Returns true if this test should run, that is if the test is not disabled // Returns true if this test should run, that is if the test is not disabled
// (or it is disabled but the also_run_disabled_tests flag has been specified) // (or it is disabled but the also_run_disabled_tests flag has been specified)
@ -670,7 +680,8 @@ class GTEST_API_ TestInfo {
friend class internal::UnitTestImpl; friend class internal::UnitTestImpl;
friend TestInfo* internal::MakeAndRegisterTestInfo( friend TestInfo* internal::MakeAndRegisterTestInfo(
const char* test_case_name, const char* name, const char* test_case_name, const char* name,
const char* test_case_comment, const char* comment, const char* type_param,
const char* value_param,
internal::TypeId fixture_class_id, internal::TypeId fixture_class_id,
Test::SetUpTestCaseFunc set_up_tc, Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc, Test::TearDownTestCaseFunc tear_down_tc,
@ -679,7 +690,8 @@ class GTEST_API_ TestInfo {
// Constructs a TestInfo object. The newly constructed instance assumes // Constructs a TestInfo object. The newly constructed instance assumes
// ownership of the factory object. // ownership of the factory object.
TestInfo(const char* test_case_name, const char* name, TestInfo(const char* test_case_name, const char* name,
const char* test_case_comment, const char* comment, const char* a_type_param,
const char* a_value_param,
internal::TypeId fixture_class_id, internal::TypeId fixture_class_id,
internal::TestFactoryBase* factory); internal::TestFactoryBase* factory);
@ -700,8 +712,12 @@ class GTEST_API_ TestInfo {
// These fields are immutable properties of the test. // These fields are immutable properties of the test.
const std::string test_case_name_; // Test case name const std::string test_case_name_; // Test case name
const std::string name_; // Test name const std::string name_; // Test name
const std::string test_case_comment_; // Test case comment // Name of the parameter type, or NULL if this is not a typed or a
const std::string comment_; // Test comment // type-parameterized test.
const internal::scoped_ptr<const ::std::string> type_param_;
// Text representation of the value parameter, or NULL if this is not a
// value-parameterized test.
const internal::scoped_ptr<const ::std::string> value_param_;
const internal::TypeId fixture_class_id_; // ID of the test fixture class const internal::TypeId fixture_class_id_; // ID of the test fixture class
bool should_run_; // True iff this test should run bool should_run_; // True iff this test should run
bool is_disabled_; // True iff this test is disabled bool is_disabled_; // True iff this test is disabled
@ -730,9 +746,11 @@ class GTEST_API_ TestCase {
// Arguments: // Arguments:
// //
// name: name of the test case // name: name of the test case
// a_type_param: the name of the test's type parameter, or NULL if
// this is not a type-parameterized test.
// set_up_tc: pointer to the function that sets up the test case // set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case // tear_down_tc: pointer to the function that tears down the test case
TestCase(const char* name, const char* comment, TestCase(const char* name, const char* a_type_param,
Test::SetUpTestCaseFunc set_up_tc, Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc); Test::TearDownTestCaseFunc tear_down_tc);
@ -742,8 +760,13 @@ class GTEST_API_ TestCase {
// Gets the name of the TestCase. // Gets the name of the TestCase.
const char* name() const { return name_.c_str(); } const char* name() const { return name_.c_str(); }
// Returns the test case comment. // Returns the name of the parameter type, or NULL if this is not a
const char* comment() const { return comment_.c_str(); } // type-parameterized test case.
const char* type_param() const {
if (type_param_.get() != NULL)
return type_param_->c_str();
return NULL;
}
// Returns true if any test in this test case should run. // Returns true if any test in this test case should run.
bool should_run() const { return should_run_; } bool should_run() const { return should_run_; }
@ -846,8 +869,9 @@ class GTEST_API_ TestCase {
// Name of the test case. // Name of the test case.
internal::String name_; internal::String name_;
// Comment on the test case. // Name of the parameter type, or NULL if this is not a typed or a
internal::String comment_; // type-parameterized test.
const internal::scoped_ptr<const ::std::string> type_param_;
// The vector of TestInfos in their original order. It owns the // The vector of TestInfos in their original order. It owns the
// elements in the vector. // elements in the vector.
std::vector<TestInfo*> test_info_list_; std::vector<TestInfo*> test_info_list_;

View File

@ -561,10 +561,10 @@ typedef void (*TearDownTestCaseFunc)();
// //
// test_case_name: name of the test case // test_case_name: name of the test case
// name: name of the test // name: name of the test
// test_case_comment: a comment on the test case that will be included in // type_param the name of the test's type parameter, or NULL if
// the test output // this is not a typed or a type-parameterized test.
// comment: a comment on the test that will be included in the // value_param text representation of the test's value parameter,
// test output // or NULL if this is not a type-parameterized test.
// fixture_class_id: ID of the test fixture class // fixture_class_id: ID of the test fixture class
// set_up_tc: pointer to the function that sets up the test case // set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case // tear_down_tc: pointer to the function that tears down the test case
@ -573,7 +573,8 @@ typedef void (*TearDownTestCaseFunc)();
// ownership of the factory object. // ownership of the factory object.
GTEST_API_ TestInfo* MakeAndRegisterTestInfo( GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
const char* test_case_name, const char* name, const char* test_case_name, const char* name,
const char* test_case_comment, const char* comment, const char* type_param,
const char* value_param,
TypeId fixture_class_id, TypeId fixture_class_id,
SetUpTestCaseFunc set_up_tc, SetUpTestCaseFunc set_up_tc,
TearDownTestCaseFunc tear_down_tc, TearDownTestCaseFunc tear_down_tc,
@ -662,8 +663,8 @@ class TypeParameterizedTest {
String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/", String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/",
case_name, index).c_str(), case_name, index).c_str(),
GetPrefixUntilComma(test_names).c_str(), GetPrefixUntilComma(test_names).c_str(),
String::Format("TypeParam = %s", GetTypeName<Type>().c_str()).c_str(), GetTypeName<Type>().c_str(),
"", NULL, // No value parameter.
GetTypeId<FixtureClass>(), GetTypeId<FixtureClass>(),
TestClass::SetUpTestCase, TestClass::SetUpTestCase,
TestClass::TearDownTestCase, TestClass::TearDownTestCase,
@ -1197,7 +1198,7 @@ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\
::test_info_ =\ ::test_info_ =\
::testing::internal::MakeAndRegisterTestInfo(\ ::testing::internal::MakeAndRegisterTestInfo(\
#test_case_name, #test_name, "", "", \ #test_case_name, #test_name, NULL, NULL, \
(parent_id), \ (parent_id), \
parent_class::SetUpTestCase, \ parent_class::SetUpTestCase, \
parent_class::TearDownTestCase, \ parent_class::TearDownTestCase, \

View File

@ -505,12 +505,11 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
param_it != generator.end(); ++param_it, ++i) { param_it != generator.end(); ++param_it, ++i) {
Message test_name_stream; Message test_name_stream;
test_name_stream << test_info->test_base_name.c_str() << "/" << i; test_name_stream << test_info->test_base_name.c_str() << "/" << i;
std::string comment = "GetParam() = " + PrintToString(*param_it);
MakeAndRegisterTestInfo( MakeAndRegisterTestInfo(
test_case_name_stream.GetString().c_str(), test_case_name_stream.GetString().c_str(),
test_name_stream.GetString().c_str(), test_name_stream.GetString().c_str(),
"", // test_case_comment NULL, // No type parameter.
comment.c_str(), PrintToString(*param_it).c_str(),
GetTestCaseTypeId(), GetTestCaseTypeId(),
TestCase::SetUpTestCase, TestCase::SetUpTestCase,
TestCase::TearDownTestCase, TestCase::TearDownTestCase,

View File

@ -607,10 +607,12 @@ class GTEST_API_ UnitTestImpl {
// Arguments: // Arguments:
// //
// test_case_name: name of the test case // test_case_name: name of the test case
// type_param: the name of the test's type parameter, or NULL if
// this is not a typed or a type-parameterized test.
// set_up_tc: pointer to the function that sets up the test case // set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case // tear_down_tc: pointer to the function that tears down the test case
TestCase* GetTestCase(const char* test_case_name, TestCase* GetTestCase(const char* test_case_name,
const char* comment, const char* type_param,
Test::SetUpTestCaseFunc set_up_tc, Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc); Test::TearDownTestCaseFunc tear_down_tc);
@ -623,7 +625,7 @@ class GTEST_API_ UnitTestImpl {
// test_info: the TestInfo object // test_info: the TestInfo object
void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc, Test::TearDownTestCaseFunc tear_down_tc,
TestInfo * test_info) { TestInfo* test_info) {
// In order to support thread-safe death tests, we need to // In order to support thread-safe death tests, we need to
// remember the original working directory when the test program // remember the original working directory when the test program
// was first invoked. We cannot do this in RUN_ALL_TESTS(), as // was first invoked. We cannot do this in RUN_ALL_TESTS(), as
@ -638,7 +640,7 @@ class GTEST_API_ UnitTestImpl {
} }
GetTestCase(test_info->test_case_name(), GetTestCase(test_info->test_case_name(),
test_info->test_case_comment(), test_info->type_param(),
set_up_tc, set_up_tc,
tear_down_tc)->AddTestInfo(test_info); tear_down_tc)->AddTestInfo(test_info);
} }

View File

@ -2174,16 +2174,18 @@ bool Test::HasNonfatalFailure() {
// Constructs a TestInfo object. It assumes ownership of the test factory // Constructs a TestInfo object. It assumes ownership of the test factory
// object. // object.
// TODO(vladl@google.com): Make a_test_case_name and a_name const string&'s
// to signify they cannot be NULLs.
TestInfo::TestInfo(const char* a_test_case_name, TestInfo::TestInfo(const char* a_test_case_name,
const char* a_name, const char* a_name,
const char* a_test_case_comment, const char* a_type_param,
const char* a_comment, const char* a_value_param,
internal::TypeId fixture_class_id, internal::TypeId fixture_class_id,
internal::TestFactoryBase* factory) internal::TestFactoryBase* factory)
: test_case_name_(a_test_case_name), : test_case_name_(a_test_case_name),
name_(a_name), name_(a_name),
test_case_comment_(a_test_case_comment), type_param_(a_type_param ? new std::string(a_type_param) : NULL),
comment_(a_comment), value_param_(a_value_param ? new std::string(a_value_param) : NULL),
fixture_class_id_(fixture_class_id), fixture_class_id_(fixture_class_id),
should_run_(false), should_run_(false),
is_disabled_(false), is_disabled_(false),
@ -2203,10 +2205,10 @@ namespace internal {
// //
// test_case_name: name of the test case // test_case_name: name of the test case
// name: name of the test // name: name of the test
// test_case_comment: a comment on the test case that will be included in // type_param: the name of the test's type parameter, or NULL if
// the test output // this is not a typed or a type-parameterized test.
// comment: a comment on the test that will be included in the // value_param: text representation of the test's value parameter,
// test output // or NULL if this is not a value-parameterized test.
// fixture_class_id: ID of the test fixture class // fixture_class_id: ID of the test fixture class
// set_up_tc: pointer to the function that sets up the test case // set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case // tear_down_tc: pointer to the function that tears down the test case
@ -2215,13 +2217,14 @@ namespace internal {
// ownership of the factory object. // ownership of the factory object.
TestInfo* MakeAndRegisterTestInfo( TestInfo* MakeAndRegisterTestInfo(
const char* test_case_name, const char* name, const char* test_case_name, const char* name,
const char* test_case_comment, const char* comment, const char* type_param,
const char* value_param,
TypeId fixture_class_id, TypeId fixture_class_id,
SetUpTestCaseFunc set_up_tc, SetUpTestCaseFunc set_up_tc,
TearDownTestCaseFunc tear_down_tc, TearDownTestCaseFunc tear_down_tc,
TestFactoryBase* factory) { TestFactoryBase* factory) {
TestInfo* const test_info = TestInfo* const test_info =
new TestInfo(test_case_name, name, test_case_comment, comment, new TestInfo(test_case_name, name, type_param, value_param,
fixture_class_id, factory); fixture_class_id, factory);
GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
return test_info; return test_info;
@ -2370,13 +2373,15 @@ int TestCase::total_test_count() const {
// Arguments: // Arguments:
// //
// name: name of the test case // name: name of the test case
// a_type_param: the name of the test case's type parameter, or NULL if
// this is not a typed or a type-parameterized test case.
// set_up_tc: pointer to the function that sets up the test case // set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case // tear_down_tc: pointer to the function that tears down the test case
TestCase::TestCase(const char* a_name, const char* a_comment, TestCase::TestCase(const char* a_name, const char* a_type_param,
Test::SetUpTestCaseFunc set_up_tc, Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc) Test::TearDownTestCaseFunc tear_down_tc)
: name_(a_name), : name_(a_name),
comment_(a_comment), type_param_(a_type_param ? new std::string(a_type_param) : NULL),
set_up_tc_(set_up_tc), set_up_tc_(set_up_tc),
tear_down_tc_(tear_down_tc), tear_down_tc_(tear_down_tc),
should_run_(false), should_run_(false),
@ -2648,15 +2653,19 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) {
} }
void PrintFullTestCommentIfPresent(const TestInfo& test_info) { void PrintFullTestCommentIfPresent(const TestInfo& test_info) {
const char* const comment = test_info.comment(); const char* const type_param = test_info.type_param();
const char* const test_case_comment = test_info.test_case_comment(); const char* const value_param = test_info.value_param();
if (test_case_comment[0] != '\0' || comment[0] != '\0') { if (type_param != NULL || value_param != NULL) {
printf(", where %s", test_case_comment); printf(", where ");
if (test_case_comment[0] != '\0' && comment[0] != '\0') { if (type_param != NULL) {
printf(" and "); printf("TypeParam = %s", type_param);
if (value_param != NULL)
printf(" and ");
}
if (value_param != NULL) {
printf("GetParam() = %s", value_param);
} }
printf("%s", comment);
} }
} }
@ -2739,10 +2748,10 @@ void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
ColoredPrintf(COLOR_GREEN, "[----------] "); ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("%s from %s", counts.c_str(), test_case_name_.c_str()); printf("%s from %s", counts.c_str(), test_case_name_.c_str());
if (test_case.comment()[0] == '\0') { if (test_case.type_param() == NULL) {
printf("\n"); printf("\n");
} else { } else {
printf(", where %s\n", test_case.comment()); printf(", where TypeParam = %s\n", test_case.type_param());
} }
fflush(stdout); fflush(stdout);
} }
@ -3208,8 +3217,18 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
const TestInfo& test_info) { const TestInfo& test_info) {
const TestResult& result = *test_info.result(); const TestResult& result = *test_info.result();
*stream << " <testcase name=\"" *stream << " <testcase name=\""
<< EscapeXmlAttribute(test_info.name()).c_str() << EscapeXmlAttribute(test_info.name()).c_str() << "\"";
<< "\" status=\""
if (test_info.value_param() != NULL) {
*stream << " value_param=\"" << EscapeXmlAttribute(test_info.value_param())
<< "\"";
}
if (test_info.type_param() != NULL) {
*stream << " type_param=\"" << EscapeXmlAttribute(test_info.type_param())
<< "\"";
}
*stream << " status=\""
<< (test_info.should_run() ? "run" : "notrun") << (test_info.should_run() ? "run" : "notrun")
<< "\" time=\"" << "\" time=\""
<< FormatTimeInMillisAsSeconds(result.elapsed_time()) << FormatTimeInMillisAsSeconds(result.elapsed_time())
@ -4059,10 +4078,12 @@ class TestCaseNameIs {
// Arguments: // Arguments:
// //
// test_case_name: name of the test case // test_case_name: name of the test case
// type_param: the name of the test case's type parameter, or NULL if
// this is not a typed or a type-parameterized test case.
// set_up_tc: pointer to the function that sets up the test case // set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case // tear_down_tc: pointer to the function that tears down the test case
TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
const char* comment, const char* type_param,
Test::SetUpTestCaseFunc set_up_tc, Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc) { Test::TearDownTestCaseFunc tear_down_tc) {
// Can we find a TestCase with the given name? // Can we find a TestCase with the given name?
@ -4075,7 +4096,7 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
// No. Let's create one. // No. Let's create one.
TestCase* const new_test_case = TestCase* const new_test_case =
new TestCase(test_case_name, comment, set_up_tc, tear_down_tc); new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc);
// Is this a death test case? // Is this a death test case?
if (internal::UnitTestOptions::MatchesFilter(String(test_case_name), if (internal::UnitTestOptions::MatchesFilter(String(test_case_name),

View File

@ -792,19 +792,17 @@ INSTANTIATE_TEST_CASE_P(FourElemSequence, SeparateInstanceTest, Range(1, 4));
// sequence element used to instantiate the test. // sequence element used to instantiate the test.
class NamingTest : public TestWithParam<int> {}; class NamingTest : public TestWithParam<int> {};
TEST_P(NamingTest, TestsAreNamedAndCommentedCorrectly) { TEST_P(NamingTest, TestsReportCorrectNamesAndParameters) {
const ::testing::TestInfo* const test_info = const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info(); ::testing::UnitTest::GetInstance()->current_test_info();
EXPECT_STREQ("ZeroToFiveSequence/NamingTest", test_info->test_case_name()); EXPECT_STREQ("ZeroToFiveSequence/NamingTest", test_info->test_case_name());
Message index_stream; Message index_stream;
index_stream << "TestsAreNamedAndCommentedCorrectly/" << GetParam(); index_stream << "TestsReportCorrectNamesAndParameters/" << GetParam();
EXPECT_STREQ(index_stream.GetString().c_str(), test_info->name()); EXPECT_STREQ(index_stream.GetString().c_str(), test_info->name());
const ::std::string comment = EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param());
"GetParam() = " + ::testing::PrintToString(GetParam());
EXPECT_EQ(comment, test_info->comment());
} }
INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5)); INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5));
@ -823,13 +821,11 @@ class Unstreamable {
class CommentTest : public TestWithParam<Unstreamable> {}; class CommentTest : public TestWithParam<Unstreamable> {};
TEST_P(CommentTest, TestsWithUnstreamableParamsCommentedCorrectly) { TEST_P(CommentTest, TestsCorrectlyReportUnstreamableParams) {
const ::testing::TestInfo* const test_info = const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info(); ::testing::UnitTest::GetInstance()->current_test_info();
const ::std::string comment = EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param());
"GetParam() = " + ::testing::PrintToString(GetParam());
EXPECT_EQ(comment, test_info->comment());
} }
INSTANTIATE_TEST_CASE_P(InstantiationWithComments, INSTANTIATE_TEST_CASE_P(InstantiationWithComments,

View File

@ -37,6 +37,7 @@
#include <string.h> // For strcmp. #include <string.h> // For strcmp.
#include <algorithm> #include <algorithm>
#include <sstream>
using ::testing::InitGoogleTest; using ::testing::InitGoogleTest;
@ -103,12 +104,6 @@ TYPED_TEST(TestCaseWithCommentTest, Dummy) {}
const int kTypedTestCases = 1; const int kTypedTestCases = 1;
const int kTypedTests = 1; const int kTypedTests = 1;
String GetExpectedTestCaseComment() {
Message comment;
comment << "TypeParam = " << GetTypeName<int>().c_str();
return comment.GetString();
}
#else #else
const int kTypedTestCases = 0; const int kTypedTestCases = 0;
const int kTypedTests = 0; const int kTypedTests = 0;
@ -143,12 +138,19 @@ TEST(ApiTest, UnitTestImmutableAccessorsWork) {
RecordProperty("key", "value"); RecordProperty("key", "value");
} }
AssertionResult IsNull(const char* str) {
if (str != NULL) {
return testing::AssertionFailure() << "argument is " << str;
}
return AssertionSuccess();
}
TEST(ApiTest, TestCaseImmutableAccessorsWork) { TEST(ApiTest, TestCaseImmutableAccessorsWork) {
const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest"); const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest");
ASSERT_TRUE(test_case != NULL); ASSERT_TRUE(test_case != NULL);
EXPECT_STREQ("ApiTest", test_case->name()); EXPECT_STREQ("ApiTest", test_case->name());
EXPECT_STREQ("", test_case->comment()); EXPECT_TRUE(IsNull(test_case->type_param()));
EXPECT_TRUE(test_case->should_run()); EXPECT_TRUE(test_case->should_run());
EXPECT_EQ(1, test_case->disabled_test_count()); EXPECT_EQ(1, test_case->disabled_test_count());
EXPECT_EQ(3, test_case->test_to_run_count()); EXPECT_EQ(3, test_case->test_to_run_count());
@ -158,26 +160,26 @@ TEST(ApiTest, TestCaseImmutableAccessorsWork) {
EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name()); EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name());
EXPECT_STREQ("ApiTest", tests[0]->test_case_name()); EXPECT_STREQ("ApiTest", tests[0]->test_case_name());
EXPECT_STREQ("", tests[0]->comment()); EXPECT_TRUE(IsNull(tests[0]->value_param()));
EXPECT_STREQ("", tests[0]->test_case_comment()); EXPECT_TRUE(IsNull(tests[0]->type_param()));
EXPECT_FALSE(tests[0]->should_run()); EXPECT_FALSE(tests[0]->should_run());
EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name()); EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name());
EXPECT_STREQ("ApiTest", tests[1]->test_case_name()); EXPECT_STREQ("ApiTest", tests[1]->test_case_name());
EXPECT_STREQ("", tests[1]->comment()); EXPECT_TRUE(IsNull(tests[1]->value_param()));
EXPECT_STREQ("", tests[1]->test_case_comment()); EXPECT_TRUE(IsNull(tests[1]->type_param()));
EXPECT_TRUE(tests[1]->should_run()); EXPECT_TRUE(tests[1]->should_run());
EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name()); EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name());
EXPECT_STREQ("ApiTest", tests[2]->test_case_name()); EXPECT_STREQ("ApiTest", tests[2]->test_case_name());
EXPECT_STREQ("", tests[2]->comment()); EXPECT_TRUE(IsNull(tests[2]->value_param()));
EXPECT_STREQ("", tests[2]->test_case_comment()); EXPECT_TRUE(IsNull(tests[2]->type_param()));
EXPECT_TRUE(tests[2]->should_run()); EXPECT_TRUE(tests[2]->should_run());
EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name()); EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name());
EXPECT_STREQ("ApiTest", tests[3]->test_case_name()); EXPECT_STREQ("ApiTest", tests[3]->test_case_name());
EXPECT_STREQ("", tests[3]->comment()); EXPECT_TRUE(IsNull(tests[3]->value_param()));
EXPECT_STREQ("", tests[3]->test_case_comment()); EXPECT_TRUE(IsNull(tests[3]->type_param()));
EXPECT_TRUE(tests[3]->should_run()); EXPECT_TRUE(tests[3]->should_run());
delete[] tests; delete[] tests;
@ -188,7 +190,7 @@ TEST(ApiTest, TestCaseImmutableAccessorsWork) {
ASSERT_TRUE(test_case != NULL); ASSERT_TRUE(test_case != NULL);
EXPECT_STREQ("TestCaseWithCommentTest/0", test_case->name()); EXPECT_STREQ("TestCaseWithCommentTest/0", test_case->name());
EXPECT_STREQ(GetExpectedTestCaseComment().c_str(), test_case->comment()); EXPECT_STREQ(GetTypeName<int>().c_str(), test_case->type_param());
EXPECT_TRUE(test_case->should_run()); EXPECT_TRUE(test_case->should_run());
EXPECT_EQ(0, test_case->disabled_test_count()); EXPECT_EQ(0, test_case->disabled_test_count());
EXPECT_EQ(1, test_case->test_to_run_count()); EXPECT_EQ(1, test_case->test_to_run_count());
@ -198,9 +200,8 @@ TEST(ApiTest, TestCaseImmutableAccessorsWork) {
EXPECT_STREQ("Dummy", tests[0]->name()); EXPECT_STREQ("Dummy", tests[0]->name());
EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name());
EXPECT_STREQ("", tests[0]->comment()); EXPECT_TRUE(IsNull(tests[0]->value_param()));
EXPECT_STREQ(GetExpectedTestCaseComment().c_str(), EXPECT_STREQ(GetTypeName<int>().c_str(), tests[0]->type_param());
tests[0]->test_case_comment());
EXPECT_TRUE(tests[0]->should_run()); EXPECT_TRUE(tests[0]->should_run());
delete[] tests; delete[] tests;
@ -212,7 +213,7 @@ TEST(ApiTest, TestCaseDisabledAccessorsWork) {
ASSERT_TRUE(test_case != NULL); ASSERT_TRUE(test_case != NULL);
EXPECT_STREQ("DISABLED_Test", test_case->name()); EXPECT_STREQ("DISABLED_Test", test_case->name());
EXPECT_STREQ("", test_case->comment()); EXPECT_TRUE(IsNull(test_case->type_param()));
EXPECT_FALSE(test_case->should_run()); EXPECT_FALSE(test_case->should_run());
EXPECT_EQ(1, test_case->disabled_test_count()); EXPECT_EQ(1, test_case->disabled_test_count());
EXPECT_EQ(0, test_case->test_to_run_count()); EXPECT_EQ(0, test_case->test_to_run_count());
@ -221,8 +222,8 @@ TEST(ApiTest, TestCaseDisabledAccessorsWork) {
const TestInfo* const test_info = test_case->GetTestInfo(0); const TestInfo* const test_info = test_case->GetTestInfo(0);
EXPECT_STREQ("Dummy2", test_info->name()); EXPECT_STREQ("Dummy2", test_info->name());
EXPECT_STREQ("DISABLED_Test", test_info->test_case_name()); EXPECT_STREQ("DISABLED_Test", test_info->test_case_name());
EXPECT_STREQ("", test_info->comment()); EXPECT_TRUE(IsNull(test_info->value_param()));
EXPECT_STREQ("", test_info->test_case_comment()); EXPECT_TRUE(IsNull(test_info->type_param()));
EXPECT_FALSE(test_info->should_run()); EXPECT_FALSE(test_info->should_run());
} }
@ -247,7 +248,7 @@ class FinalSuccessChecker : public Environment {
const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases(); const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases();
EXPECT_STREQ("ApiTest", test_cases[0]->name()); EXPECT_STREQ("ApiTest", test_cases[0]->name());
EXPECT_STREQ("", test_cases[0]->comment()); EXPECT_TRUE(IsNull(test_cases[0]->type_param()));
EXPECT_TRUE(test_cases[0]->should_run()); EXPECT_TRUE(test_cases[0]->should_run());
EXPECT_EQ(1, test_cases[0]->disabled_test_count()); EXPECT_EQ(1, test_cases[0]->disabled_test_count());
ASSERT_EQ(4, test_cases[0]->total_test_count()); ASSERT_EQ(4, test_cases[0]->total_test_count());
@ -257,7 +258,7 @@ class FinalSuccessChecker : public Environment {
EXPECT_FALSE(test_cases[0]->Failed()); EXPECT_FALSE(test_cases[0]->Failed());
EXPECT_STREQ("DISABLED_Test", test_cases[1]->name()); EXPECT_STREQ("DISABLED_Test", test_cases[1]->name());
EXPECT_STREQ("", test_cases[1]->comment()); EXPECT_TRUE(IsNull(test_cases[1]->type_param()));
EXPECT_FALSE(test_cases[1]->should_run()); EXPECT_FALSE(test_cases[1]->should_run());
EXPECT_EQ(1, test_cases[1]->disabled_test_count()); EXPECT_EQ(1, test_cases[1]->disabled_test_count());
ASSERT_EQ(1, test_cases[1]->total_test_count()); ASSERT_EQ(1, test_cases[1]->total_test_count());
@ -266,8 +267,7 @@ class FinalSuccessChecker : public Environment {
#if GTEST_HAS_TYPED_TEST #if GTEST_HAS_TYPED_TEST
EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name()); EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name());
EXPECT_STREQ(GetExpectedTestCaseComment().c_str(), EXPECT_STREQ(GetTypeName<int>().c_str(), test_cases[2]->type_param());
test_cases[2]->comment());
EXPECT_TRUE(test_cases[2]->should_run()); EXPECT_TRUE(test_cases[2]->should_run());
EXPECT_EQ(0, test_cases[2]->disabled_test_count()); EXPECT_EQ(0, test_cases[2]->disabled_test_count());
ASSERT_EQ(1, test_cases[2]->total_test_count()); ASSERT_EQ(1, test_cases[2]->total_test_count());
@ -285,24 +285,24 @@ class FinalSuccessChecker : public Environment {
EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name()); EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name());
EXPECT_STREQ("ApiTest", tests[1]->test_case_name()); EXPECT_STREQ("ApiTest", tests[1]->test_case_name());
EXPECT_STREQ("", tests[1]->comment()); EXPECT_TRUE(IsNull(tests[1]->value_param()));
EXPECT_STREQ("", tests[1]->test_case_comment()); EXPECT_TRUE(IsNull(tests[1]->type_param()));
EXPECT_TRUE(tests[1]->should_run()); EXPECT_TRUE(tests[1]->should_run());
EXPECT_TRUE(tests[1]->result()->Passed()); EXPECT_TRUE(tests[1]->result()->Passed());
EXPECT_EQ(0, tests[1]->result()->test_property_count()); EXPECT_EQ(0, tests[1]->result()->test_property_count());
EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name()); EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name());
EXPECT_STREQ("ApiTest", tests[2]->test_case_name()); EXPECT_STREQ("ApiTest", tests[2]->test_case_name());
EXPECT_STREQ("", tests[2]->comment()); EXPECT_TRUE(IsNull(tests[2]->value_param()));
EXPECT_STREQ("", tests[2]->test_case_comment()); EXPECT_TRUE(IsNull(tests[2]->type_param()));
EXPECT_TRUE(tests[2]->should_run()); EXPECT_TRUE(tests[2]->should_run());
EXPECT_TRUE(tests[2]->result()->Passed()); EXPECT_TRUE(tests[2]->result()->Passed());
EXPECT_EQ(0, tests[2]->result()->test_property_count()); EXPECT_EQ(0, tests[2]->result()->test_property_count());
EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name()); EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name());
EXPECT_STREQ("ApiTest", tests[3]->test_case_name()); EXPECT_STREQ("ApiTest", tests[3]->test_case_name());
EXPECT_STREQ("", tests[3]->comment()); EXPECT_TRUE(IsNull(tests[3]->value_param()));
EXPECT_STREQ("", tests[3]->test_case_comment()); EXPECT_TRUE(IsNull(tests[3]->type_param()));
EXPECT_TRUE(tests[3]->should_run()); EXPECT_TRUE(tests[3]->should_run());
EXPECT_TRUE(tests[3]->result()->Passed()); EXPECT_TRUE(tests[3]->result()->Passed());
EXPECT_EQ(1, tests[3]->result()->test_property_count()); EXPECT_EQ(1, tests[3]->result()->test_property_count());
@ -318,9 +318,8 @@ class FinalSuccessChecker : public Environment {
EXPECT_STREQ("Dummy", tests[0]->name()); EXPECT_STREQ("Dummy", tests[0]->name());
EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name()); EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name());
EXPECT_STREQ("", tests[0]->comment()); EXPECT_TRUE(IsNull(tests[0]->value_param()));
EXPECT_STREQ(GetExpectedTestCaseComment().c_str(), EXPECT_STREQ(GetTypeName<int>().c_str(), tests[0]->type_param());
tests[0]->test_case_comment());
EXPECT_TRUE(tests[0]->should_run()); EXPECT_TRUE(tests[0]->should_run());
EXPECT_TRUE(tests[0]->result()->Passed()); EXPECT_TRUE(tests[0]->result()->Passed());
EXPECT_EQ(0, tests[0]->result()->test_property_count()); EXPECT_EQ(0, tests[0]->result()->test_property_count());

View File

@ -54,7 +54,7 @@ else:
STACK_TRACE_TEMPLATE = "" STACK_TRACE_TEMPLATE = ""
EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?> EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="15" failures="4" disabled="2" errors="0" time="*" name="AllTests"> <testsuites tests="23" failures="4" disabled="2" errors="0" time="*" name="AllTests">
<testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*"> <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/> <testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
</testsuite> </testsuite>
@ -105,6 +105,24 @@ Invalid characters in brackets []%(stack)s]]></failure>
<testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_int="1"/> <testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_int="1"/>
<testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_string="1"/> <testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_string="1"/>
</testsuite> </testsuite>
<testsuite name="Single/ValueParamTest" tests="4" failures="0" disabled="0" errors="0" time="*">
<testcase name="HasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" />
<testcase name="HasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" />
<testcase name="AnotherTestThatHasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" />
<testcase name="AnotherTestThatHasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" />
</testsuite>
<testsuite name="TypedTest/0" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="TypedTest/0" />
</testsuite>
<testsuite name="TypedTest/1" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="TypedTest/1" />
</testsuite>
<testsuite name="Single/TypeParameterizedTestCase/0" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="Single/TypeParameterizedTestCase/0" />
</testsuite>
<testsuite name="Single/TypeParameterizedTestCase/1" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="HasTypeParamAttribute" type_param="*" status="run" time="*" classname="Single/TypeParameterizedTestCase/1" />
</testsuite>
</testsuites>""" % {'stack': STACK_TRACE_TEMPLATE} </testsuites>""" % {'stack': STACK_TRACE_TEMPLATE}

View File

@ -42,9 +42,13 @@
using ::testing::InitGoogleTest; using ::testing::InitGoogleTest;
using ::testing::TestEventListeners; using ::testing::TestEventListeners;
using ::testing::TestWithParam;
using ::testing::UnitTest; using ::testing::UnitTest;
using ::testing::Test;
using ::testing::Types;
using ::testing::Values;
class SuccessfulTest : public testing::Test { class SuccessfulTest : public Test {
}; };
TEST_F(SuccessfulTest, Succeeds) { TEST_F(SuccessfulTest, Succeeds) {
@ -52,14 +56,14 @@ TEST_F(SuccessfulTest, Succeeds) {
ASSERT_EQ(1, 1); ASSERT_EQ(1, 1);
} }
class FailedTest : public testing::Test { class FailedTest : public Test {
}; };
TEST_F(FailedTest, Fails) { TEST_F(FailedTest, Fails) {
ASSERT_EQ(1, 2); ASSERT_EQ(1, 2);
} }
class DisabledTest : public testing::Test { class DisabledTest : public Test {
}; };
TEST_F(DisabledTest, DISABLED_test_not_run) { TEST_F(DisabledTest, DISABLED_test_not_run) {
@ -91,7 +95,7 @@ TEST(InvalidCharactersTest, InvalidCharactersInMessage) {
FAIL() << "Invalid characters in brackets [\x1\x2]"; FAIL() << "Invalid characters in brackets [\x1\x2]";
} }
class PropertyRecordingTest : public testing::Test { class PropertyRecordingTest : public Test {
}; };
TEST_F(PropertyRecordingTest, OneProperty) { TEST_F(PropertyRecordingTest, OneProperty) {
@ -134,6 +138,31 @@ TEST(NoFixtureTest, ExternalUtilityThatCallsRecordStringValuedProperty) {
ExternalUtilityThatCallsRecordProperty("key_for_utility_string", "1"); ExternalUtilityThatCallsRecordProperty("key_for_utility_string", "1");
} }
// Verifies that the test parameter value is output in the 'value_param'
// XML attribute for value-parameterized tests.
class ValueParamTest : public TestWithParam<int> {};
TEST_P(ValueParamTest, HasValueParamAttribute) {}
TEST_P(ValueParamTest, AnotherTestThatHasValueParamAttribute) {}
INSTANTIATE_TEST_CASE_P(Single, ValueParamTest, Values(33, 42));
// Verifies that the type parameter name is output in the 'type_param'
// XML attribute for typed tests.
template <typename T> class TypedTest : public Test {};
typedef Types<int, long> TypedTestTypes;
TYPED_TEST_CASE(TypedTest, TypedTestTypes);
TYPED_TEST(TypedTest, HasTypeParamAttribute) {}
// Verifies that the type parameter name is output in the 'type_param'
// XML attribute for type-parameterized tests.
template <typename T> class TypeParameterizedTestCase : public Test {};
TYPED_TEST_CASE_P(TypeParameterizedTestCase);
TYPED_TEST_P(TypeParameterizedTestCase, HasTypeParamAttribute) {}
REGISTER_TYPED_TEST_CASE_P(TypeParameterizedTestCase, HasTypeParamAttribute);
typedef Types<int, long> TypeParameterizedTestCaseTypes;
INSTANTIATE_TYPED_TEST_CASE_P(Single,
TypeParameterizedTestCase,
TypeParameterizedTestCaseTypes);
int main(int argc, char** argv) { int main(int argc, char** argv) {
InitGoogleTest(&argc, argv); InitGoogleTest(&argc, argv);

View File

@ -58,8 +58,9 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
* It has the same tag name as expected_node. * It has the same tag name as expected_node.
* It has the same set of attributes as expected_node, each with * It has the same set of attributes as expected_node, each with
the same value as the corresponding attribute of expected_node. the same value as the corresponding attribute of expected_node.
An exception is any attribute named "time", which needs only be Exceptions are any attribute named "time", which needs only be
convertible to a floating-point number. convertible to a floating-point number and any attribute named
"type_param" which only has to be non-empty.
* It has an equivalent set of child nodes (including elements and * It has an equivalent set of child nodes (including elements and
CDATA sections) as expected_node. Note that we ignore the CDATA sections) as expected_node. Note that we ignore the
order of the children as they are not guaranteed to be in any order of the children as they are not guaranteed to be in any
@ -150,6 +151,9 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
* The "time" attribute of <testsuites>, <testsuite> and <testcase> * The "time" attribute of <testsuites>, <testsuite> and <testcase>
elements is replaced with a single asterisk, if it contains elements is replaced with a single asterisk, if it contains
only digit characters. only digit characters.
* The "type_param" attribute of <testcase> elements is replaced with a
single asterisk (if it sn non-empty) as it is the type name returned
by the compiler and is platform dependent.
* The line number reported in the first line of the "message" * The line number reported in the first line of the "message"
attribute of <failure> elements is replaced with a single asterisk. attribute of <failure> elements is replaced with a single asterisk.
* The directory names in file paths are removed. * The directory names in file paths are removed.
@ -159,6 +163,9 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
if element.tagName in ("testsuites", "testsuite", "testcase"): if element.tagName in ("testsuites", "testsuite", "testcase"):
time = element.getAttributeNode("time") time = element.getAttributeNode("time")
time.value = re.sub(r"^\d+(\.\d+)?$", "*", time.value) time.value = re.sub(r"^\d+(\.\d+)?$", "*", time.value)
type_param = element.getAttributeNode("type_param")
if type_param and type_param.value:
type_param.value = "*"
elif element.tagName == "failure": elif element.tagName == "failure":
for child in element.childNodes: for child in element.childNodes:
if child.nodeType == Node.CDATA_SECTION_NODE: if child.nodeType == Node.CDATA_SECTION_NODE: