Google test - tutorial (따라하기)

반응형

     

    본 글에서는 C 언어로 작성된 특정 라이브러리의 기능에 대해, google test를 이용한 단위테스트를 수행하는 샘플 프로젝트를 소개한다.

     

    사용된 환경은 다음과 같다.

    • 빌드 및 테스트 실행 환경: Ubuntu 리눅스 16.04 (도커 컨테이너)

    • 단위테스트 툴: google test v1.10.0

    • 빌드 툴: cmake v3.19.2

     

    리눅스에 google test(v1.10.0)을 설치하는 방법은 아래 글에서 확인할 수 있다.

     

    리눅스에 CMake(v3.19.2)를 설치하는 방법은 아래 글에서 확인할 수 있다.

     

    개요

    튜토리얼 프로젝트의 개요는 다음과 같다.

    • 더하기(sum) 기능을 지원하는 라이브러리인 libsum(sum.c, sum.h)을 구현한다.

    • libsum 라이브러리의 더하기 기능을 사용하는 실행 프로그램(sum_app.c)을 구현한다. 

    • google test 를 이용하여 libsum 라이브러리의 더하기 기능을 테스트하는 단위테스트 코드(sum_test.cc)를 구현한다.

    • 단위테스트 코드를 빌드하고 실행하여 각 테스트의 결과가 기대하는 결과와 일치하는지 확인한다.

    • 단위테스트를 통해 수행된 코드 커버리지(Code coverage)를 측정한다.

    • 단위테스트가 성공하면 실제 실행 프로그램을 믿고 실행할 수 있다.

     

     

    라이브러리 코드 구현

    더하기 기능을 지원하는 libsum 라이브러리 코드인 sum.c, sum.h 파일을 다음과 같이 작성한다.  sum 라이브러리 내 API 함수는 C 로 작성되었으므로, C++로 구현된 googe test에서 호출되기 위해서는 API 함수 선언부를 extern "C" 구문으로 감싸 주어야 한다.

    /**
     * @file sum.c
     */
    
    #include "sum.h"
    
    int sum(int a, int b)
    {
      return (a+b);
    }

     

    /**
     * @file sum.h
     */
    
    #ifndef GOOGLE_TEST_SUM_H
    #define GOOGLE_TEST_SUM_H
    
    // C++로 구현된 google test에서 참조/빌드 되기 위해 추가되는 구문
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    int sum(int a, int b);
    
    // C++로 구현된 google test에서 참조/빌드 되기 위해 추가되는 구문
    #ifdef __cplusplus
    }
    #endif
    
    #endif //GOOGLE_TEST_SUM_H
    

     

    실행 프로그램 코드 구현

    libsum의 더하기 기능을 사용하는 실행 프로그램 코드인 sum_app.c 파일을 다음과 같이 작성한다.  본 프로그램은 실제로 더하기 동작을 수행하는 샘플 어플리케이션이다.

    /**
     * @file sum_app.c
     */
    
    #include <stdio.h>
    #include "sum.h"
    
    int main()
    {
      printf("Hello, World! %d\n", sum(1,2));
      return 0;
    }

     

     

    테스트 코드 구현

    libsum의 더하기 API 함수를 테스트하기 위한 테스트 코드인 sum_test.cc 파일을 다음과 같이 작성한다. 확인하고자 하는 조건별로 테스트 함수를 작성한다. 본 튜토리얼에서는 하나의 테스트만을 구현하였다.

    /**
     * @file sum_test.cc
     */
    
    #include <stdio.h>
    #include "gtest/gtest.h"
    #include "sum.h"
    
    /**
     * @brief 작성된 테스트 코드
     * 
     * 테스트하고자 하는 내용을 작성한다.
     */
    TEST(SUM_TEST/*test case name*/, SUM_TEST_1/*test name*/)
    {
      // sum(1,1) 함수 실행 결과가 2와 동일한지 확인한다 - 동일할 경우 테스트 통과, 다를 경우 테스트 실패
      EXPECT_EQ(2, sum(1,1));
    }
    
    /**
     * @brief 테스트 메인 함수. 
     * 
     * 모든 테스트 코드에서 변경없이 아래와 같은 통일된 내용으로 작성한다.
     * RUN_ALL_TESTS() 매크로에 의해, 정의된 모든 테스트함수가 실행된다.
     */
    int main(int argc, char **argv)
    {
      ::testing::InitGoogleTest(&argc, argv);
      return RUN_ALL_TESTS();
    }
    

     

    CMakeLists.txt 파일 작성

    libsum 라이브러리 및 실행프로그램, 테스트 코드를 CMake를 통해 빌드하기 위한 CMakeLists.txt 파일을 다음과 같이 작성한다.

    cmake_minimum_required(VERSION 3.19)
    project(google-test-tutorial)
    set(CMAKE_CXX_STANDARD 11) # google-test 1.10.1 버전을 빌드하기 위해 C++ 11 표준 사용
    
    # gcov 및 lcov를 이용하여 코드 커버리지를 측정하기 위한 설정 추가
    set(CMAKE_C_OUTPUT_EXTENSION_REPLACE ON)
    set(CMAKE_CXX_OUTPUT_EXTENSION_REPLACE ON)
    add_compile_options(-g -O0 -fprofile-arcs -ftest-coverage)
    link_libraries(gcov)
      
    # 더하기(sum) 기능을 지원하는 라이브러리 빌드 (C 코드)
    set(TARGET_LIB sum)
    add_library(${TARGET_LIB} SHARED sum.c)
    
    # 더하기 라이브러리를 이용하는 실행 프로그램 빌드 (C 코드)
    set(TARGET_APP sum_app)
    add_executable(${TARGET_APP} sum_app.c)
    target_include_directories(${TARGET_APP} PRIVATE .)
    target_link_directories(${TARGET_APP} PRIVATE .)
    target_link_libraries(${TARGET_APP} ${TARGET_LIB})
    
    # 테스트 코드 빌드 (C++ 코드)
    set(TARGET_TEST run_sum_tests)
    add_executable(${TARGET_TEST} sum_test.cc)
    target_include_directories(${TARGET_TEST} PRIVATE . usr/local/include)
    target_link_directories(${TARGET_TEST} PRIVATE . usr/local/lib/)
    target_link_libraries(${TARGET_TEST} PRIVATE ${TARGET_LIB} gtest gtest_main pthread)
    
    # 단위테스트 수행 및 코드 커버리지 측정 레포트 생성
    set(COVERAGE_REPORT_DIR coverage_report)
    set(GCOV_FILE_DIR CMakeFiles/${TARGET_LIB}.dir/src)
    add_custom_target(sumtest
                      COMMENT "Execute all unit test cases and generate coverage report"
                      WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
                      DEPENDS ${TARGET_TEST}
                      COMMAND mkdir -p ${COVERAGE_REPORT_DIR}
                      COMMAND rm -rf ${COVERAGE_REPORT_DIR}/*
                      COMMAND lcov -c -d ${GCOV_FILE_DIR} -o ${COVERAGE_REPORT_DIR}/${TARGET_LIB}.cov
                      COMMAND genhtml ${COVERAGE_REPORT_DIR}/${TARGET_LIB}.cov -o ${COVERAGE_REPORT_DIR}

     

     

    빌드

    다음과 같이 libsum 라이브러리 및 실행프로그램, 테스트 코드를 빌드한다.

    root@1a0a902554ba:~/sum# cmake .
    -- The C compiler identification is GNU 5.4.0
    -- The CXX compiler identification is GNU 5.4.0
    -- Detecting C compiler ABI info
    -- Detecting C compiler ABI info - done
    -- Check for working C compiler: /usr/bin/cc - skipped
    -- Detecting C compile features
    -- Detecting C compile features - done
    -- Detecting CXX compiler ABI info
    -- Detecting CXX compiler ABI info - done
    -- Check for working CXX compiler: /usr/bin/c++ - skipped
    -- Detecting CXX compile features
    -- Detecting CXX compile features - done
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /root/sum
    root@1a0a902554ba:~/sum#
    root@1a0a902554ba:~/sum# make
    Scanning dependencies of target sum
    [ 16%] Building C object CMakeFiles/sum.dir/sum.c.o
    [ 33%] Linking C shared library libsum.so
    [ 33%] Built target sum
    Scanning dependencies of target sum_app
    [ 50%] Building C object CMakeFiles/sum_app.dir/main.c.o
    [ 66%] Linking C executable sum_app
    [ 66%] Built target sum_app
    Scanning dependencies of target run_sum_tests
    [ 83%] Building CXX object CMakeFiles/run_sum_tests.dir/sum_test.cc.o
    [100%] Linking CXX executable run_sum_tests
    [100%] Built target run_sum_tests
    root@1a0a902554ba:~/sum#

     

    테스트 실행

    다음과 같이 테스트를 실행한다. 테스트 실행 결과가 화면에 출력된다. 작성한 SUM_TEST.SUM_TEST_1 테스트가 성공했음을 알 수 있다.

    root@1a0a902554ba:~/sum# ./run_sum_tests
    [==========] Running 1 test from 1 test suite.
    [----------] Global test environment set-up.
    [----------] 1 test from SUM_TEST
    [ RUN      ] SUM_TEST.SUM_TEST_1
    [       OK ] SUM_TEST.SUM_TEST_1 (0 ms)
    [----------] 1 test from SUM_TEST (0 ms total)
    
    [----------] Global test environment tear-down
    [==========] 1 test from 1 test suite ran. (1 ms total)
    [  PASSED  ] 1 test.

     

    단위테스트 실행 및 코드 커버리지 측정 레포트 생성

    lcov를 이용하여 코드 커버리지 측정 레포트를 생성하기 위해서는 시스템에 lcov가 설치되어 있어야 한다. 다음  명령으로 설치할 수 있다.

    sudo apt install lcov

     

    CMakeLists.txt 파일의 마지막 부분에 추가한 add_custom_target() 명령에 따라 "make sumtest"를 실행하면 단위테스트가 수행되며, 또한 단위테스트가 진행되면서 실행된 코드들의 코드 커버리지 측정 결과를 담은 레포트가 자동으로 생성된다. 

    make sumtest

     

    빌드 및 단위테스트 실행이 완료되면 CMakeLists.txt의 COVERAGE_REPORT_DIR 항목에 정의된 coverage_report/ 디렉토리에 html 형식의 레포트가 생성되며, index.html 파일을 클릭하면 다음과 같이 레포트를 확인할 수 있다. 참고로 단위테스트가 실패하면 레포트는 생성되지 않는다.

     

     

    어플리케이션 실행

    이제 libsum 라이브러리의 더하기 기능이 테스트를 통해 검증 완료되었으므로, 어플리케이션을 믿고 실행할 수 있다.

    root@1a0a902554ba:~/sum# ./sum_app
    Hello, World! 3

    파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음

    '프로그래밍 > Google Test' 카테고리의 다른 글

    Google test 설치하기  (0) 2020.12.31
    Google Test - 테스트 결과 레포트 만들기  (0) 2020.05.28

    댓글

    Designed by JB FACTORY