summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2010-12-06 22:18:59 +0000
committerzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2010-12-06 22:18:59 +0000
commit71874246c3a054977d94fd4729576484c2af62e9 (patch)
tree2995f382edd65f2a7e095a8868d45f22cb60d063
parenta8c1fdfb00d6f1751e119f5632a38b0498a8c1a7 (diff)
downloadgtest-71874246c3a054977d94fd4729576484c2af62e9.tar.gz
gtest-71874246c3a054977d94fd4729576484c2af62e9.tar.bz2
gtest-71874246c3a054977d94fd4729576484c2af62e9.tar.xz
Allows a value-parameterized test fixture to derive from Test and WithParamInterface<T> separately; contributed by Matt Austern.
git-svn-id: http://googletest.googlecode.com/svn/trunk@526 861a406c-534a-0410-8894-cb66d6ee9925
-rw-r--r--include/gtest/gtest-param-test.h40
-rw-r--r--include/gtest/gtest-param-test.h.pump45
-rw-r--r--include/gtest/gtest.h27
-rw-r--r--test/gtest-param-test_test.cc33
4 files changed, 127 insertions, 18 deletions
diff --git a/include/gtest/gtest-param-test.h b/include/gtest/gtest-param-test.h
index fb6ec8f..9a92303 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<T>, where T is
-// the type of your parameter values. TestWithParam<T> 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<T> (see below for
+// another inheritance scheme that's sometimes useful in more complicated
+// class hierarchies), where the type of your parameter values.
+// TestWithParam<T> 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<const char*> {
// 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<T>, where T is the type of the parameter
+// values. Inheriting from TestWithParam<T> satisfies that requirement because
+// TestWithParam<T> 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<int> {
+ // 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 cff9972..d73f24d 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<T>, where T is
-// the type of your parameter values. TestWithParam<T> 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<T> (see below for
+// another inheritance scheme that's sometimes useful in more complicated
+// class hierarchies), where the type of your parameter values.
+// TestWithParam<T> 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<const char*> {
// 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<T>, where T is the type of the parameter
+// values. Inheriting from TestWithParam<T> satisfies that requirement because
+// TestWithParam<T> 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<int> {
+ // 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 6ce58d7..f7ed948 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 <typename T>
-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<bool>::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<T>.
+ // TestClass must be a subclass of WithParamInterface<T> and Test.
template <class TestClass> friend class internal::ParameterizedTestFactory;
};
template <typename T>
-const T* TestWithParam<T>::parameter_ = NULL;
+const T* WithParamInterface<T>::parameter_ = NULL;
+
+// Most value-parameterized classes can ignore the existence of
+// WithParamInterface, and can just inherit from ::testing::TestWithParam.
+
+template <typename T>
+class TestWithParam : public Test, public WithParamInterface<T> {
+};
#endif // GTEST_HAS_PARAM_TEST
diff --git a/test/gtest-param-test_test.cc b/test/gtest-param-test_test.cc
index c920f4f..acd269b 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<int> {
+ 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) {