---
name: testcase-common-setup
description: 'Use when: refactoring tests to eliminate duplication via test fixtures, extracting common setup into SetUp(), converting TEST() to TEST_F() in Google Test. Run this after adding new test cases that duplicate setup code.'
user-invocable: true
---

# Test Case Common Setup (Google Test)

This skill refactors Google Test suites by extracting duplicate setup code into a shared test fixture with `SetUp()`. Applying this skill makes tests more maintainable and reduces noise from repeated scaffolding.

## When to Use

- Multiple `TEST()` cases create the same object or call the same configuration
- A new test case requires copying setup lines from an existing test
- Reviewing test code and noticing the same 2+ lines repeated across every test
- After adding a new test that duplicates setup from existing tests

## Procedure

### 1. Identify Duplicated Setup

Scan all `TEST()` blocks in the test suite. Look for lines that are **identical** across every test — typically:

- Object creation: `VendingMachine vm;` (or similar SUT construction)
- Common configuration calls: `vm.configureSlot(...)`
- Pre-conditions that apply to all tests

### 2. Create a Test Fixture

Introduce a fixture class deriving from `::testing::Test`:

```cpp
class <TestSuiteName> : public ::testing::Test {
protected:
  // Shared state goes here — typically the System Under Test
  <Type> <variable>;
};
```

- Place it right after the includes, before the first test
- Declare shared variables as `protected` members
- Name the fixture after the test suite (e.g. `VendingMachineTest`)

### 3. Extract Shared Setup into `SetUp()`

Define `void SetUp() override` inside the fixture with the lines common to **all** tests:

```cpp
class <TestSuiteName> : public ::testing::Test {
protected:
  <Type> <variable>;

  void SetUp() override
  {
    // Lines that every test needs — extracted here once
    <sharedSetupLine1>;
    <sharedSetupLine2>;
  }
};
```

Rules:
- Only move lines that appear in **every** test
- If a line only appears in some tests, leave it in the individual `TEST_F()` bodies
- Keep `SetUp()` focused — it runs before each test, so don't put expensive or test-specific logic there

### 4. Convert `TEST()` to `TEST_F()`

Replace every occurrence:

```cpp
// Before
TEST(<TestSuiteName>, <TestCaseName>)
{
  <Type> <variable>;          // ← now redundant
  <sharedSetupLine1>;         // ← now redundant (in SetUp)
  ...
}

// After
TEST_F(<TestSuiteName>, <TestCaseName>)
{
  // Only test-specific code remains
  ...
}
```

- Remove the redundant object declaration from each test body
- Remove any lines now handled by `SetUp()`
- Remove configuration calls that were duplicates across all tests

### 5. Verify

Run the test suite to confirm all tests still pass:

```bash
./run_tests.sh
```

All tests must pass before considering the refactor complete.

## Example

Before — three tests with duplicated setup:

```cpp
TEST(VendingMachineTest, unconfigured_choice_dispenses_nothing)
{
  VendingMachine vm;
  EXPECT_EQ(vm.dispense(Choice::Cola), std::nullopt);
}

TEST(VendingMachineTest, configured_slot_dispenses_can)
{
  VendingMachine vm;
  vm.configureSlot(Choice::Cola, Can::Coke);
  EXPECT_EQ(vm.dispense(Choice::Cola), Can::Coke);
}

TEST(VendingMachineTest, multiple_slots_dispense_correctly)
{
  VendingMachine vm;
  vm.configureSlot(Choice::FizzyOrange, Can::Fanta);
  vm.configureSlot(Choice::Cola, Can::Coke);
  EXPECT_EQ(vm.dispense(Choice::FizzyOrange), Can::Fanta);
}
```

After — fixture with `SetUp()`:

```cpp
class VendingMachineTest : public ::testing::Test {
protected:
  VendingMachine vm;

  void SetUp() override
  {
    vm.configureSlot(Choice::Cola, Can::Coke);
    vm.configureSlot(Choice::FizzyOrange, Can::Fanta);
  }
};

TEST_F(VendingMachineTest, unconfigured_choice_dispenses_nothing)
{
  EXPECT_EQ(vm.dispense(Choice::Beer), std::nullopt);
}

TEST_F(VendingMachineTest, configured_slot_dispenses_can)
{
  EXPECT_EQ(vm.dispense(Choice::Cola), Can::Coke);
}

TEST_F(VendingMachineTest, multiple_slots_dispense_correctly)
{
  EXPECT_EQ(vm.dispense(Choice::FizzyOrange), Can::Fanta);
}
```

## References

- [Google Test: Test Fixtures](https://google.github.io/googletest/primer.html#same-data-multiple-tests)