Android Studio에서 Google Test로 C++ unit 테스트 작성

Google Test는 오픈소스이며, Native(C++)의 unit test 라이브러리입니다. Google mock으로 객체를 mocking할 수 있고, Assertion 클래스 등을 제공합니다.

Android Studio에서 NDK를 개발할 때 Google test(gtest)를 사용하여 unit test 코드를 작성할 수 있습니다.

안드로이드 스튜디오의 SDK Manager에서 NDK, LLDB, CMAKE를 다운받으면 gtest를 사용할 수 있습니다. (gtest는 소스를 다운받아 사용할 수 있지만 NDK에 기본적으로 소스가 있습니다.) sdk manager ndk in android studio

안드로이드 스튜디오에서 NDK 프로젝트를 만들고 gtest를 설정하는 것에 대해서 알아보겠습니다.

프로젝트 생성

메뉴에서 [New] -> [Project]를 누르고, Native C++를 선택합니다. setup native cpp project in android studio

프로젝트 이름을 설정하고 Next를 누릅니다. config ndk project in android studio

Toolchain Default를 선택합니다. customize cpp support in android studio

이제 NDK 프로젝트가 생성되었습니다.

gtest 설정

src/main/cpp를 보시면 아래와 같은 구조에, 2개의 파일이 있습니다.

CMakeLists.txt는 CMake의 빌드 설정파일입니다. native-lib.cpp는 Java에서 jni로 native를 호출해주는 기본 코드가 있습니다.

└── src
    ├── androidTest
    ├── main
    │   ├── AndroidManifest.xml
    │   ├── cpp
    │   │   ├── CMakeLists.txt
    │   │   └── native-lib.cpp

gtest를 사용하려면 CMakeLists.txt에 gtest를 include하도록 설정해야 합니다. 파일의 맨 아래에 다음과 같이 입력합니다. 이 코드는 NDK에 있는 gtest를 라이브러리로 추가한다는 의미입니다.

set(GOOGLETEST_ROOT ${ANDROID_NDK}/sources/third_party/googletest/)
add_library(gtest STATIC ${GOOGLETEST_ROOT}/src/gtest_main.cc ${GOOGLETEST_ROOT}/src/gtest-all.cc)
target_include_directories(gtest PRIVATE ${GOOGLETEST_ROOT})
target_include_directories(gtest PUBLIC ${GOOGLETEST_ROOT}/include)

테스트 코드 구현

이제 테스트 코드를 구현해야 합니다.

main/cpp/에 다음과 같이 3개의 파일을 추가할 것입니다.

├── CMakeLists.txt
├── foo.cpp
├── foo.h
├── foo_unittest.cpp
└── native-lib.cpp

아래와 같이 파일을 만들고 코드를 입력해주세요.

foo.h

extern int foo(int x, int y);

foo.cpp

int foo(int x, int y) {
    return x + y;
}

foo_unittest.cpp

#include <gtest/gtest.h>
#include "foo.h"

TEST(FooTest,ZeroZero) {
    EXPECT_EQ(0, foo(0, 0));
}

TEST(FooTest,OneOne) {
    EXPECT_EQ(2, foo(1, 1));
}

코드를 모두 입력하였으면, foo_unittest.cpp를 executable로 만들어야 합니다.

CMakeLists.txt의 마지막에 다음과 같이 입력합니다.

add_library(foo SHARED foo.cpp)               # 1
add_executable(foo_unittest foo_unittest.cpp) # 2
target_link_libraries(foo_unittest gtest foo) # 3
  1. foo.cpp로 foo 라이브러리를 만듭니다.
  2. foo_unittest.cpp를 executable로 만듭니다.
  3. foo_unittest에 gtest와 foo 라이브러리를 linking합니다.

빌드 및 테스트

구현은 모두 끝났습니다. 이제 빌드를 하면 다음과 같은 파일들이 생성됩니다.

./app/.externalNativeBuild/cmake/debug/x86_64/foo_unittest
./app/build/intermediates/cmake/debug/obj/x86_64/libfoo.so

파일들을 adb로 디바이스에 넣고 실행시키면 테스트를 수행합니다.

$ adb push app/build/intermediates/cmake/debug/obj/x86_64/libfoo.so /data/local/tmp/
$ adb push app/.externalNativeBuild/cmake/debug/x86_64/foo_unittest /data/local/tmp/
$ adb shell chmod 775 /data/local/tmp/foo_unittest
$ adb shell \"LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/foo_unittest\"

테스트가 완료되면 다음과 같은 결과를 터미널에 출력합니다.

[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from FooTest
[ RUN      ] FooTest.ZeroZero
[       OK ] FooTest.ZeroZero (0 ms)
[ RUN      ] FooTest.OneOne
[       OK ] FooTest.OneOne (0 ms)
[----------] 2 tests from FooTest (0 ms total)

[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (0 ms total)
[  PASSED  ] 2 tests.

이 글에서 사용한 예제는 GitHub - GoogleTestWithNDK에서 확인할 수 있습니다.

참고

Loading script...

Related Posts

codechachaCopyright ©2019 codechacha