Unityのテストフィクスチャフレームワークの使い方を調べてみた

以前、Unityの使い方について記事にしました。そのときは、スクリプトを使っていろいろとテストを書く方法を試したけれども、Unityはスクリプトを使わずにテストフィクスチャを利用する方法もあるみたい。

UnityとCMockの使い方が分かる本『Embedded Testing with Unity and CMock』を読んだ | Futurismo

今日の参考文献は、これです。

テストフィクスチャを使う

Unityには、テストフィクスチャを利用するためのフレームワークが付随している。

/unity/extras/fixture

にあります。これを利用する。このフレームワークはunity_framework.hをunityといっしょに使うことで、テストグループをまとめて実行できたりする。とりあえず、自分の環境で動作するかどうかまずはチェック。

% mkdir build
% rake

20 Tests 0 Failures 0 Ignored OK

 

必要なもの

必要な物は2つ。

  • Unity本体

    • unity/src
  • Unitry Fixuture

    • unity/extras/fixture/src

これらは、Makefileでパスを通して使うので、Unityを適当な場所に配置します。ここでは、$HOME/tools/unityに配置した。

ソースコードとテストコード

今回のソースコードとテストコードはこんな感じで作成した。

ソースコード

// src/hogehoge.c
#include "hogehoge.h"
int hogehoge(void)
{
  return 1;
}

// src/hogehoge.h

ifndef HOGEHOGEH

define HOGEHOGEH

int hogehoge(void);

endif // HOGEHOGEH

テストコード

//test/Testhogehoge.c
#include "unity_fixture.h"
#include "hogehoge.h"

TEST_GROUP(hogehoge);

TEST_SETUP(hogehoge) { }

TESTTEARDOWN(hogehoge) { }

TEST(hogehoge,first) { TESTASSERTEQUAL(1,hogehoge() ); }

TEST(hogehoge,second) { TESTASSERTEQUAL( 2 , (hogehoge() + 1) ); }

TESTGROUPRUNNER(hogehoge) { RUNTESTCASE(hogehoge, first); RUNTESTCASE(hogehoge, second); }

簡単な解説

  • TEST_GROUP

テストグループの宣言。ここではhogehogeという名前。

  • TEST_SETUP

テストグループで共通して実施したい前処理を書く。

  • TEST_TEAR_DOWN

テストグループで共通して実施したい後処理を書く。

  • TEST

テストフィクスチャ本体。ここにテストを書く。

  • TEST_GROUP_RUNNER

テストをまとめて実行するためのグループランナー。

テストランナーとmain関数

テストランナー用のファイル AllTests.cを作成。これは、定形なので、コピペしよう。main関数もココに書く。もし、main関数が自分のコードにすでにあるならば、UnityMainをmain関数から呼び出す。

#include "unity_fixture.h"

static void runAllTests() { RUNTESTGROUP(hogehoge); /** ここにTEST_GROUPを追加していく **/ }

int main(int argc, char* argv[]) { return UnityMain(argc, argv, runAllTests); }

 

Makefileの作成

Makefileを作成します。ポイントは、

  • unity.cとunity_fixture.cをコンパイルすること。
  • unity/srcとunity/extras/fixtureにインクルードパスを通してあげること

でしょうか。

#---- Outputs ----#
TARGET_BASE = hogehoge
TARGET_EXTENSION=.exe
TARGET = $(TARGET_BASE)$(TARGET_EXTENSION)

--- Inputs ----

PROJECTHOMEDIR = . UNITYHOME = $(HOME)/tools/unity UNITYFIXTURE = $(UNITY_HOME)/extras/fixture

C_COMPILER=gcc

Unity File

SRCFILES =$(UNITYHOME)/src/unity.c

Unity Fixture File

SRCFILES +=$(UNITYFIXTURE)/src/unity_fixture.c

Source Files

SRC_FILES += src/hogehoge.c

Test Files

SRCFILES += test/Testhogehoge.c SRCFILES += test/AllTests.c

INCDIRS =-Isrc INCDIRS +=-I$(UNITYHOME)/src INCDIRS +=-I$(UNITY_FIXTURE)/src

SYMBOLS=-DTEST -DUNITYSUPPORT64

CLEANUP = rm -f build/*.o ; rm -f $(TARGET); rm -f $(TARGET2) ; mkdir -p build

all: default

default: $(CCOMPILER) $(INCDIRS) $(SYMBOLS) $(SRC_FILES) -o $(TARGET) ./$(TARGET)

テストの実行

テストを実行すると、テストが通ります。♪(〃’▽’〃)

./hogehoge.exe
Unity test run 1 of 1
..
-----------------------
2 Tests 0 Failures 0 Ignored
OK

おまけ

このフィクスチャの使い方は、テスト駆動開発による組み込みプログラミング ―C言語とオブジェクト指向で学ぶアジャイルな設計のサンプルコードを見るとよく分かる。

サンプルコードは以下からダウンロードできる。

https://pragprog.com/titles/jgade/source_code

これをみると、unity.framework/extras/fixture/build配下に、MakefileWorker.mkというものを配置して、Makefileの最後でインクルードしている。

こっちのやり方のほうが綺麗だな。ディレクトリを指定すれば、配下のファイルを自動でコンパイルしてくれるので。また、オプションによっては、gcovを実行したりもできるっぽい。面白そう!( ^ω^)こんど調べてみよう。

というわけで、サンプルコードをダウンロードして、MakefileWorker.mkを手に入れましょう。自作のMakefileは書いておきます。

#---- Outputs ----#
TARGET_BASE = hogehoge
TARGET_EXTENSION=.exe 
TARGET = $(TARGET_BASE)$(TARGET_EXTENSION) 

--- Inputs ----

PROJECTHOMEDIR = . UNITYHOME = $(HOME)/tools/unity UNITYFIXTURE = $(UNITYHOME)/extras/fixture UNITYBUILDHOME = $(UNITYHOME)/extras/fixture/build

C_COMPILER=gcc

UNITYCFLAGS += -DUNITYOUTPUTCHAR=UnityOutputCharSpyOutputChar

SRCDIRS =
$(PROJECT
HOME_DIR)/src\

TESTSRCDIRS =
$(PROJECTHOMEDIR)/test
$(UNITYHOME)/src
$(UNITY
HOME)/extras/fixture/src\

INCLUDEDIRS =
.
$(PROJECT
HOMEDIR)/src
$(UNITY
HOME)/src
$(UNITYHOME)/src
$(UNITY
HOME)/extras/fixture/src
$(UNITY_HOME)/extras/fixture/test\

include $(UNITYBUILDHOME)/MakefileWorker.mk

 

ついでにgithubにも。

git://github.com/tsu-nera/embedded_testing_with_unity_and_cmock.git