読者です 読者をやめる 読者になる 読者になる

Jの衝動書き日記

さらりーまんSEの日記でございます。

C++テストのカバレッジメモ

仕事

JUnitでお馴染みの、ソースのカパレッジレポートをC++のソースで行う時のメモである。
メモの環境は、cygwinのもの。

準備

lcovをインストールする。
URL: http://ltp.sourceforge.net/coverage/lcov.php

cd /tmp
tar zxf lcov-1.8.tar.gz
cd lcov-1.8
make install


lcovはperlのスクリプトなので、DOS窓からは実行出来ない(出来ないことは無いが、パスがややこしいことになるので面倒)。cygwin窓から行うことにする。
このため、makefileを作成 → eclipseで実行が出来ない。cygwin上でeclipseワークスペースを作り、cygwin窓から実行という手順で行う。

レポート作成手順

  1. C++ソースをコンパイルする時、オプションで-fprofile-arcs -ftest-coverageを付ける
  2. リンク時も同様に-fprofile-arcs -ftest-coverageを付ける
  3. 作成したバイナリを実行する
  4. lcovでlcov.infoファイル(レポートファイル)を作成する
  5. genhtmlでlcov.infoをhtml形式に整形する

コンパイルすると、*.oファイルの他に、*.gcnoファイルが出来る。バイナリを実行すると、さらに*.gcdaファイルが出来ればOK。
ちなみに、実行する前に lcovでレポートファイルを作る前に lcov --zerocountersを実施せよと書いてあるが、cygwin上だと*.gcdaファイルが消えてしまい、レポートファイルが作成出来ない。バイナリ実行前に lcov --zerocountersを実行すればOKっぽいのでそうしている。

以下、makefileのサンプル。

# ソースの場所設定
# 自分の環境に置き換える
BASE_DIR = /home/hoge/eclipse/c++/SampleCppUnit
INC_DIR = ${BASE_DIR}/src
SRC_DIR = ${BASE_DIR}/src
TEST_BASE_DIR = ${BASE_DIR}/test
TEST_SRC_DIR  = ${TEST_BASE_DIR}/src

# Unit Test関連の設定
UNIT_BIN_NAME  = SampleCppUnit
UNIT_BASE = ${UNIT_BIN_NAME}
UNIT_BUILD = ${UNIT_BASE}/build
UNIT_DOC   = ${UNIT_BASE}/doc
UNIT_BIN   = ${UNIT_BASE}/bin

# テスト対象ソース
OBJS = ${UNIT_BUILD}/SampleInfo.o 
# テストソース
TEST_OBJS = ${UNIT_BUILD}/Test.o ${UNIT_BUILD}/TestSampleInfo.o
LIBS = -lcppunit
BUILD_OPTS = -O0 -g3 -Wall -fprofile-arcs -ftest-coverage
LINK_OPTS = -fprofile-arcs -ftest-coverage

# 単体試験実施・レポート出力
all: test report

# レポートファイルの作成
# cygwin上で実施する場合,lcov -d ${UNIT_BUILD} --zerocountersはコメントアウトすること
report:
#	lcov -d ${UNIT_BUILD} --zerocounters
	lcov -d ${UNIT_BUILD} --capture --output-file ${UNIT_BUILD}/lcov.info
	genhtml --output-director ${UNIT_DOC}/report ${UNIT_BUILD}/lcov.info
	cd ${UNIT_BASE} ; tar zcf doc.tgz doc ; 
	
# 単体試験実施・レポート出力無し
test: init build
	${UNIT_BIN}/${UNIT_BIN_NAME}

# コンパイルの実施
build: ${OBJS} ${TEST_OBJS}
	g++ -o ${UNIT_BIN}/${UNIT_BIN_NAME} ${OBJS} ${TEST_OBJS} ${LIBS} ${LINK_OPTS}

#テスト対象のソースのコンパイルルール
${UNIT_BUILD}/%.o: ${SRC_DIR}/%.cpp ${INC_DIR}/*.hpp
	g++ -I"${INC_DIR}" ${BUILD_OPTS} -c -o"$@" "$<"

#テストソースのコンパイルルール
${UNIT_BUILD}/%.o: ${TEST_SRC_DIR}/%.cpp
	g++ -I"${INC_DIR}" ${BUILD_OPTS} -c -o"$@" "$<"

#初期化
init:
	if [ ! -d ${UNIT_BASE} ] ;\
	then \
		mkdir ${UNIT_BASE} ; \
		mkdir ${UNIT_BIN}; \
		mkdir ${UNIT_BUILD} ; \
		mkdir ${UNIT_DOC} ; \
	fi

#クリア

clean:
	rm -rf ${UNIT_BASE}