ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • google test 로 C++ 단위 테스트 진행기
    개발/C, C++ 2022. 5. 8. 15:26

    테스트 코드를 도입해야겠다고 생각하고, 순전히 하루정도 정말 테스트 코드에 대한 고민을 할 기회가 생겼다.

     

    리눅스 환경에서 C++ 의 테스트 코드를 작성할 때, 어떤 개념으로 이 테스트 코드가 동작하는지 내가 이해한 바를 적어두려고 한다. 

     

    환경은

    CentOS 7에 c++ 11

    테스트는 google test 를 사용하기로 했다.

     

    테스트 프로젝트로 단위 테스트가 없는 프로젝트에 단위 테스트를 넣는 과정은 이 글을 참고하면 된다.

    예제 프로젝트에 테스트 코드를 추가하는 과정과 동작을 직접 확인할 수 있다.

    https://bearnet.tistory.com/22

     

    google test를 테스트 프로젝트에 적용해보기

    테스트 구조는 알았고, 사내에 테스트를 적용을 마쳤다. 이해한 내용을 정리해서 테스트 프로젝트를 하나 작성하고, 이 아이를 "테스트 코드가 없던 프로젝트" 에서 "단위 테스트가 포함된 프로

    bearnet.tistory.com

     

     

    https://github.com/google/googletest/releases

     

    Releases · google/googletest

    GoogleTest - Google Testing and Mocking Framework. Contribute to google/googletest development by creating an account on GitHub.

    github.com

     

    이제 테스트코드가 동작하는 구조를 알아보기 위해 C++를 컴파일하면 일어나는일을 생각해보자

     

    cpp 파일을 컴파일 한 결과물은 목적 파일이다. 실제 클래스가 구현된 소스코드를 컴파일 한 "목적 파일" 을 그대로 가져와서, 테스트 코드와 링크하는 빌드 과정을 거치면, 같은 동작을 하는 클래스를 담은 테스트용 이진 파일이 생성 될 것이다.

     

    약간의 설명을 위한 내용

    cpp-소스파일, o-목적파일, out-결과물(바이너리)

    프로그램 빌드

    myclass.cpp -(컴파일)--> myclass.o

    dbconn.cpp -(컴파일)--> dbconn.o

    main.cpp -(컴파일)--> main.o 

    myclass.o dbconn.o main.o -(링크)--> myproject.out

    테스트 코드의 빌드

    mytest.cc  -(컴파일)--> mytest.o

    mytest.o myclass.o  -(링크)--> mytest.out

    *라이브러리는 설명상 포함하지 않았으나 실제 빌드시에는 알맞는 동/정적 라이브러리 파일을 명시해야한다

     

    즉, myclass.cpp 에 있는 클래스의 단위 테스트를 위해서는 myclass.cpp를 컴파일 해서 나오는 myclass.o 를 그대로 가져가서 테스트 코드에서 사용한다는 뜻이다.

     

    하나의 소스 파일은 컴파일을 거쳐 하나의 목적파일이 된다. 그런데 소스 파일은 다른 소스 파일에 정의된 클래스를 참조하기도 한다. 컴파일러가 소스 파일에 없는 클래스를 아무런 단서 없이 목적 파일로 만들지 않을것이다. 이 "아무런 단서" 는 헤더파일이 제공한다. 코드에 선언한 #include "myclass.hpp" 는 우리가 어떤 단서를 통해 목적 파일을 만들어야 하는지 제공해준다. 그러므로, 이 단서가 되는 헤더를 찾지 못하면 컴파일은 실패한다.

     

    이 내용은 테스트 코드 자체를 작성할 때 필요하다. mytest.cc 파일은 "gtest/gtest.h" 파일을 참조해야하고 클래스를 테스트 하기 위해 "myclass.hpp" 파일도 참조해야 한다. 테스트 대상이 되는 클래스의 목적 파일은 기존에 사용하던 make 절차의 결과물을 그대로 이용해도 된다. 오히려 그대로 이용해야 더 명확한 "테스트" 가 된다.

     

    현재 사내 프로젝트에서 사용하는 구조에 적용해보자.

     

    google test를 빌드해서 설치하는 과정은 생략, 정적 라이브러리로 빌드하고 헤더 파일들을 챙겼다.

     

    현재 내 프로젝트의 최상위 구조는

    bin/ obj/ lib/ src/ pkg_script.sh Makefile

     

    이며, src 내부를 확인해보자면

    myclass.hpp myclass.cpp main.cpp myproject.hpp ext/

     

    방금 만든 디렉토리가 ext/ 이다. 이 안에다 테스트 코드를 수행하는 테스트 바이너리의 main 이 될 코드를 만들고, gtest라는 디렉토리를 만들어서 헤더와 정적 라이브러리 파일을 넣어놓을것이다. 

     

    그렇다면 그 구조는 아래와 같다.

    gtest/ myproject_test.cc

     

    myproject_test.cc 에는 테스트 바이너리의 main 함수가 들어갈것이며, myclass 의 public 메소드들, 즉 인터페이스를 활용해서 테스트 할 것이다. myproject_test.cc 에서 참조해야 하는 헤더는 gtest/gtest.h 와 ../myclass.hpp 파일이다. g++ 동작 시 하위 디렉토리를 소스에 명시하지 않도록 하위 디렉토리는 헤더 참조 위치에 설정한다. myclass.cpp 를 컴파일 할 때 필요한 라이브러리가 있다면, 최종 링크시에 그 라이브러리를 명시해준다.

     

    myproject_test.cc 파일에는 myclass에서 정의한 클래스를 설계한 대로 동작을 테스트 하면 된다.

     

     

    이 테스트 코드를 설계 하는 방법은 책을 읽어보는것을 추천한다. 추천하는 책은 자바 위주로 내용이 작성되어있으나 코드 테스트의 설계에 대한 생각을 하기에는 충분하다.

     

    소프트웨어 개발과 테스트-조대협의 서버 사이드

     

    ISBN: 9788965400936(8965400937)

     

     

     

     

     

Designed by Tistory.