메뉴 닫기

C++ 유닛 테스트 자동화: Google Test(GTest)로 신뢰성 높이기


C++ 유닛 테스트 자동화: Google Test(GTest)로 신뢰성 높이기

✅ C++ 코드 품질을 높이고 싶은 개발자라면 이 글을 주목하세요!

C++ 프로젝트를 진행하다 보면 점점 복잡해지는 코드와 함께 테스트의 중요성도 커지기 마련입니다.
그럴수록 안정성과 유지보수를 위해 자동화된 유닛 테스트 환경을 갖추는 것이 필수가 되죠.
특히 Google Test(GTest)처럼 잘 정리된 프레임워크를 사용하면 테스트가 단순해질 뿐 아니라 협업에서도 큰 도움이 됩니다.
이번 글에서는 C++ 개발자들이 자주 사용하는 유닛 테스트 도구와 함께, 실제 적용 방법 및 활용 팁까지 하나하나 자세히 알려드릴게요.
테스트 자동화에 대한 개념이 어렵게 느껴졌던 분들도 오늘부터는 조금 다르게 느껴질 수 있습니다.
함께 시작해볼까요?

이 글에서는 C++에서 사용할 수 있는 대표적인 테스트 프레임워크인 Google Test를 중심으로 유닛 테스트를 어떻게 구성하고 자동화할 수 있는지를 소개합니다.
테스트 코드를 작성해야 하는 이유부터, 설치 방법, 기초 문법, 실전 예제, 그리고 자주 묻는 질문까지 단계별로 안내해드릴 예정입니다.
유닛 테스트를 처음 접하는 분부터 실제 현업에 적용하고 싶은 분들까지 모두 참고하실 수 있는 실용적인 내용으로 구성되어 있어요.







유닛 테스트란 무엇인가요?

유닛 테스트(Unit Test)란 소프트웨어 개발에서 하나의 함수나 클래스 같은 최소 단위 단위의 코드가 정확히 동작하는지 검증하는 테스트입니다.
이런 테스트는 보통 자동화된 방식으로 실행되며, 코드 변경 시 버그가 발생했는지를 빠르게 확인할 수 있도록 도와줍니다.

특히 C++처럼 구조가 복잡하고 메모리 관리를 직접 해야 하는 언어에서는, 테스트를 통한 안정성 확보가 매우 중요합니다.
예상치 못한 예외나 논리 오류, 인터페이스 변경 등의 이슈를 사전에 잡아낼 수 있기 때문이죠.

  • 🧪기능별 테스트 코드로 예상 결과와 실제 결과 비교
  • 🛠️버그 발생 시 정확한 위치와 원인을 빠르게 파악
  • 🔄리팩토링 후에도 동작이 유지되는지 검증

물론, 모든 기능을 유닛 테스트로 다 커버할 수는 없습니다.
하지만 핵심 로직이나 자주 변경되는 코드에 대해 유닛 테스트가 잘 작성되어 있다면 전체 시스템의 안정성은 크게 높아집니다.
또한 팀 개발 환경에서는 커밋 전에 테스트를 돌려보는 습관만으로도 수많은 장애를 예방할 수 있죠.

💎 핵심 포인트:
유닛 테스트는 단지 코드의 품질을 높이는 도구가 아니라, 전체 개발 프로세스의 생산성과 협업 효율성을 높여주는 핵심 도구입니다.


🛠️ Google Test(GTest) 설치 방법

Google Test(GTest)는 C++ 진영에서 가장 많이 사용되는 유닛 테스트 프레임워크입니다.
구글에서 직접 오픈소스로 관리하고 있으며, 다양한 플랫폼과 빌드 시스템을 지원해 활용도가 매우 높습니다.
간단한 설정만으로도 바로 테스트 코드를 작성하고 실행할 수 있어, 초보자도 쉽게 접근할 수 있다는 장점이 있습니다.

GTest 설치 방법은 사용하는 빌드 도구에 따라 조금씩 다르지만, 대표적으로 많이 사용하는 CMake 기반의 설치 과정을 예시로 들어 설명드릴게요.

CODE BLOCK
# GoogleTest를 FetchContent로 설치하는 CMake 예제
include(FetchContent)

FetchContent_Declare(
  googletest
  URL https://github.com/google/googletest/archive/refs/heads/main.zip
)

FetchContent_MakeAvailable(googletest)

enable_testing()
add_executable(MyTest main_test.cpp)
target_link_libraries(MyTest gtest_main)
include(GoogleTest)
gtest_discover_tests(MyTest)

위 방식은 GoogleTest를 외부 라이브러리로 자동 다운로드하여 프로젝트 내부에 포함시키는 형태입니다.
추가적인 빌드 옵션 없이도 테스트 실행 파일이 생성되며, CTest와 통합하여 CI/CD 환경에서도 손쉽게 활용할 수 있습니다.

💡 TIP: 이미 빌드된 GTest 라이브러리를 사용하는 경우에는 CMake 대신 직접 링크 옵션을 추가하거나 Makefile을 통해 빌드할 수도 있습니다.

GTest 설치가 완료되면 이제부터는 다양한 테스트 케이스를 자유롭게 작성하고, 실행 결과를 통해 코드의 안정성을 높일 수 있게 됩니다.
이제 다음 단계에서는 GTest의 기본 구조와 주요 문법을 함께 살펴보겠습니다.







🔍 GTest 기본 구조와 주요 문법

Google Test는 간결하면서도 확장성 있는 문법 구조를 가지고 있습니다.
기본적인 테스트 함수 하나만으로도 다양한 조건 검증이 가능하며, 필요한 경우 Fixture 기반의 테스트 구성도 지원합니다.
처음 GTest를 접하시는 분들을 위해, 핵심적인 문법 구조를 아래 예제와 함께 정리해볼게요.

CODE BLOCK
// 기본 테스트 예제
#include <gtest/gtest.h>

TEST(MathTest, Addition) {
    EXPECT_EQ(2 + 2, 4);
    EXPECT_NE(2 + 2, 5);
}

위 예제처럼 TEST() 매크로를 사용해 테스트 케이스를 작성할 수 있습니다.
매크로는 TEST(테스트 그룹명, 테스트 이름) 형식이며, 내부에는 여러 개의 검증 구문을 포함할 수 있습니다.

  • EXPECT_EQ(a, b) – 두 값이 같아야 통과
  • EXPECT_NE(a, b) – 두 값이 달라야 통과
  • ⚠️ASSERT_TRUE(condition) – 조건이 true여야 테스트 통과

또한 ASSERT_* 계열은 실패 시 테스트를 즉시 중단하며, EXPECT_*는 실패해도 다음 라인까지 실행되는 차이점이 있습니다.
테스트 목적에 따라 두 가지를 적절히 조합해 사용하는 것이 중요합니다.

💎 핵심 포인트:
GTest는 단순히 검증 도구를 넘어서 테스트 환경 구성, 테스트 반복 실행, 조건 분기 테스트까지 폭넓은 기능을 제공합니다.

기본 구조를 이해했다면, 이제 다음으로는 실전 예제를 통해 실제 테스트 코드가 어떻게 작성되는지를 더 자세히 살펴보겠습니다.


📌 실전 예제로 배우는 테스트 작성법

기본 문법을 익혔다면 이제는 실제 프로젝트 코드에 테스트를 어떻게 적용하는지를 알아볼 차례입니다.
단순한 수학 계산이 아닌, 클래스와 객체를 다루는 예제를 중심으로 테스트 구성 방식을 이해해보겠습니다.

예를 들어, 간단한 Calculator 클래스가 있다고 가정해 보겠습니다.
이 클래스는 덧셈과 나눗셈을 처리하며, 나눗셈에서 0으로 나눌 경우 예외를 발생시킵니다.

CODE BLOCK
class Calculator {
public:
    int Add(int a, int b) { return a + b; }
    int Divide(int a, int b) {
        if (b == 0) throw std::invalid_argument("Divide by zero");
        return a / b;
    }
};

이제 위 클래스를 테스트하는 GTest 코드는 다음과 같이 작성할 수 있습니다.

CODE BLOCK
TEST(CalculatorTest, AddTest) {
    Calculator calc;
    EXPECT_EQ(calc.Add(3, 2), 5);
}

TEST(CalculatorTest, DivideTest) {
    Calculator calc;
    EXPECT_EQ(calc.Divide(10, 2), 5);
}

TEST(CalculatorTest, DivideByZeroTest) {
    Calculator calc;
    EXPECT_THROW(calc.Divide(10, 0), std::invalid_argument);
}

이처럼 실전 테스트에서는 단순한 값 비교 외에도 예외 처리, 경계 조건, 오류 상황까지 폭넓게 검증해야 합니다.
또한 여러 테스트 케이스가 실패 없이 통과할 수 있도록 코드 자체도 테스트 가능하게 구성하는 것이 중요하죠.

⚠️ 주의: 테스트 코드를 작성할 때 너무 많은 로직을 포함하거나, 실제 시스템 환경에 의존하지 않도록 주의해야 합니다. 테스트는 독립적이고 반복 실행 가능해야 합니다.

실전 테스트를 통해 실제 업무에서 발생할 수 있는 다양한 시나리오를 사전에 점검하고, 오류를 줄이는 개발 문화를 만들어갈 수 있습니다.
다음 단계에서는 이렇게 작성된 테스트를 CI/CD에 통합하는 방법을 알려드릴게요.







🚀 CI/CD 파이프라인에 테스트 통합하기

유닛 테스트는 단순히 로컬에서 실행하고 끝나는 것이 아니라, CI/CD 파이프라인에 자동으로 포함되어야 진정한 효과를 발휘합니다.
이렇게 하면 코드가 커밋될 때마다 테스트가 자동으로 실행되어, 오류를 조기에 발견하고 배포 품질을 유지할 수 있습니다.

CI 툴로는 GitHub Actions, GitLab CI, Jenkins, Travis CI 등이 있으며, 대부분 GTest를 손쉽게 통합할 수 있습니다.
그중에서도 GitHub Actions를 예로 들어 간단한 워크플로 구성을 보여드릴게요.

CODE BLOCK
# .github/workflows/test.yml

name: Run GTest on push

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Install Dependencies
      run: sudo apt-get install cmake g++ -y
    - name: Configure
      run: cmake -Bbuild -H.
    - name: Build
      run: cmake --build build
    - name: Run Tests
      run: ctest --test-dir build

이 스크립트는 main 브랜치에 코드가 푸시될 때마다 자동으로 빌드하고, CMake를 이용해 테스트를 실행합니다.
이처럼 CI 환경에 테스트를 연결하면 실수로 인한 오류나 배포 실패를 방지할 수 있습니다.

  • 🔄테스트가 실패하면 배포 중단
  • 📦빌드-테스트-배포 흐름을 자동화
  • 👥협업 중 코드 오류 발생 시 즉시 알림

CI/CD에 테스트를 연동하면 코드 품질이 눈에 띄게 향상되며, 운영 환경으로의 배포 안정성도 보장받을 수 있습니다.
이제 개발팀 전체가 테스트 자동화를 통해 더 안전하고 빠르게 소프트웨어를 릴리즈할 수 있는 환경을 갖추게 되는 셈이죠.


자주 묻는 질문 (FAQ)

Google Test는 꼭 필요한가요?
필수는 아니지만, 중대형 프로젝트에서는 안정성과 생산성을 위해 적극 권장됩니다. 수동 테스트보다 훨씬 정확하고 빠르게 오류를 찾아낼 수 있기 때문입니다.
GTest는 어떤 플랫폼에서 사용할 수 있나요?
Windows, macOS, Linux 등 다양한 운영체제에서 사용 가능합니다. 대부분의 C++ 컴파일러와도 호환되어 환경 제약이 거의 없습니다.
기존 프로젝트에 테스트를 추가하려면 어떻게 하나요?
기존 코드에서 핵심 기능을 함수 단위로 분리하고, 그 부분부터 테스트를 작성해보는 것이 좋습니다. 점차 테스트 커버리지를 넓혀가는 방식이 효과적입니다.
GTest에서 테스트 이름은 어떻게 정하나요?
보통 테스트 그룹명과 케이스명을 조합해 의미 있는 식별자를 사용합니다. 예: TEST(UserTest, LoginSuccess)와 같이 기능 단위로 명확하게 지정하는 것이 좋습니다.
GTest 실행 결과를 보고서로 만들 수 있나요?
네, GTest는 XML 출력 형식을 지원하므로, Jenkins 등과 연동해 테스트 리포트를 자동 생성할 수 있습니다.
EXPECT와 ASSERT의 차이는 뭔가요?
EXPECT는 실패해도 다음 줄로 넘어가지만, ASSERT는 실패 시 테스트 함수가 즉시 종료됩니다. 조건에 따라 적절히 사용해야 합니다.
테스트 속도가 느릴 경우 어떻게 하나요?
테스트는 빠르게 실행될수록 좋습니다. 불필요한 의존성 제거, 더미 객체 활용, 데이터 세트 최소화 등을 통해 속도를 개선할 수 있습니다.
Mock 테스트는 어떻게 활용하나요?
GTest에는 gMock이라는 강력한 모킹 라이브러리가 포함되어 있습니다. 외부 시스템이나 복잡한 객체의 동작을 흉내 내 테스트를 더 효과적으로 진행할 수 있습니다.



🔎 C++ 유닛 테스트 자동화로 얻는 진짜 이점

이번 글에서는 C++에서 유닛 테스트를 어떻게 구성하고, Google Test(GTest)를 활용해 자동화하는 방법을 단계별로 살펴봤습니다.
단순히 테스트 코드를 작성하는 수준을 넘어, 실전 환경에서의 예제 적용, CI/CD 파이프라인 통합까지 함께 다루면서 유닛 테스트의 진정한 가치에 대해 이해할 수 있었죠.

유닛 테스트는 코드를 견고하게 만들고, 변경에 강한 구조로 이끄는 핵심 개발 습관입니다.
특히 협업 환경이나 장기적인 유지보수가 필요한 프로젝트라면 테스트 자동화는 더 이상 선택이 아닌 필수입니다.
Google Test와 같은 도구는 그 과정을 훨씬 쉽게 만들어주며, 개발자의 실수를 줄이고 품질을 높이는 데 큰 역할을 합니다.

앞으로 여러분의 프로젝트에도 유닛 테스트 자동화를 적극 도입해보세요.
코드가 점점 더 자신감 있게 작성되고, 개발이 한층 더 효율적이고 안정적으로 변화할 수 있을 거예요.


🏷️ 관련 태그:C++, 유닛테스트, GoogleTest, GTest설치법, 테스트자동화, CMake, 테스트코드작성, 개발팁, 코드품질, CI/CD연동