• このエントリーをはてなブックマークに追加

以前、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 _HOGEHOGE_H
#define _HOGEHOGE_H

int hogehoge(void);

#endif // _HOGEHOGE_H

テストコード

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

TEST_GROUP(hogehoge);

TEST_SETUP(hogehoge)
{
}

TEST_TEAR_DOWN(hogehoge)
{
}

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

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

TEST_GROUP_RUNNER(hogehoge)
{
  RUN_TEST_CASE(hogehoge, first);
  RUN_TEST_CASE(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()
{
  RUN_TEST_GROUP(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 ----#
PROJECT_HOME_DIR = .
UNITY_HOME = $(HOME)/tools/unity
UNITY_FIXTURE = $(UNITY_HOME)/extras/fixture

C_COMPILER=gcc

# Unity File
SRC_FILES  =$(UNITY_HOME)/src/unity.c
# Unity Fixture File
SRC_FILES +=$(UNITY_FIXTURE)/src/unity_fixture.c

# Source Files
SRC_FILES += src/hogehoge.c

# Test Files
SRC_FILES += test/Testhogehoge.c
SRC_FILES += test/AllTests.c

INC_DIRS  =-Isrc
INC_DIRS +=-I$(UNITY_HOME)/src
INC_DIRS +=-I$(UNITY_FIXTURE)/src

#SYMBOLS=-DTEST -DUNITY_SUPPORT_64

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

all: default

default:
        $(C_COMPILER) $(INC_DIRS) $(SYMBOLS) $(SRC_FILES) -o $(TARGET)
        ./$(TARGET)

テストの実行

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

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

おまけ

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

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

http://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 ----#
PROJECT_HOME_DIR = .
UNITY_HOME = $(HOME)/tools/unity
UNITY_FIXTURE = $(UNITY_HOME)/extras/fixture
UNITY_BUILD_HOME = $(UNITY_HOME)/extras/fixture/build

C_COMPILER=gcc

#UNITY_CFLAGS += -DUNITY_OUTPUT_CHAR=UnityOutputCharSpy_OutputChar

SRC_DIRS = \
	 $(PROJECT_HOME_DIR)/src\

TEST_SRC_DIRS = \
	      $(PROJECT_HOME_DIR)/test\
	      $(UNITY_HOME)/src\
	      $(UNITY_HOME)/extras/fixture/src\

INCLUDE_DIRS =\
  .\
  $(PROJECT_HOME_DIR)/src\
  $(UNITY_HOME)/src\
  $(UNITY_HOME)/src\
  $(UNITY_HOME)/extras/fixture/src\
  $(UNITY_HOME)/extras/fixture/test\

include $(UNITY_BUILD_HOME)/MakefileWorker.mk
 

 

ついでにgithubにも。

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