diff --git a/include/gtest/gtest-param-test.h b/include/gtest/gtest-param-test.h index fb6ec8f5..9a92303b 100644 --- a/include/gtest/gtest-param-test.h +++ b/include/gtest/gtest-param-test.h @@ -1,4 +1,6 @@ -// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! +// This file was GENERATED by command: +// pump.py gtest-param-test.h.pump +// DO NOT EDIT BY HAND!!! // Copyright 2008, Google Inc. // All rights reserved. @@ -48,10 +50,12 @@ #if 0 // To write value-parameterized tests, first you should define a fixture -// class. It must be derived from testing::TestWithParam, where T is -// the type of your parameter values. TestWithParam is itself derived -// from testing::Test. T can be any copyable type. If it's a raw pointer, -// you are responsible for managing the lifespan of the pointed values. +// class. It is usually derived from testing::TestWithParam (see below for +// another inheritance scheme that's sometimes useful in more complicated +// class hierarchies), where the type of your parameter values. +// TestWithParam is itself derived from testing::Test. T can be any +// copyable type. If it's a raw pointer, you are responsible for managing the +// lifespan of the pointed values. class FooTest : public ::testing::TestWithParam { // You can implement all the usual class fixture members here. @@ -146,6 +150,32 @@ INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); // In the future, we plan to publish the API for defining new parameter // generators. But for now this interface remains part of the internal // implementation and is subject to change. +// +// +// A parameterized test fixture must be derived from testing::Test and from +// testing::WithParamInterface, where T is the type of the parameter +// values. Inheriting from TestWithParam satisfies that requirement because +// TestWithParam inherits from both Test and WithParamInterface. In more +// complicated hierarchies, however, it is occasionally useful to inherit +// separately from Test and WithParamInterface. For example: + +class BaseTest : public ::testing::Test { + // You can inherit all the usual members for a non-parameterized test + // fixture here. +}; + +class DerivedTest : public BaseTest, public ::testing::WithParamInterface { + // The usual test fixture members go here too. +}; + +TEST_F(BaseTest, HasFoo) { + // This is an ordinary non-parameterized test. +} + +TEST_P(DerivedTest, DoesBlah) { + // GetParam works just the same here as if you inherit from TestWithParam. + EXPECT_TRUE(foo.Blah(GetParam())); +} #endif // 0 diff --git a/include/gtest/gtest-param-test.h.pump b/include/gtest/gtest-param-test.h.pump index cff9972d..d73f24dc 100644 --- a/include/gtest/gtest-param-test.h.pump +++ b/include/gtest/gtest-param-test.h.pump @@ -49,10 +49,12 @@ $var maxtuple = 10 $$ Maximum number of Combine arguments we want to support. #if 0 // To write value-parameterized tests, first you should define a fixture -// class. It must be derived from testing::TestWithParam, where T is -// the type of your parameter values. TestWithParam is itself derived -// from testing::Test. T can be any copyable type. If it's a raw pointer, -// you are responsible for managing the lifespan of the pointed values. +// class. It is usually derived from testing::TestWithParam (see below for +// another inheritance scheme that's sometimes useful in more complicated +// class hierarchies), where the type of your parameter values. +// TestWithParam is itself derived from testing::Test. T can be any +// copyable type. If it's a raw pointer, you are responsible for managing the +// lifespan of the pointed values. class FooTest : public ::testing::TestWithParam { // You can implement all the usual class fixture members here. @@ -134,9 +136,12 @@ INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); // in the given test case, whether their definitions come before or // AFTER the INSTANTIATE_TEST_CASE_P statement. // -// Please also note that generator expressions are evaluated in -// RUN_ALL_TESTS(), after main() has started. This allows evaluation of -// parameter list based on command line parameters. +// Please also note that generator expressions (including parameters to the +// generators) are evaluated in InitGoogleTest(), after main() has started. +// This allows the user on one hand, to adjust generator parameters in order +// to dynamically determine a set of tests to run and on the other hand, +// give the user a chance to inspect the generated tests with Google Test +// reflection API before RUN_ALL_TESTS() is executed. // // You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc // for more examples. @@ -144,6 +149,32 @@ INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); // In the future, we plan to publish the API for defining new parameter // generators. But for now this interface remains part of the internal // implementation and is subject to change. +// +// +// A parameterized test fixture must be derived from testing::Test and from +// testing::WithParamInterface, where T is the type of the parameter +// values. Inheriting from TestWithParam satisfies that requirement because +// TestWithParam inherits from both Test and WithParamInterface. In more +// complicated hierarchies, however, it is occasionally useful to inherit +// separately from Test and WithParamInterface. For example: + +class BaseTest : public ::testing::Test { + // You can inherit all the usual members for a non-parameterized test + // fixture here. +}; + +class DerivedTest : public BaseTest, public ::testing::WithParamInterface { + // The usual test fixture members go here too. +}; + +TEST_F(BaseTest, HasFoo) { + // This is an ordinary non-parameterized test. +} + +TEST_P(DerivedTest, DoesBlah) { + // GetParam works just the same here as if you inherit from TestWithParam. + EXPECT_TRUE(foo.Blah(GetParam())); +} #endif // 0 diff --git a/include/gtest/gtest.h b/include/gtest/gtest.h index 6ce58d72..f7ed948b 100644 --- a/include/gtest/gtest.h +++ b/include/gtest/gtest.h @@ -1589,9 +1589,13 @@ class GTEST_API_ AssertHelper { } // namespace internal #if GTEST_HAS_PARAM_TEST -// The abstract base class that all value-parameterized tests inherit from. +// The pure interface class that all value-parameterized tests inherit from. +// A value-parameterized class must inherit from both ::testing::Test and +// ::testing::WithParamInterface. In most cases that just means inheriting +// from ::testing::TestWithParam, but more complicated test hierarchies +// may need to inherit from Test and WithParamInterface at different levels. // -// This class adds support for accessing the test parameter value via +// This interface has support for accessing the test parameter value via // the GetParam() method. // // Use it with one of the parameter generator defining functions, like Range(), @@ -1620,12 +1624,16 @@ class GTEST_API_ AssertHelper { // INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); template -class TestWithParam : public Test { +class WithParamInterface { public: typedef T ParamType; + virtual ~WithParamInterface() {} // The current parameter value. Is also available in the test fixture's - // constructor. + // constructor. This member function is non-static, even though it only + // references static data, to reduce the opportunity for incorrect uses + // like writing 'WithParamInterface::GetParam()' for a test that + // uses a fixture whose parameter type is int. const ParamType& GetParam() const { return *parameter_; } private: @@ -1638,12 +1646,19 @@ class TestWithParam : public Test { // Static value used for accessing parameter during a test lifetime. static const ParamType* parameter_; - // TestClass must be a subclass of TestWithParam. + // TestClass must be a subclass of WithParamInterface and Test. template friend class internal::ParameterizedTestFactory; }; template -const T* TestWithParam::parameter_ = NULL; +const T* WithParamInterface::parameter_ = NULL; + +// Most value-parameterized classes can ignore the existence of +// WithParamInterface, and can just inherit from ::testing::TestWithParam. + +template +class TestWithParam : public Test, public WithParamInterface { +}; #endif // GTEST_HAS_PARAM_TEST diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc index c920f4fd..acd269bc 100644 --- a/test/gtest-param-test_test.cc +++ b/test/gtest-param-test_test.cc @@ -836,6 +836,39 @@ INSTANTIATE_TEST_CASE_P(InstantiationWithComments, CommentTest, Values(Unstreamable(1))); +// Verify that we can create a hierarchy of test fixtures, where the base +// class fixture is not parameterized and the derived class is. In this case +// ParameterizedDerivedTest inherits from NonParameterizedBaseTest. We +// perform simple tests on both. +class NonParameterizedBaseTest : public ::testing::Test { + public: + NonParameterizedBaseTest() : n_(17) { } + protected: + int n_; +}; + +class ParameterizedDerivedTest : public NonParameterizedBaseTest, + public ::testing::WithParamInterface { + protected: + ParameterizedDerivedTest() : count_(0) { } + int count_; + static int global_count_; +}; + +int ParameterizedDerivedTest::global_count_ = 0; + +TEST_F(NonParameterizedBaseTest, FixtureIsInitialized) { + EXPECT_EQ(17, n_); +} + +TEST_P(ParameterizedDerivedTest, SeesSequence) { + EXPECT_EQ(17, n_); + EXPECT_EQ(0, count_++); + EXPECT_EQ(GetParam(), global_count_++); +} + +INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5)); + #endif // GTEST_HAS_PARAM_TEST TEST(CompileTest, CombineIsDefinedOnlyWhenGtestHasParamTestIsDefined) {