[2026] Google Test (gtest) for C++: From Setup to TEST, Fixtures, and CI

[2026] Google Test (gtest) for C++: From Setup to TEST, Fixtures, and CI

이 글의 핵심

Complete C++ unit testing guide with Google Test: setup, assertions, fixtures, parameterized tests, death tests, TDD workflow, CI integration, and production patterns with real-world examples.

Introduction: “I refactored and something else broke”

Table of contents

  1. Setup with CMake
  2. Basic assertions
  3. Test fixtures
  4. Parameterized tests
  5. Death tests
  6. Real-world examples
  7. TDD workflow
  8. Common errors
  9. Debugging tips
  10. Best practices
  11. CI integration
  12. Production patterns

1. Setup with CMake

다음은 cmake를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

cmake_minimum_required(VERSION 3.14)
project(MyProject)
include(FetchContent)
FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://github.com/google/googletest.git
    GIT_TAG release-1.12.1
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
enable_testing()
add_executable(myapp_test 
    test_main.cpp
    test_calculator.cpp
)
target_link_libraries(myapp_test PRIVATE 
    gtest_main
    myapp_lib  # Your library under test
)
include(GoogleTest)
gtest_discover_tests(myapp_test)

Method 2: vcpkg

vcpkg install gtest

아래 코드는 cmake를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

find_package(GTest CONFIG REQUIRED)
add_executable(myapp_test test_main.cpp)
target_link_libraries(myapp_test PRIVATE 
    GTest::gtest_main
    myapp_lib
)

Method 3: Conan

아래 코드는 ini를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# conanfile.txt
[requires]
gtest/1.12.1
[generators]
CMakeDeps
CMakeToolchain
find_package(GTest REQUIRED)
target_link_libraries(myapp_test PRIVATE GTest::gtest_main)

2. Basic assertions

EXPECT vs ASSERT

아래 코드는 cpp를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <gtest/gtest.h>
TEST(CalculatorTest, Addition) {
    // EXPECT: continues after failure
    EXPECT_EQ(2 + 2, 4);
    EXPECT_EQ(3 + 3, 6);  // Still runs even if above fails
    
    // ASSERT: stops test on failure
    int* ptr = new int(42);
    ASSERT_NE(ptr, nullptr);  // Must pass before using ptr
    EXPECT_EQ(*ptr, 42);      // Only runs if ptr is valid
    delete ptr;
}

Common assertions

다음은 cpp를 활용한 상세한 구현 코드입니다. 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// Boolean
EXPECT_TRUE(condition);
EXPECT_FALSE(condition);
// Comparison
EXPECT_EQ(a, b);   // ==
EXPECT_NE(a, b);   // !=
EXPECT_LT(a, b);   // <
EXPECT_LE(a, b);   // <=
EXPECT_GT(a, b);   // >
EXPECT_GE(a, b);   // >=
// Strings
EXPECT_STREQ("hello", str);      // C-strings
EXPECT_STRNE("world", str);
std::string s = "test";
EXPECT_EQ("test", s);            // std::string works with EQ
// Floating point
EXPECT_FLOAT_EQ(1.0f, result);
EXPECT_DOUBLE_EQ(1.0, result);
EXPECT_NEAR(1.0, result, 0.001); // Within tolerance
// Exceptions
EXPECT_THROW(func(), std::runtime_error);
EXPECT_NO_THROW(func());
EXPECT_ANY_THROW(func());

Custom messages

EXPECT_EQ(expected, actual) << "Failed with input: " << input;

3. Test fixtures (TEST_F)

Basic fixture

다음은 cpp를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

class DatabaseTest : public ::testing::Test {
protected:
    Database* db;
    
    // Runs before each test
    void SetUp() override {
        db = new Database("test.db");
        db->connect();
    }
    
    // Runs after each test
    void TearDown() override {
        db->disconnect();
        delete db;
    }
};
TEST_F(DatabaseTest, InsertRecord) {
    EXPECT_TRUE(db->insert("key", "value"));
    EXPECT_EQ(db->get("key"), "value");
}
TEST_F(DatabaseTest, DeleteRecord) {
    db->insert("key", "value");
    EXPECT_TRUE(db->remove("key"));
    EXPECT_EQ(db->get("key"), "");
}

Suite-level setup (shared across tests)

다음은 cpp를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

class ExpensiveResourceTest : public ::testing::Test {
protected:
    static Database* shared_db;
    
    // Runs once before all tests in suite
    static void SetUpTestSuite() {
        shared_db = new Database("shared.db");
        shared_db->connect();
    }
    
    // Runs once after all tests in suite
    static void TearDownTestSuite() {
        shared_db->disconnect();
        delete shared_db;
        shared_db = nullptr;
    }
};
Database* ExpensiveResourceTest::shared_db = nullptr;
TEST_F(ExpensiveResourceTest, Test1) {
    EXPECT_NE(shared_db, nullptr);
}
TEST_F(ExpensiveResourceTest, Test2) {
    EXPECT_NE(shared_db, nullptr);
}

4. Parameterized tests

Basic parameterized test

다음은 cpp를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

class SquareTest : public ::testing::TestWithParam<std::pair<int, int>> {};
TEST_P(SquareTest, CheckSquare) {
    auto [input, expected] = GetParam();
    EXPECT_EQ(input * input, expected);
}
INSTANTIATE_TEST_SUITE_P(
    SquareValues,
    SquareTest,
    ::testing::Values(
        std::make_pair(0, 0),
        std::make_pair(1, 1),
        std::make_pair(2, 4),
        std::make_pair(3, 9),
        std::make_pair(-2, 4)
    )
);

Multiple parameters with Combine

다음은 cpp를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

class StringTest : public ::testing::TestWithParam<std::tuple<std::string, char, int>> {};
TEST_P(StringTest, CountChar) {
    auto [str, ch, expected] = GetParam();
    int count = std::count(str.begin(), str.end(), ch);
    EXPECT_EQ(count, expected);
}
INSTANTIATE_TEST_SUITE_P(
    StringCases,
    StringTest,
    ::testing::Combine(
        ::testing::Values("hello", "world", "test"),
        ::testing::Values('l', 'o', 't'),
        ::testing::Range(0, 3)
    )
);

Range and ValuesIn

아래 코드는 cpp를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

// Range: [0, 10) step 2
INSTANTIATE_TEST_SUITE_P(RangeTest, MyTest, ::testing::Range(0, 10, 2));
// ValuesIn: from container
std::vector<int> inputs = {1, 2, 3, 5, 8, 13};
INSTANTIATE_TEST_SUITE_P(FibTest, MyTest, ::testing::ValuesIn(inputs));

5. Death tests

Basic death test

다음은 cpp를 활용한 상세한 구현 코드입니다. 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

void DivideByZero(int a, int b) {
    assert(b != 0 && "Division by zero");
    return a / b;
}
TEST(MathDeathTest, DivisionByZero) {
    EXPECT_DEATH(DivideByZero(10, 0), "Division by zero");
}
TEST(MathDeathTest, AbortOnError) {
    ASSERT_DEATH({
        if (condition) {
            std::abort();
        }
    }, ".*");  // Regex for expected stderr
}

Platform-specific death tests

아래 코드는 cpp를 사용한 구현 예제입니다. 에러 처리를 통해 안정성을 확보합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

TEST(DeathTest, CrossPlatform) {
#ifdef NDEBUG
    EXPECT_DEATH_IF_SUPPORTED(func(), "error");
#else
    EXPECT_DEATH(func(), "error");
#endif
}

6. Real-world examples

Example 1: String utility class

다음은 cpp를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며, 반복문으로 데이터를 처리합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

class StringUtils {
public:
    static std::string trim(const std::string& str) {
        size_t start = str.find_first_not_of(" \t\n\r");
        if (start == std::string::npos) return "";
        size_t end = str.find_last_not_of(" \t\n\r");
        return str.substr(start, end - start + 1);
    }
    
    static std::vector<std::string> split(const std::string& str, char delim) {
        std::vector<std::string> result;
        std::stringstream ss(str);
        std::string item;
        while (std::getline(ss, item, delim)) {
            result.push_back(item);
        }
        return result;
    }
};
TEST(StringUtilsTest, TrimWhitespace) {
    EXPECT_EQ(StringUtils::trim("  hello  "), "hello");
    EXPECT_EQ(StringUtils::trim("\t\ntest\r\n"), "test");
    EXPECT_EQ(StringUtils::trim(""), "");
    EXPECT_EQ(StringUtils::trim("   "), "");
}
TEST(StringUtilsTest, SplitString) {
    auto result = StringUtils::split("a,b,c", ',');
    ASSERT_EQ(result.size(), 3);
    EXPECT_EQ(result[0], "a");
    EXPECT_EQ(result[1], "b");
    EXPECT_EQ(result[2], "c");
}

Example 2: HTTP client with mock

다음은 cpp를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

class HttpClient {
public:
    virtual ~HttpClient() = default;
    virtual std::string get(const std::string& url) = 0;
};
class RealHttpClient : public HttpClient {
public:
    std::string get(const std::string& url) override {
        // Actual HTTP implementation
        return "real response";
    }
};
class MockHttpClient : public HttpClient {
public:
    std::string get(const std::string& url) override {
        return "mock response";
    }
};
class ApiService {
    HttpClient* client;
public:
    explicit ApiService(HttpClient* c) : client(c) {}
    
    std::string fetchData(const std::string& endpoint) {
        return client->get("https://api.example.com/" + endpoint);
    }
};
TEST(ApiServiceTest, FetchData) {
    MockHttpClient mock;
    ApiService service(&mock);
    
    std::string result = service.fetchData("users");
    EXPECT_EQ(result, "mock response");
}

Example 3: Thread-safe queue

다음은 cpp를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며, 에러 처리를 통해 안정성을 확보합니다, 반복문으로 데이터를 처리합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

template<typename T>
class ThreadSafeQueue {
    std::queue<T> queue;
    mutable std::mutex mutex;
public:
    void push(T value) {
        std::lock_guard<std::mutex> lock(mutex);
        queue.push(std::move(value));
    }
    
    bool try_pop(T& value) {
        std::lock_guard<std::mutex> lock(mutex);
        if (queue.empty()) return false;
        value = std::move(queue.front());
        queue.pop();
        return true;
    }
    
    size_t size() const {
        std::lock_guard<std::mutex> lock(mutex);
        return queue.size();
    }
};
TEST(ThreadSafeQueueTest, PushAndPop) {
    ThreadSafeQueue<int> q;
    q.push(1);
    q.push(2);
    
    int value;
    ASSERT_TRUE(q.try_pop(value));
    EXPECT_EQ(value, 1);
    ASSERT_TRUE(q.try_pop(value));
    EXPECT_EQ(value, 2);
    EXPECT_FALSE(q.try_pop(value));
}
TEST(ThreadSafeQueueTest, Concurrent) {
    ThreadSafeQueue<int> q;
    const int N = 1000;
    
    std::thread producer([&]() {
        for (int i = 0; i < N; ++i) {
            q.push(i);
        }
    });
    
    std::thread consumer([&]() {
        int count = 0;
        int value;
        while (count < N) {
            if (q.try_pop(value)) {
                ++count;
            }
        }
    });
    
    producer.join();
    consumer.join();
    
    EXPECT_EQ(q.size(), 0);
}

7. TDD workflow

Red-Green-Refactor cycle

다음은 cpp를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// 1. RED: Write failing test
TEST(CalculatorTest, Multiply) {
    Calculator calc;
    EXPECT_EQ(calc.multiply(2, 3), 6);  // Fails: multiply not implemented
}
// 2. GREEN: Minimal implementation
class Calculator {
public:
    int multiply(int a, int b) {
        return a * b;  // Simplest solution
    }
};
// 3. REFACTOR: Improve without breaking test
class Calculator {
public:
    int multiply(int a, int b) {
        // Add validation, logging, etc.
        if (a == 0 || b == 0) return 0;
        return a * b;
    }
};

Test-first development

다음은 cpp를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// Step 1: Write test for new feature
TEST(UserServiceTest, CreateUser) {
    UserService service;
    User user = service.createUser("john", "john@example.com");
    EXPECT_EQ(user.name, "john");
    EXPECT_EQ(user.email, "john@example.com");
    EXPECT_FALSE(user.id.empty());
}
// Step 2: Implement to pass test
class UserService {
public:
    User createUser(const std::string& name, const std::string& email) {
        User user;
        user.id = generateId();
        user.name = name;
        user.email = email;
        return user;
    }
};

8. Common errors and fixes

Error 1: Undefined reference to InitGoogleTest

undefined reference to `testing::InitGoogleTest(int*, char**)'

Fix: Link gtest_main or provide main

target_link_libraries(myapp_test PRIVATE gtest_main)

Error 2: Multiple definitions of main

multiple definition of `main'

Fix: Don’t define main when using gtest_main 아래 코드는 cpp를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

// Remove this if using gtest_main
int main(int argc, char** argv) {
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

Error 3: pthread error on Linux

undefined reference to `pthread_create'

Fix: Link Threads

find_package(Threads REQUIRED)
target_link_libraries(myapp_test PRIVATE gtest_main Threads::Threads)

Error 4: Death test fails in Release

Expected: DivideByZero(10, 0) dies
  Actual: it didn't die

Fix: assert() is disabled in Release (NDEBUG) 아래 코드는 cpp를 사용한 구현 예제입니다. 조건문으로 분기 처리를 수행합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

// Use custom assertion that works in Release
#define MY_ASSERT(cond, msg) \
    if (!(cond)) { \
        std::cerr << msg << std::endl; \
        std::abort(); \
    }

Error 5: Flaky tests in CI

Test passed locally but fails randomly in CI

Fix: Remove nondeterminism 아래 코드는 cpp를 사용한 구현 예제입니다. 반복문으로 데이터를 처리합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

// BAD: depends on timing
std::this_thread::sleep_for(std::chrono::milliseconds(100));
// GOOD: use synchronization
std::condition_variable cv;
std::mutex m;
std::unique_lock<std::mutex> lock(m);
cv.wait(lock, []{ return ready; });

9. Debugging tips

Tip 1: Run specific tests

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# Run all tests in suite
./myapp_test --gtest_filter=CalculatorTest.*
# Run specific test
./myapp_test --gtest_filter=CalculatorTest.Addition
# Exclude tests
./myapp_test --gtest_filter=-*Slow*

Tip 2: Repeat tests

아래 코드는 bash를 사용한 구현 예제입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다, 에러 처리를 통해 안정성을 확보합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# Repeat 100 times to catch flaky tests
./myapp_test --gtest_repeat=100
# Break on first failure
./myapp_test --gtest_repeat=100 --gtest_break_on_failure

Tip 3: Verbose output

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# Show all test names
./myapp_test --gtest_list_tests
# Colorized output
./myapp_test --gtest_color=yes

Tip 4: SCOPED_TRACE for loops

아래 코드는 cpp를 사용한 구현 예제입니다. 반복문으로 데이터를 처리합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

TEST(LoopTest, MultipleValues) {
    std::vector<int> inputs = {1, 2, 3, 4, 5};
    for (size_t i = 0; i < inputs.size(); ++i) {
        SCOPED_TRACE("Testing input at index " + std::to_string(i));
        EXPECT_GT(inputs[i], 0);
    }
}

Tip 5: Debug with GDB

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# Build with debug symbols
cmake -DCMAKE_BUILD_TYPE=Debug ..
# Run under GDB
gdb --args ./myapp_test --gtest_filter=MyTest.Specific
(gdb) break MyTest_Specific_Test::TestBody
(gdb) run

10. Best practices

1. One assertion per test (when possible)

다음은 cpp를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// BAD: Multiple unrelated assertions
TEST(UserTest, Everything) {
    User user("john");
    EXPECT_EQ(user.getName(), "john");
    EXPECT_TRUE(user.isValid());
    EXPECT_EQ(user.getAge(), 0);
}
// GOOD: Separate tests
TEST(UserTest, GetName) {
    User user("john");
    EXPECT_EQ(user.getName(), "john");
}
TEST(UserTest, IsValid) {
    User user("john");
    EXPECT_TRUE(user.isValid());
}

2. Descriptive test names

아래 코드는 cpp를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

// BAD
TEST(UserTest, Test1) { }
// GOOD
TEST(UserTest, GetName_WithValidInput_ReturnsName) { }
TEST(UserTest, IsValid_WithEmptyName_ReturnsFalse) { }

3. AAA pattern (Arrange-Act-Assert)

아래 코드는 cpp를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

TEST(CalculatorTest, Add_TwoPositiveNumbers_ReturnsSum) {
    // Arrange
    Calculator calc;
    int a = 2, b = 3;
    
    // Act
    int result = calc.add(a, b);
    
    // Assert
    EXPECT_EQ(result, 5);
}

4. Test edge cases

아래 코드는 cpp를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

TEST(StringTest, EdgeCases) {
    EXPECT_EQ(trim(""), "");           // Empty
    EXPECT_EQ(trim(" "), "");          // Only whitespace
    EXPECT_EQ(trim("a"), "a");         // Single char
    EXPECT_EQ(split("", ',').size(), 1); // Empty split
}

5. Avoid test interdependence

아래 코드는 cpp를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// BAD: Tests depend on order
static int counter = 0;
TEST(BadTest, First) { counter = 1; }
TEST(BadTest, Second) { EXPECT_EQ(counter, 1); } // Fragile!
// GOOD: Each test is independent
TEST(GoodTest, First) {
    int counter = 0;
    counter = 1;
    EXPECT_EQ(counter, 1);
}

11. CI integration

GitHub Actions

다음은 yaml를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

name: Tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Install dependencies
        run: sudo apt-get install -y cmake g++
      
      - name: Build
        run: |
          cmake -B build -DCMAKE_BUILD_TYPE=Release
          cmake --build build
      
      - name: Run tests
        run: |
          cd build
          ctest --output-on-failure
      
      - name: Generate coverage
        run: |
          cmake -B build -DCMAKE_BUILD_TYPE=Debug -DENABLE_COVERAGE=ON
          cmake --build build
          cd build
          ctest
          lcov --capture --directory . --output-file coverage.info
          lcov --remove coverage.info '/usr/*' --output-file coverage.info
          lcov --list coverage.info

CTest integration

아래 코드는 cmake를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

enable_testing()
add_executable(myapp_test test_main.cpp)
target_link_libraries(myapp_test PRIVATE gtest_main myapp_lib)
include(GoogleTest)
gtest_discover_tests(myapp_test)

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# Run all tests
ctest
# Verbose output
ctest -V
# Run specific test
ctest -R CalculatorTest
# Parallel execution
ctest -j4

12. Production patterns

Pattern 1: Separate test directory

아래 코드는 code를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

project/
├── CMakeLists.txt
├── src/
│   ├── calculator.h
│   └── calculator.cpp
└── test/
    ├── CMakeLists.txt
    └── test_calculator.cpp

Pattern 2: Test utilities

아래 코드는 cpp를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// test/test_utils.h
namespace test_utils {
    inline std::string readFile(const std::string& path) {
        std::ifstream file(path);
        return std::string((std::istreambuf_iterator<char>(file)),
                          std::istreambuf_iterator<char>());
    }
    
    inline void createTempFile(const std::string& path, const std::string& content) {
        std::ofstream file(path);
        file << content;
    }
}

Pattern 3: Custom matchers

아래 코드는 cpp를 사용한 구현 예제입니다. 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

testing::AssertionResult IsEven(int n) {
    if (n % 2 == 0)
        return testing::AssertionSuccess();
    else
        return testing::AssertionFailure() << n << " is odd";
}
TEST(NumberTest, EvenNumbers) {
    EXPECT_TRUE(IsEven(2));
    EXPECT_TRUE(IsEven(4));
}

Summary

  • Setup: FetchContent, vcpkg, or Conan
  • Assertions: EXPECT_* (continue) vs ASSERT_* (stop)
  • Fixtures: TEST_F for setup/teardown
  • Parameterized: TEST_P for data-driven tests
  • Death tests: EXPECT_DEATH for abort/exit verification
  • TDD: Red-Green-Refactor cycle
  • CI: ctest integration with GitHub Actions
  • Best practices: One assertion per test, descriptive names, AAA pattern Next: Google Mock (#18-2)
    Previous: Package managers (#17-2)

Keywords

Google Test, gtest, C++ unit testing, TDD, CTest, test fixtures, parameterized tests

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3