# How to Write Parameterized Tests in GoogleTest: A Complete Guide with Examples

> Master parameterized tests in GoogleTest. Learn to write value and type parameterized tests using TEST_P and TYPED_TEST_P for efficient, reusable test logic across diverse data and types. Get the complete guide now.

- Repository: [Google/googletest](https://github.com/google/googletest)
- Tags: how-to-guide
- Published: 2026-09-01

---

**Use `TEST_P` with `INSTANTIATE_TEST_SUITE_P` for value-parameterized tests and `TYPED_TEST_P` with `REGISTER_TYPED_TEST_SUITE_P` for type-parameterized tests**, inheriting from `::testing::TestWithParam<T>` or template fixtures respectively to execute identical test logic across varying data sets or C++ types.

GoogleTest (gtest) provides a robust framework for data-driven testing through its parameterized test API, eliminating code duplication when validating logic against multiple inputs or type implementations. The implementation resides in the `google/googletest` repository, where macros defined in [`googletest/include/gtest/gtest-param-test.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/gtest-param-test.h) and [`googletest/include/gtest/gtest-typed-test.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/gtest-typed-test.h) drive value-based and type-based parameterization. Understanding how to write parameterized tests in GoogleTest requires familiarity with fixture inheritance, parameter generators, and the internal registration mechanisms managed by [`gtest-param-util.h`](https://github.com/google/googletest/blob/main/gtest-param-util.h).

## Understanding GoogleTest Parameterized Test Types

GoogleTest distinguishes between two primary parameterized testing strategies. **Value-parameterized tests** use `TEST_P` macros to iterate over concrete runtime values such as integers, strings, or factory functions. **Type-parameterized tests** employ `TYPED_TEST_P` to instantiate test code across different C++ types for validating template-based implementations.

The value-parameterized API resides in [`googletest/include/gtest/gtest-param-test.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/gtest-param-test.h), while type-parameterized functionality lives in [`googletest/include/gtest/gtest-typed-test.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/gtest-typed-test.h). Under the hood, both delegate to internal utilities in [`googletest/include/gtest/internal/gtest-param-util.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/internal/gtest-param-util.h), which manages test pattern storage through classes like `ParameterizedTestSuiteInfo` and drives instantiation during `TestSuite::Run`.

## Writing Value-Parameterized Tests with TEST_P

Value-parameterized tests require fixtures inheriting from `::testing::TestWithParam<T>`, where `T` represents your parameter type. Inside the test body or fixture methods, `GetParam()` retrieves the current iteration's value.

### Factory Function Parameters

The canonical example in `googletest/samples/sample7_unittest.cc` demonstrates parameterizing tests with factory functions to validate different `PrimeTable` implementations:

```cpp
#include "prime_tables.h"
#include "gtest/gtest.h"

using ::testing::TestWithParam;
using ::testing::Values;

typedef PrimeTable* CreatePrimeTableFunc();

PrimeTable* CreateOnTheFlyPrimeTable() { 
  return new OnTheFlyPrimeTable(); 
}

template <size_t max_precalculated>
PrimeTable* CreatePreCalculatedPrimeTable() {
  return new PreCalculatedPrimeTable(max_precalculated);
}

class PrimeTableTestSmpl7 : public TestWithParam<CreatePrimeTableFunc*> {
 public:
  ~PrimeTableTestSmpl7() override { delete table_; }
  
  void SetUp() override { 
    table_ = (*GetParam())(); 
  }
  
  void TearDown() override { 
    delete table_; 
    table_ = nullptr; 
  }

 protected:
  PrimeTable* table_;
};

TEST_P(PrimeTableTestSmpl7, ReturnsFalseForNonPrimes) {
  EXPECT_FALSE(table_->IsPrime(-5));
  EXPECT_FALSE(table_->IsPrime(0));
}

TEST_P(PrimeTableTestSmpl7, ReturnsTrueForPrimes) {
  EXPECT_TRUE(table_->IsPrime(2));
  EXPECT_TRUE(table_->IsPrime(3));
}

INSTANTIATE_TEST_SUITE_P(
    OnTheFlyAndPreCalculated,
    PrimeTableTestSmpl7,
    Values(&CreateOnTheFlyPrimeTable,
           &CreatePreCalculatedPrimeTable<1000>));

```

The `INSTANTIATE_TEST_SUITE_P` macro accepts three arguments: an instance name appearing in test logs, the fixture class name, and a parameter generator. Here, `Values()` supplies two factory function pointers, causing GoogleTest to generate two independent test cases per `TEST_P` definition—one for each factory implementation. The fixture creates the concrete object in `SetUp()` and cleans up in `TearDown()`.

### Combining Multiple Parameters

For Cartesian product generation across multiple parameter dimensions, `googletest/samples/sample8_unittest.cc` illustrates the `Combine` generator:

```cpp
#include <tuple>
#include "prime_tables.h"
#include "gtest/gtest.h"

using ::testing::Bool;
using ::testing::Combine;
using ::testing::TestWithParam;
using ::testing::Values;

class PrimeTableTest : public TestWithParam<std::tuple<bool, int>> {
 protected:
  void SetUp() override {
    bool force_on_the_fly;
    int max_precalculated;
    std::tie(force_on_the_fly, max_precalculated) = GetParam();
    table_ = new HybridPrimeTable(force_on_the_fly, max_precalculated);
  }
  
  void TearDown() override { delete table_; }

  HybridPrimeTable* table_;
};

TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) {
  // Test implementation using table_
}

INSTANTIATE_TEST_SUITE_P(
    MeaningfulTestParameters,
    PrimeTableTest,
    Combine(Bool(), Values(1, 10)));

```

The `Combine(Bool(), Values(1, 10))` generator produces four parameter tuples: `(false,1)`, `(true,1)`, `(false,10)`, and `(true,10)`. Each tuple unpacks in `SetUp()` via `std::tie`, demonstrating how to write parameterized tests in GoogleTest with multi-dimensional data sets without manual enumeration.

## Writing Type-Parameterized Tests with TYPED_TEST_P

Type-parameterized tests validate template code across multiple concrete types without duplicating test logic. Unlike value-parameterization, these tests use `TypeParam` within the test body to reference the current type instantiation.

### Template Fixtures and Registration

As shown in `googletest/samples/sample3_unittest.cc`, type-parameterized tests require a template fixture base and explicit registration steps:

```cpp
template <typename Container>
class ContainerTest : public ::testing::Test {};

TYPED_TEST_SUITE_P(ContainerTest);

TYPED_TEST_P(ContainerTest, CanBeDefaultConstructed) {
  TypeParam container;
  // TypeParam resolves to std::vector<int> or std::list<int> during instantiation
}

REGISTER_TYPED_TEST_SUITE_P(ContainerTest,
    CanBeDefaultConstructed, 
    InitialSizeIsZero);

using MyTypes = ::testing::Types<std::vector<int>, std::list<int>>;
INSTANTIATE_TYPED_TEST_SUITE_P(MyContainerTests,
    ContainerTest, 
    MyTypes);

```

The `TYPED_TEST_SUITE_P` macro registers the template fixture, while `REGISTER_TYPED_TEST_SUITE_P` enumerates the test names belonging to the suite. Finally, `INSTANTIATE_TYPED_TEST_SUITE_P` binds concrete types from `::testing::Types<...>` to generate distinct test cases at compile time.

## Key Implementation Details

The parameter generation pipeline relies on internal classes defined in [`googletest/include/gtest/internal/gtest-param-util.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/internal/gtest-param-util.h). The `ParameterizedTestSuiteInfo` class stores test patterns and drives instantiation during the test execution phase. Registration macros like `INSTANTIATE_TEST_SUITE_P` ultimately invoke `AddTestPattern` to record parameter values, ensuring each concrete test case receives a unique name combining the suite name and generated suffix.

For type-parameterized tests, the [`gtest-typed-test.h`](https://github.com/google/googletest/blob/main/gtest-typed-test.h) header defines `TYPED_TEST_P` to expand template definitions into concrete test instances at compile time, while maintaining the same runtime reporting structure as standard tests through the `TestSuite` infrastructure.

## Summary

- **Value-parameterized tests** use `TEST_P` macros with fixtures inheriting from `TestWithParam<T>`, accessing parameters via `GetParam()` and instantiating through `INSTANTIATE_TEST_SUITE_P` with generators like `Values()` or `Combine()`.
- **Type-parameterized tests** employ `TYPED_TEST_P` with template fixtures, requiring `REGISTER_TYPED_TEST_SUITE_P` for name registration and `INSTANTIATE_TYPED_TEST_SUITE_P` for type binding via `::testing::Types`.
- **Parameter generators** such as `Bool()`, `Values()`, and `Combine()` create Cartesian products of test inputs, defined in [`gtest-param-test.h`](https://github.com/google/googletest/blob/main/gtest-param-test.h) and processed by `ParameterizedTestSuiteInfo` in [`gtest-param-util.h`](https://github.com/google/googletest/blob/main/gtest-param-util.h).
- **Lifecycle management** occurs in fixture `SetUp()` and `TearDown()` methods, as demonstrated in `sample7_unittest.cc` and `sample8_unittest.cc` for resource allocation per parameter value.

## Frequently Asked Questions

### What is the difference between TEST_P and TYPED_TEST_P in GoogleTest?

`TEST_P` (value-parameterized) runs the same test code against different runtime values supplied via `INSTANTIATE_TEST_SUITE_P`, requiring inheritance from `TestWithParam<T>`. `TYPED_TEST_P` (type-parameterized) compiles the test code against different C++ types, using `TypeParam` as a placeholder for the current type during instantiation. Value-parameterization suits data-driven testing with varying inputs, while type-parameterization validates template implementations across multiple type constraints.

### How do I access the current parameter value in a parameterized test?

Call the `GetParam()` method inherited from `TestWithParam<T>`. Inside the test body or fixture methods, `GetParam()` returns the current parameter value of type `T` specified in the fixture declaration. For multi-parameter scenarios using `std::tuple`, unpack the tuple with `std::tie` or structured binding in your `SetUp()` method, as shown in `googletest/samples/sample8_unittest.cc`.

### Can I combine multiple parameter generators in GoogleTest?

Yes. Use the `Combine()` generator from [`gtest-param-test.h`](https://github.com/google/googletest/blob/main/gtest-param-test.h) to create Cartesian products of parameter sets. For example, `Combine(Bool(), Values(1, 10))` generates four test instances covering all combinations of boolean values and the provided integers. Each combination becomes a separate test case with a unique name suffix during instantiation via `INSTANTIATE_TEST_SUITE_P`.

### Where are parameterized test patterns stored in the GoogleTest source?

Parameterized test metadata resides in [`googletest/include/gtest/internal/gtest-param-util.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/internal/gtest-param-util.h), where the `ParameterizedTestSuiteInfo` class maintains test patterns and parameter lists. Public API macros like `INSTANTIATE_TEST_SUITE_P` delegate to internal helpers such as `AddTestPattern` to register these patterns, which the framework later expands during `TestSuite::Run` to generate concrete test cases with unique identifiers.