# How to Define Type-Parameterized Tests in GoogleTest: 4 Macro Phases Explained

> Learn how to define type-parameterized tests in GoogleTest using four key macros. Separate test patterns from type instantiation for efficient testing across multiple data types.

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

---

**GoogleTest enables type-parameterized tests through four distinct macros—`TYPED_TEST_SUITE_P`, `TYPED_TEST_P`, `REGISTER_TYPED_TEST_SUITE_P`, and `INSTANTIATE_TYPED_TEST_SUITE_P`—that separate test pattern declaration from concrete type instantiation, allowing a single template-based test suite to run against multiple data types.**

Type-parameterized tests eliminate redundancy when testing template classes or generic algorithms across different types. The implementation resides in [`googletest/include/gtest/gtest-typed-test.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/gtest-typed-test.h) and leverages static initialization to register test cases before `main()` executes. This guide explains how to define type-parameterized tests in GoogleTest using the exact macro expansion sequence found in the source code.

## The Four-Phase Macro Architecture

GoogleTest implements type-parameterized testing through a strict four-phase workflow. Each phase corresponds to a specific macro in [`gtest-typed-test.h`](https://github.com/google/googletest/blob/main/gtest-typed-test.h) that expands into template machinery and static registration objects within the `testing::internal` namespace.

### Phase 1: Declare the Pattern with `TYPED_TEST_SUITE_P`

Begin by declaring a test pattern using `TYPED_TEST_SUITE_P(SuiteName)`. According to lines 59-61 of [`gtest-typed-test.h`](https://github.com/google/googletest/blob/main/gtest-typed-test.h), this macro creates a static `TypedTestSuitePState` object that stores metadata about the tests that will belong to this pattern.

```cpp
template <typename T>
class StackTest : public ::testing::Test {};

// Declares the pattern (lines 59-61)
TYPED_TEST_SUITE_P(StackTest);

```

The macro generates a unique namespace `GTEST_SUITE_NAMESPACE_(SuiteName)` to encapsulate pattern-specific declarations and initializes the registration state.

### Phase 2: Define Test Bodies with `TYPED_TEST_P`

Use `TYPED_TEST_P(SuiteName, TestName)` to define individual test cases. As implemented in lines 70-84, this macro generates a templated test class inside the hidden namespace and registers the test name with the `TypedTestSuitePState` object created in Phase 1.

```cpp
// Defines test bodies (lines 70-84)
TYPED_TEST_P(StackTest, IsEmpty) {
  Stack<TypeParam> s;
  EXPECT_TRUE(s.empty());
}

TYPED_TEST_P(StackTest, PushPop) {
  Stack<TypeParam> s;
  s.push(TypeParam{});
  EXPECT_FALSE(s.empty());
  s.pop();
  EXPECT_TRUE(s.empty());
}

```

Inside these tests, access the current type using the `TypeParam` typedef injected by the macro expansion.

### Phase 3: Register the Pattern with `REGISTER_TYPED_TEST_SUITE_P`

Aggregate all defined tests using `REGISTER_TYPED_TEST_SUITE_P(SuiteName, TestName1, TestName2, ...)`. Lines 89-96 of [`gtest-typed-test.h`](https://github.com/google/googletest/blob/main/gtest-typed-test.h) implement this macro to pack the test names into an internal `Templates` type list and store it within a static registration structure.

```cpp
// Registers the pattern (lines 89-96)
REGISTER_TYPED_TEST_SUITE_P(StackTest, IsEmpty, PushPop);

```

**Critical constraint:** This macro must appear in exactly one translation unit. Including it in multiple files causes duplicate symbol linker errors because it defines static registration objects with external linkage.

### Phase 4: Instantiate with Concrete Types

Finally, instantiate the pattern using `INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types)`. Lines 106-119 utilize `internal::GenerateTypeList<Types>` to iterate over the type list, generate concrete test classes for each type, and register them with unique names formed by concatenating `Prefix` and `SuiteName`.

```cpp
// In a .cc file (lines 106-119)
using MyTypes = ::testing::Types<int, std::string, double>;
INSTANTIATE_TYPED_TEST_SUITE_P(My, StackTest, MyTypes);

```

This creates test suites named `My/StackTest<int>`, `My/StackTest<std::string>`, and `My/StackTest<double>`, each containing the `IsEmpty` and `PushPop` tests.

## Complete Working Example

### Pattern Definition Header

Create a header file that declares the pattern and defines test logic without knowing the concrete types:

```cpp
// stack_test_pattern.h
#include <gtest/gtest.h>
#include <stack>

template <typename T>
class StackTest : public ::testing::Test {
 protected:
  std::stack<T> stack_;
};

// Phase 1: Declaration
TYPED_TEST_SUITE_P(StackTest);

// Phase 2: Test definitions
TYPED_TEST_P(StackTest, DefaultConstructible) {
  // TypeParam refers to the current type being tested
  TypeParam val{};
  this->stack_.push(val);
  EXPECT_EQ(this->stack_.top(), val);
}

TYPED_TEST_P(StackTest, SizeIncreases) {
  EXPECT_EQ(this->stack_.size(), 0);
  this->stack_.push(TypeParam{});
  EXPECT_EQ(this->stack_.size(), 1);
}

// Phase 3: Registration (must be in header if only included once, or move to .cc)
REGISTER_TYPED_TEST_SUITE_P(StackTest, DefaultConstructible, SizeIncreases);

```

### Instantiation Translation Unit

Instantiate the pattern in a separate source file:

```cpp
// test_instantiation.cc
#include "stack_test_pattern.h"

using TestTypes = ::testing::Types<int, float, std::string>;
// Phase 4: Instantiation
INSTANTIATE_TYPED_TEST_SUITE_P(Pre, StackTest, TestTypes);

```

## Customizing Test Name Generation

GoogleTest accepts an optional fourth parameter to `INSTANTIATE_TYPED_TEST_SUITE_P` for custom name generation. Define a struct with a static `GetName(int index)` template method:

```cpp
struct TypeNames {
  template <typename T>
  static std::string GetName(int) {
    if (std::is_same<T, int>::value) return "Integer";
    if (std::is_same<T, float>::value) return "Float";
    return "Unknown";
  }
};

INSTANTIATE_TYPED_TEST_SUITE_P(Custom, StackTest, 
                               ::testing::Types<int, float>, 
                               TypeNames);
// Generates: Custom/StackTest_Integer/DefaultConstructible

```

The `GTEST_NAME_GENERATOR_` machinery in [`gtest-typed-test.h`](https://github.com/google/googletest/blob/main/gtest-typed-test.h) invokes this at instantiation time to construct the final test name.

## Key Implementation Files

The type-parameterized test system spans three primary headers in the GoogleTest repository:

- **[`googletest/include/gtest/gtest-typed-test.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/gtest-typed-test.h)**: Contains the four public macros and their expansions (lines 59-119).
- **[`googletest/include/gtest/internal/gtest-internal.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/internal/gtest-internal.h)**: Defines `TypeParameterizedTest` and registration helpers used by the macros.
- **[`googletest/include/gtest/internal/gtest-type-util.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/internal/gtest-type-util.h)**: Provides `GenerateTypeList` and name generation utilities for type list traversal.

Because registration occurs through static object initialization (`gtest_*_registered_` variables), patterns can be declared in headers and instantiated across multiple translation units without manual registry manipulation.

## Summary

- **Declare** patterns with `TYPED_TEST_SUITE_P` to initialize the test suite state.
- **Define** tests using `TYPED_TEST_P`, accessing types via `TypeParam` inside test bodies.
- **Register** exactly once per pattern with `REGISTER_TYPED_TEST_SUITE_P` to avoid linker errors.
- **Instantiate** across multiple translation units using `INSTANTIATE_TYPED_TEST_SUITE_P` with a type list and optional name generator.
- Reference the concrete implementation in [`googletest/include/gtest/gtest-typed-test.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/gtest-typed-test.h) lines 59-119 for macro expansion details.

## Frequently Asked Questions

### What is the difference between `TYPED_TEST` and `TYPED_TEST_P`?

**`TYPED_TEST`** is used when the type list is known at the point of test definition, requiring `TYPED_TEST_SUITE` and the type list immediately. **`TYPED_TEST_P`** creates a reusable pattern where the type list is supplied later via `INSTANTIATE_TYPED_TEST_SUITE_P`, enabling test definitions in headers separate from instantiation sites.

### Why am I getting linker errors about duplicate symbols?

`REGISTER_TYPED_TEST_SUITE_P` defines static objects with external linkage. If you include this macro in a header included by multiple translation units, the linker encounters duplicate definitions. Move the registration macro to a single `.cc` file, or ensure the header has include guards and is only processed once per pattern.

### Can I instantiate the same pattern multiple times with different prefixes?

Yes. You can call `INSTANTIATE_TYPED_TEST_SUITE_P` multiple times with different `Prefix` values and different type lists. Each instantiation generates distinct test suites (e.g., `Prefix1/SuiteName<int>` and `Prefix2/SuiteName<double>`) without conflict.

### How do I access the type parameter inside a `TYPED_TEST_P`?

The macro expansion injects a `TypeParam` typedef into the test class scope. Use `TypeParam` to declare variables, or use `this` to access fixture members as shown in the examples above. For qualified names, `typename TestFixture::TypeParam` also works within the test body.