モデリングカフェ 第4回のテーマ【テスト駆動開発】のモデリングの過程

# この記事は何?
**モデリングカフェ**をご存知でしょうか?

オージス総研が企画、進めている**身近にあるモノや出来事など、簡単な【お題】を出題し、モデリングを楽しむ活動**です。
第4回のテーマは**テスト駆動開発**のモデリングです。

https://www.ogis-ri.co.jp/otc/hiroba/others/ModelingCafe/re04.html

2024年度にUMTPレベル3取得を目標にしていることもあり、モデリングに関する情報はアンテナを張りチェックしていました。

* TDDに興味がある
* TDDのモデリングがどうなるか興味深い

上記理由からTDDのモデリングをすることに決めました。
モデリングする際の気づきや考え、モデルの背景などモデリングの過程を記事にしてみたいと思います。

# 回答モデルの送付について
回答モデルの送付についてです。

## 提出する図
クラス図とオブジェクト図を提出します。

## その他、回答が必要なこと
モデル図と共に下記の説明をつける必要があります。

* モデルのコンセプト
* 難しかったところ
* モデルについて自己評価

# 回答モデル
この記事では回答モデルを先に示し、この章の後にモデリングの過程を書きます。

## モデルのコンセプト
* 自分が書籍（テスト駆動開発による組み込みプログラミング―C言語とオブジェクト指向で学ぶアジャイルな設計）から学んだ具体的なTDDの手法、技術に焦点をあてオブジェクト図、クラス図をボトムアップ的（具体化→抽象化の思考で）に作成する。
* TDD全体像が理解できるようなモデルをつくる。

## モデル
### オブジェクト図
![TDD_オブジェクト図_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171866/de1de31b-ae28-b8ce-cbe3-d7e9fc89739f.png)

### クラス図
![TDD_クラス図_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171866/cb7cefc4-5acf-a588-4100-e2aade96b908.png)

## 難しかったところ
モデルのコンセプトをどう定義するか?が難しかったです。

## モデルについて自己評価
* コンセプトに近いものができたという認識なので満足はしています。
私のモデルは実際にテスト駆動開発の行う際に登場するもの（テストフレームワークCppUTest、テストファイル、テストグループ、テストコード、プロダクトファイル、プロダクトコードなど）に注目しました。
具体的なモデルで、**テスト駆動開発はどのような要素で構成されているかという技術的な観点に注目している**と思いました。

* 私のモデルとは違い、テスト駆動開発の実現手段に注目しないという方針もあると思います。テスト駆動開発は何をするものか、何の課題を解決できるのか、テストする人に何を提供するのかという視点でモデル化する方針もあると思います。

* 私が作成したモデルはテストフレームワークCppUTestに強く影響をうけています。JUnitなど他のテストフレームにはフィットしないモデルとなっています。どのテストフレームワークにも適応するモデルがつくれれば良かったと思いました。


# モデリングの過程
モデリングカフェに提出する回答モデル（オブジェクト図・クラス図）を作成するにあたり、モデルを作成する過程で考えたことを明確にしたいと思います。

## コンセプトの検討
以前からテスト駆動開発は個人的に気になっていた技術だったので、下記の本の写経で学習をしたり、学んだことをアウトプットしたりしていました。

* テスト駆動開発の学習に使っている本 その1
>テスト駆動開発による組み込みプログラミング
―C言語とオブジェクト指向で学ぶアジャイルな設計
James W. Grenning　著、蛸島 昭之　監訳、笹井 崇司　訳
https://www.oreilly.co.jp/books/9784873116143/


* テスト駆動開発の学習に使っている本 その2
>テスト駆動開発
著者 Kent Beck 著、和田 卓人 訳
https://www.ohmsha.co.jp/book/9784274217883/

* 学びのアウトプット
>Docswellにアップロードしたスライドでタイトルに【組み込みソフトウェア基礎】, 【テスト駆動開発】が含まれるもの
https://www.docswell.com/user/juraruming

私の仕事が組込みソフトウェア開発ということもあり、1つ目の本に時間をかけて学びました。こちらの本で学んだことをベースにモデルのコンセプトを考えてみることにしました。

以上をコンセプトとして言語化します。

:::note info
コンセプト：
* 自分が書籍（テスト駆動開発による組み込みプログラミング―C言語とオブジェクト指向で学ぶアジャイルな設計）から学んだ具体的なTDDの手法、技術に焦点をあてオブジェクト図、クラス図をボトムアップ的（具体化→抽象化の思考で）に作成する。
* TDD全体像が理解できるようなモデルをつくる。
:::


## オブジェクト図
コンセプトに則り、オブジェクト図を作成していきます。

テスト駆動開発の学習に使っている本 その1　**テスト駆動開発による組み込みプログラミング**に書かれている**LEDドライバ**をテーマにしました。
過去に本の写経をしていたのでこちらのテストコード、プロダクトコードを参考にオブジェクト図を書いていくことにしました。

>テストコード
https://github.com/grace2riku/TDD_EmbeddedC_HomeAutomation/blob/main/tests/LedDriver/LedDriverTest.cpp
テスト名: LedsOffAfterCreate, TurnOnLedOne, IsOn


>プロダクトコード
https://github.com/grace2riku/TDD_EmbeddedC_HomeAutomation/blob/main/src/LedDriver/LedDriver.c
該当関数: LedDriver_Create, LedDriver_TurnOn

本ではテストはテストリストから作成することが書かれています。
今回は下記のテストリストの中の一部を対象にオブジェクトを書きます。

```
LEDドライバのテスト
◻︎ ドライバを初期化したら、すべてのLEDがオフになる
◻︎ 1つのLEDをオンできる
◻︎ LEDの状態を問い合わせる
```

テストリストとテスト名の対応はつぎになっています。

```
LEDドライバのテスト
◻︎ ドライバを初期化したら、すべてのLEDがオフになる → LedsOffAfterCreate
◻︎ 1つのLEDをオンできる → TurnOnLedOne
◻︎ LEDの状態を問い合わせる → IsOn
```

### オブジェクト図（1回目）
この記事の目的はモデリングの過程を明らかにすることなので、完成途中のモデルも共有したいと思います。
1回目のオブジェクト図は下図です。

![TDD_オブジェクト図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171866/19cfe8c8-b487-be20-8ccc-1569a065ec5f.png)

### オブジェクト図（2回目）
1回目のオブジェクト図を書いた後に全体を確認していて、つぎの点が気になりました。

* テストはテストリストを元に書かれる。そのことが表現されていない。
* テスト駆動開発のステータス レッド・グリーン・リファクタリングがない。これが表現されていないのはテスト駆動開発のモデルとは言えないと思った。

上記を反映したのが下図のオブジェクト図です。

![TDD_オブジェクト図_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171866/de1de31b-ae28-b8ce-cbe3-d7e9fc89739f.png)

このオブジェクト図はグリーン（すべてのテストが成功している）を示していることを意識して書きました（実行ファイル:LedDriverTestがグリーンと関連があるところ）。

## クラス図
コンセプト通りボトムアップの考え方でオブジェクト図からクラス図を作成します。

### クラス図（1回目）
1回目のクラス図は下図です。

![TDD_クラス図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171866/24bd992e-f577-1c18-23c5-b618b800687c.png)

### クラス図（2回目）
1回目のクラス図を再確認し、違和感を感じたところを変更しました。
変更したところは下図の赤枠です。

![TDD_クラス図_2_diff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171866/bdb58565-de16-1c63-485a-ed1fd3327d4f.png)

#### 変更点1. テストリストの要件（Requirement）とテスト（Test）の多重度
テストリストの要件（Requirement）とテスト（Test）の多重度を変更しました（1..*から0..*に変更）。
要件を満たすテストがまだ書かれていないこともあるかと思ったので0..*に変更しました。

#### 変更点２. テストコードのファイル（TestCodeFile）からテストグループ（TestGroup）の多重度
もうひとつ、テストコードのファイル（TestCodeFile）からテストグループ（TestGroup）の多重度を変更しました（0..*から1..*に変更）。
テストコードのファイルにはテストグループが必須なので1..*に変更しました。

#### 変更点3. クラス名
TestGroupUtilityからTestGroupFixtureにクラス名を変更しました。
TestGroupUtilityクラスが指すものは下記のコード例でいうとTEST_GROUP(LedDriver)の中で定義されている変数、関数（virtualLeds, setup(), teardown()）です。

```cpp:LedDriverTest.cpp
TEST_GROUP(LedDriver)
{
    uint16_t virtualLeds; // TEST_GROUPの中の変数はTEST_GROUPで共有できる
    void setup()  // setupは各TEST実行の際に呼び出される
    {
      LedDriver_Create(&virtualLeds);
    }

    void teardown()
    {
    }
};

TEST(LedDriver, LedsOffAfterCreate)
{
  virtualLeds = 0xffff;
  LedDriver_Create(&virtualLeds);
  LONGS_EQUAL(0, virtualLeds);
}

TEST(LedDriver, TurnOnLedOne)
{
  LedDriver_TurnOn(1);
  LONGS_EQUAL(1, virtualLeds);
}
```

>テストコード
https://github.com/grace2riku/TDD_EmbeddedC_HomeAutomation/blob/main/tests/LedDriver/LedDriverTest.cpp

この中で定義した変数・関数は同じテストグループの中でのみ使える、影響します。
具体的には次の動きになります。

* LedDriverテストグループのLedsOffAfterCreateテスト、TurnOnLedOneテストの実行前にsetup()が実行される
* LedsOffAfterCreateテスト、TurnOnLedOneテストの中でvirtualLedsが参照できる

本ではvirtualLeds, setup(), teardown()をテストフィクスチャ（Test fixture）と説明していました。こちらの名称の方が適切だと感じたのでクラス名称を変更しました。


## 難しかったところ
モデルのコンセプトをどう定義するか?が難しかったです。


## モデルについて自己評価
* コンセプトに近いものができたという認識なので満足はしています。
私のモデルは実際にテスト駆動開発の行う際に登場するもの（テストフレームワークCppUTest、テストファイル、テストグループ、テストコード、プロダクトファイル、プロダクトコードなど）に注目しました。
具体的なモデルで、**テスト駆動開発はどのような要素で構成されているかという技術的な観点に注目している**と思いました。

* 私のモデルとは違い、テスト駆動開発の実現手段に注目しないという方針もあると思います。テスト駆動開発は何をするものか、何の課題を解決できるのか、テストする人に何を提供するのかという視点でモデル化する方針もあると思います。

* 私が作成したモデルはテストフレームワークCppUTestに強く影響をうけています。JUnitなど他のテストフレームにはフィットしないモデルとなっています。どのテストフレームワークにも適応するモデルがつくれれば良かったと思いました。