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

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

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

テスト駆動開発による組み込みプログラミング ―C言語とオブジェクト指向で学ぶアジャイルな設計

https://amzn.to/3CGgio3

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

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