2015년 1월 16일 금요일

Bamboo를 이용한 테스트 자동화 삽질 이야기

요구사항

  • 프로젝트는 C로 개발한다.
  • 테스트는 googletest로 한다.
  • Bamboo를 이용한 일일빌드 시스템을 만든다.

이번 달 부터 새로운 프로젝트를 작은 인원으로 시작한다. 자료조사와 문서 정리 외에 '일일빌드'시스템을 만들어야 하는 과제가 내려졌다. 필요성은 잘 알고 있었기에 1.5일간에 걸친 삽질을 통해 완료했다. 프로젝트가 본격 개발에 들어가기 전이라 별 내용은 없으나, 이 후 개발에 많은 도움이 될 것이라 만족도는 상당히 높다.

상황

googletest는 사용법이 간단하기도 하고, 간간히 쓰고 있기 때문에 문제될 것은 없다. Bamboo는 타부서에서는 사용하고 있지만 우리 부서는 제한적으로 사용중이고 나는 제한적인 부분에도 포함되지 않는 완전 초보다. 우리 부서 동료분의 도움을 받아 진행한다.

시나리오

  1. Bamboo에서 소스를 내려받는다.
  2. 소스와 테스트 코드를 빌드한다.
  3. 테스트를 실행한다.
특별한 시나리오는 없다. Bamoo에 Plan을 만들고, Job을 등록하고, 잘 돌아가게 설정하면 끝!
다만, 잘 돌아가게 설정하는 삽질이 많이 필요했다.

Bamboo에서 소스 내려 받기

소스 내려 받기 위해선 당연히 소스는 서버에 있어야 한다. 우리 프로젝트는 SVN은 버리고 Git을 사용하기로 하고 계정과 저장소를 요청해서 받았다. 간단한 C코드와 테스트 코드를 작성하고, commit & push.

소스와 테스트 코드 빌드

길고 힘든 삽질이 계속되었다.
빌드를 위한 Toolchain이나 script의 선택이 있어야하나, 다른 부서가 CMake 사용하는 것을 보고 왠지 멋져 보였음 따라하기로 한다.
프로젝트 Root에 CMakeLists.txt를 만들고, 내용을 입력한다.

cmake_minimum_required(VERSION 2.8)
project(project_name)

set(CMAKE_VERBOSE_MAKEFILE on)

include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/internal_utils.cmake)

if(MSVC)
#We statically link to reduce dependancies
foreach(flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
    if(${flag_var} MATCHES "/MD")
        string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
    endif(${flag_var} MATCHES "/MD")
    if(${flag_var} MATCHES "/MDd")
        string(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}")
    endif(${flag_var} MATCHES "/MDd")
endforeach(flag_var)
endif(MSVC)

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/test/gtest-1.7.0)

set(ENGINE_SOURCE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src)
set(ENGINE_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include)
set(TEST_SOURCE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/test)

INCLUDE_DIRECTORIES(${ENGINE_INCLUDE_DIRS})

INCLUDE_DIRECTORIES(${ENGINE_SOURCE_DIRS})
add_subdirectory(test)
처음엔 googletest를 미리 빌드하고 lib만 추가하려고 했으나, 그러면 cross-platform을 제대로 지원하지 못하게 되는데다가, googletest에 CMake script가 잘 되어 있어서 굳이 빌드한 것을 가져다 쓸 필요가 없다.
소스가 있는 폴더를 add_subdirectory 하면 googletest 준비는 완료.
test가 있는 폴더를 add_subdirectory 해 준 후, 해당 폴더에 CMakeLists.txt를 하나 더 생성


INCLUDE_DIRECTORIES(${gtest_SOURCE_DIR}/include)

add_executable(exec_test test_sources)
target_link_libraries(exec_test gtest_main)

여기까지 하면 빌드 준비 끝!
사실 여기까지 반나절 가량 걸린 듯 하다. 결국 집에서 구글링하다 찾은 https://schneide.wordpress.com/2014/01/27/integrating-googletest-in-cmake-projects-and-jenkins/ 아니었으면 훨씬 더 오래 걸렸으리라..

그리고 생성된 빌드 스크립트로 빌드하면 되는데, 몇번의 삽질 끝에 MSBuild로 간단히 해결되었다. 물론 MSBuild를 쓴 이유는 test 코드에 윈도우 라이브러리를 사용해서 메모리 릭을 확인하는 코드가 있어서 어쩔수 없었고, CMake도 윈도우용을 사용했다.
처음엔 빌드하는데 Toolchain이 없어서 삽질을 했고(http://stackoverflow.com/questions/13596816/how-can-i-generate-a-visual-studio-2012-project-targeting-windows-xp-with-cmake), CMake에
-G "Visual Studio 11" -T "v100" 
를 추가해서 해결되었다.

제대로 빌드가 되면 CMakeLists.txt에 적어준 대로 "exec_test.exe" 파일이 생성된다.

 

테스트 실행

스크립트를 통해 실행하면 테스트가 진행되고, 그냥 두면 console에 출력하고 끝나버린다. 게다가 우리 테스트 코드에는 system("pause"); 코드가 들어있어서, "아무키나 누르세요"하고 기다리게 되고, task가 진행되지 않는 상황이 생겼다. console에 출력되는 내용을 xml로 보내기 위해
exec_test --gtest_output=xml:testresults.xml
를 추가하고, 대기상태에 있는 것은 Bamboo의 Script Argument에
/c < nul
를 추가하는 것으로 해결했다.
마지막으로 생성된 testresults.xml을 Bamboo의 JUnit Parser로 보내서 테스트 결과를 점검하게 하면 완료되겠다. 마지막으로, googletest를 작성할 때 testname에 한글을 넣어도 잘 동작하지만, JUnit Parser는 제대로 파싱하지못하고 실패하는 문제가 있었다. 파싱 실패 원인을 찾느라 또 삽질

댓글 없음: