2026-06-30 20:45:25 +02:00

161 lines
4.2 KiB
Markdown

---
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)