Google Test でC言語のプログラムをテストするようにできたのでメモ書き。
C言語でプログラムを書いていて、CUnit でテストコードを書いていたのだけれど、CU_ASSERT_EQUAL などで failure になっても「どんな値で failure になったのか」が分からなかった。Google Test なら
- failure 時に、どういう結果のためにfailure かがわかる
- テストの追加が簡単にできる
- テスト結果が見やすい
ためにやってみた。
以下の手順で行った。各ファイルは最後に書く。
- テスト用 main 関数を作る(test_main.cpp)
- hoge.c にある関数 increment のテストプログラムを作る(test_hoge.cpp)
- hoge.c と test_hoge.cpp, test_main.cpp をコンパイル、リンクする(Makefile)
- このときテスト対象のプログラムは main.c に main 関数が書いてあるため除外した
ひとつハマったのは、C言語で
typedef enum { RED, GREEN, BLUE } COLOR;
などとして、COLOR型を引数に取る関数 bar のテストを
EXPECT_EQ(ERROR_ARGUMENT, bar(3));
と書いていたらエラーが出た。
EXPECT_EQ(ERROR_ARGUMENT, bar((COLOR)3));
とキャストすればOK。問題なくテストできる。
テストは C++ で書くので、COLOR 型の関数はあるけど int 型の関数はないよ!って判断された。
test_main.cpp
#include "gtest/gtest.h" int main(int argc, char *argv[]) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
test_hoge.cpp
#include "gtest/gtest.h" extern "C" { #include "hoge.h" } TEST(foo, testOfFoo) { EXPECT_EQ(1, increment(0)); EXPECT_EQ(2, increment(1)); }
ちなみに、hoge.h は
#ifndef HOGE_H #define HOGE_H int increment(int i); #endif
hoge.c は、
#include "hoge.h" int increment(int i) { return i + 1; }
とした。
最後に Makefile
TARGET=a.out CC = clang CPP = clang++ # ===== テスト対象のプログラム作成用 ===== CFILES=$(wildcard *.c) SRCS=$(CFILES) HEADERS=$(wildcard *.h) OBJS=$(SRCS:.c=.o) INCLUDE=$(addprefix -I./,$(filter-out $(NOMAKEDIR), $(shell find * -type d))) CFLAG = -Wall # ===== テスト用 ===== # ./test をテスト用実行ファイルとする TEST_TARGET=test # テスト対象のソースファイル(.c ファイル) TEST_SRCS_C=$(filter-out main.c, $(CFILES)) # main.c 以外の .c ファイル # テスト用のソースファイル(.cpp ファイル) TEST_SRCS_CPP=$(wildcard *.cpp) TEST_OBJS=$(TEST_SRCS_C:.c=.o) $(TEST_SRCS_CPP:.cpp=.o) TEST_LINK= -lgtest #-------------------- all: $(TARGET) $(TARGET): $(OBJS) $(CC) -o $@ $(LINK) $(OBJS) .c.o: $(CC) $(CFLAG) $(INCLUDE) -c -o $@ $< .cpp.o: $(CPP) $(CFLAG) $(INCLUDE) -c -o $@ $< test: $(TEST_OBJS) $(CPP) -o $@ $(TEST_OBJS) $(TEST_LINK) clean: rm -f $(TARGET) $(TEST_TARGET) *.o