オブジェクトの広場はオージス総研グループのエンジニアによる技術発表サイトです

モデリング

モデリングカフェ 第5回:テスト駆動開発(回答編)

~UMLでモデリングを愉しもう~
技術部ビジネスイノベーションセンター 原田 巌
コンサルティング・サービス部 赤坂 英彦
2025年3月31日

毎回、身近にあるモノや出来事など、簡単な【お題】を出題し、皆様にモデリングをしていただいています。お題の次の記事で、皆様の回答モデルの中から2、3個取り上げて、コメントを付けていくかたちで進めています。今回の第5回は前回の「お題:テスト駆動開発」を回答していきます。編集員からも考えた回答例を出しています。モデルに完璧な正しさというのはないと思っているので、モデリングした人の意図とモデルが合っているか、よりよいモデルにするにはどうしたら良いかをワイワイ発信できれば幸いです。

目次

  1. 前回の問題 (テスト駆動開発)
  2. 読者回答モデル
  3. 回答例
  4. プレゼント企画
  5. さいごに

1.前回の問題 (テスト駆動開発)

前回の問題をもう一度確認しておきましょう。

【お題02】テスト駆動開発のおさらい

いきなりですが、少し前の話です。

筆者らは、2024年9月28日にXP祭り2024で『UMLモデリングカフェ実演』というモデリングワークショップを実施しました。ワークショップ後、近くのソファで休みながら次のモデリングカフェのお題の話をしていたところ、近くで『TDDトレーニング』が行われていました。

そこで、

「『テスト駆動開発』って何やっているかわかる?」

という議論をきっかけに自然とモデリングしていたモデリングカフェ常連の2人だったのでした。
そこで、今回のお題です。

【お題02】テスト駆動開発

テスト駆動開発 (てすとくどうかいはつ、英: test-driven development; TDD) とは、プログラム開発手法の一種で、プログラムに必要な各機能について、最初にテストを書き(これをテストファーストと言う)、そのテストが動作する必要最低限な実装をとりあえず行なった後、コードを洗練させる、という短い工程を繰り返すスタイルである。 https://ja.wikipedia.org/wiki/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA

テスト駆動開発のイメージ
(画像は Canva AI で作成)


「テスト駆動開発」について語ろうとすると、視点や関心の違いなどから多くの議論が巻き起こりそうです(いろんなモデルが登場しそうで楽しみです♪)。
私自身は、設計や実装の方法として「テスト→実装」の細かいサイクルと分かりやすさが好きで、その繰り返しの中で、RED → GREEN → REFACTORINGのように、コードを洗練させていくのも気持ちがいいと感じています。

さて今回も、回答はクラス図とオブジェクト図で表現してください。クラスには必要な属性を、関連には多重度を明記するのがポイントです (回答時間の目安は30分です)。

2.読者回答モデル

今回も、読者の皆様から、たくさんの回答モデルをいただきました。ありがとうございました。その中から2つの回答モデルを、当カフェのヒトクセある!?常連たちの声を交えながら紹介いたします。コーヒーなどを飲みながら、皆様も一緒にわいわいやる感じで考えてみてください。

また、残念ながら紹介できなかった回答モデルはどこかで掲載できるよう企画を考えていこうと思っております。掲載のなかった方は、お待たせして申し訳ございませんが、ご了承いただければ幸いです。

読者モデル1:ヴァンダイン様

【モデルのコンセプト】

  • TDDでは、製品IF仕様を確認しながら先にテストコードを実装する(テストコードは1回でfixする前提とした)。
  • テストコードには、複数のテストケース(各機能のテスト)が存在する。
  • 製品IF仕様(≃テストコード)を元に製品コードを実装する。
  • テストコードと製品コードの実装を突合せてテストを実施し、テストケース毎にテスト結果を得る。
  • 各テストケースの判定結果をリスト化する。
  • 判定結果リストを確認し、全ての判定がOKになるまでコードの洗練を繰り返す(コードの洗練も製品コード実装に包含した)。
  • 製品コード実装はバージョンで管理する。

【難しかったところ】

  • 「最初にテストを書く(テストファースト)」の表現
  • 「そのテストが通るように実装(コードを洗練)する」の表現
  • オブジェクト図を綺麗に記載すること
投稿01_オブジェクト図
オブジェクト図(クリックすると別ウィンドウで拡大表示します)


投稿01_クラス図
クラス図(クリックすると別ウィンドウで表示します)

【モデルについての自己評価】

  • 30点 TDDではない一般的な開発モデルとも捉えることができそうなため。

【モデルについてのコメント】

常連A- オブジェクト図を詳細に書いてくれていることが嬉しいですね。テスト駆動開発を行ったときに何に対してどんな事が起こっているのか分かりやすいです。活動に対してバージョン管理して、コードやテスト結果を管理する思いが伝わってきますね。

常連B- 確かに。普段の仕事を思い浮かべながら考えたのかもしれないですね。

常連A- 一方で、バージョンが最初の「ver0.0.0.1」のオブジェクト構造しかないので、次のアクションがあった時にどのような変化があるか考えると新しい発見があったかも。例えばNGだった結果がOKに変わったところまで見ると、自分がどこまで何を管理したいのか分かったかもしれないです。

常連B- 確かに。前回の「サウナでととのう」の回答編に書いたように、サ活1回目、サ活2回目、途中で体調を崩した場合、のように「全てNG、一部NG、全てOK」だったり、「テストケース追加」や「リファクタリング実施」のような場面も考えると深い思考ができそう。

常連A- 細かくシーンに分けて考えると関係性も「1対1」ではなく、ソフトウェアライフサイクルを考えると「0」の場面も多そうです。「1対1」というのは強い制約だと思っていて、片方が存在する時にはもう片方も存在することになるので…。

常連B- クラス図はどうですか?

常連A- 仕様とテストの関連がよいですね。仕様を実現するためのテスト、つまりはコードをチェックするためのテストではなく、満たすべき仕様をテストされてクリアできるような製品コード実装が必要である設計行為であることが分かります。

常連B- そうですね。製品IF仕様、テストコード実装、テスト実施、製品コード実装の関係は良い感じです。

常連A- ただ、名称が「実装」や「実施」というコトになっていて、コト同士の多重度やコトに対するモノの関係(例:テストコード実装ーテストケース、製品コード実装ー判定結果リスト)はモヤッとしました。

常連B- 多分、テストコード実装や製品コード実装は、それぞれコード、Javaならクラスのようなものをイメージしているのかもしれませんね。

常連A- その意味だとテスト結果と判定結果も一見すると悩ましい名称なので、テスト結果をテスト出力にして、テストケースに対する判定結果がどうなのかのようにすると伝わりやすそうです。

常連B- 日本語は難しい…。

常連A- あと、「テストコード実装ーテスト実施ー製品コード実装」の関係と同様に、「テストケースーテスト結果」を「テストケースーテスト結果ー製品コード」のような関係にして、「テストケース」に対応する「製品コード」を表現してもよかったかもしれない。

常連B- なるほど、構造的にもすっきりして、対応が分かりやすくなりそうです。

読者モデル2:酒飲むのやめねばならん様

【モデルのコンセプト】

  • 1つの機能には、複数のテストコードが存在する。
  • テストコードを実行することでテスト結果が分かる。
  • 実装コードが存在するには、必ずテストコードが存在しなければならない。

【難しかったところ】

MSUnitを想像しながらモデリングしました。1つの機能に対してのテスト結果(全て成功したか、失敗があるか)をどこかに表現したかったのですが、表現できませんでした。

投稿02_オブジェクト図
オブジェクト図(クリックすると別ウィンドウで拡大表示します)


投稿02_クラス図
クラス図(クリックすると別ウィンドウで拡大表示します)

【モデルについての自己評価】

テスト駆動開発のモデリングとしては、75点ぐらいですかね。

【モデルについてのコメント】

常連B- こちらのオブジェクト図は、機能1がテストコードしかないシーン、機能2がテストコードと実装コードが揃っているシーン、機能3が実装コードがなくテストが失敗するシーンのように複数のシーンを表現してくれているようですね。

常連A- オブジェクト図でのスケッチや様々な時点の様子を分析することでモデリングする対象の理解が進みますね。

常連B- ちょっと機能とテストコードの関係が気になりました。クラス図側を見ても多重度はありますが、関連名が欲しい気がします。

常連A- 要件に紐づく機能群なので、機能を満たしていると言えるテストコード(テストケース)かもしれないです。

常連B- んー。「テストコード」と「実装コード」を結びつける「テスト結果」の捉え方が難しい気がしました。もしかしたら、「テスト結果」をコトとして捉えると構造が分かりやすいのかな、と。

常連A- なるほど。「テスト結果」をコトとして捉えると、実行している「テストコード」とテストの対象となる「実装コード」の関係と考えるとスッキリしそうです。

常連B- ただ、その意図があったのか、分からないですね。

常連A- そうですね。その関係性にすると最初に見たヴァンダインさんのモデルの「テストコード実装」-「テスト実施」-「製品コード実装」と形や意味が近くなりそうです。

常連B- モノとモノ、コトとコト、だけでなく、モノとコトの関係であったり、関連も「多重度」だけでなく、「関連名」や「関連端名」を入れることで、自分たちで考えたモデルの「意図」が伝わりやすくなるかもしれませんね。

常連A- 単なる線に見える「関連」の意味を考えることは重要ですね。

常連B- ちなみに、「テスト結果」をコトとして(実行している「テストコード」とテストの対象となる「実装コード」の関係と)考えると、

  • 「テスト結果」には必ず「テストコード」がある(多重度1)
  • 最初の失敗するステップでは、失敗する「実装コード」がないか空っぽのコード(多重度は0か1)
  • 次に成功するステップでは、成功する「実装コード」は存在する(多重度は1)
  • リファクタリングのステップでは、成功する「実装コード」が更新される(多重度は1)

と解釈できるのかな?

常連A- そう解釈すると「テストコード」「テスト結果」「実装コード」の順にオブジェクトが生成されることになるから、コンセプトの「実装コードが存在するには、必ずテストコードが存在しなければならない」(テストファースト)がモデルで表現されますね♪

常連B- そう、そう!なかなか良い感じです♪

3.回答例

マスターー回答例としまして、当カフェの常連さんのモデルを紹介します。 コンセプト次第でモデルは変わりうるものですから、正解としてではなく、1つの考え方、1つの例としてご覧ください。 では、結果としてのモデルだけではなく、常連さんたちがどのようにそのモデルにたどり着いたのか、モデリングの過程も追ってみましょう。

コンセプト

シナリオを考える

常連さんたちは、ざっくばらんにいろいろ話をしたようです。 『テスト駆動開発』については、お互いに知っていることからシナリオを考えてみました。

  • テスト駆動開発(TDD)と言えば、RED - GREEN - REFACTOR !
  • 最初に失敗、次に成功、さらにリファクタリング、という3ステップのサイクルのこと
  • 最初はテストコードだけ、次に成功するだけのコードを追加、その次にコードをきれいにする
  • リファクタリングは必ずやるわけではない(省略あり)
  • 一回のサイクルでは一つのテストケースを対象にする(一度に複数のテストケースを扱わない)

常連A- そういえば、テストケースってどうするんだっけ?

常連B- 書籍『テスト駆動開発』には「取り組むべきこと」が列挙された「TODOリスト」が登場します。この「取り組むべきこと」がテストケースと言えそう。テスト駆動開発を始めるときは、最初に「TODOリスト」としてテストケースを書き出しておくんだね。

常連B- そういえば、最近KentBeck氏の翻訳記事が公開されていたけど、その記事では「テストリスト」と呼ばれていたよ。「TODOリスト」のことだと思うけど。

常連A- その記事、見たかも!「【翻訳】テスト駆動開発の定義 - t-wadaのブログ」だよね?

常連B- そうそう!「テスト駆動開発」に関する誤解について書かれているみたいだよ。ちゃんと読んだ方がよさそうだね。

常連たちはそんな会話をした後、シナリオにテストリストの記述を追加しました。

  • はじめに「テストリスト」に「期待する動作」を洗い出す(「TODOリスト」に「取り組むべき動作」を洗い出す)

コンセプトを決める

  • テスト駆動開発は、初めに「テストリスト」に「期待する動作」を洗い出し、「期待する動作」を一つ選んで、テスト失敗(RED)、テスト成功(GREEN)、リファクタリング(REFACTOR)のステップで開発していく。
  • 「テストリスト」の中に実現していない「期待する動作」がなくなるまで、1つずつ選んで3つのステップで小さくテンポのよい開発を繰り返していくものである。

ラフスケッチ

コンセプトを決める話し合いの際、常連さんたちは、コンセプトを話しながら、オブジェクト図を書いていました。 思いついたシナリオの風景が違っていないかを確認しながら図にしていたようです。

①テストリストを作成する

①テストリストを作成する

②リストから1つ選ぶ

①テストリストを作成する

③テストを書く(失敗する:RED)

①テストリストを作成する

④成功するコードを書く(成功する:GREEN)

①テストリストを作成する

⑤リファクタリングする(きれいになる:REFACTOR)

①テストリストを作成する

⑥次のテスト:リストから一つ選ぶ

①テストリストを作成する

モデル

最後に、業連さんたちは、ススっとオブジェクト図とクラス図を描いていました。 ここまでの話の流れで、常連さんたちの間に統一されたイメージが出来上がっていたようです。

前提・制約・その他

  • テストリストに期待する動作を列挙する
  • テストリストから期待する動作を1つ選んで、3つのステップ(サイクルと呼ぶ)で小さく開発する
  • テストリストの期待する動作がなくなるまでサイクル(3つのステップ)を繰り返す

オブジェクト図

 - 2回目のテスト(サイクル)を終え、3回目のテストを始めるため、最後の期待する動作を選択したところ

①テストリストを作成する

クラス図

①テストリストを作成する

今回も、常連さんたちのモデリング過程を追ってみました。お題や考える人によってモデルに至る過程は違いそうです。 今回、常連さんたちは前回のサウナでととのうと同じような思考過程でモデリングしていました。 みなさんも自分なりのモデリングスタイルを見つけられるとよいですね。

4.プレゼント企画

今回、株式会社チェンジビジョン様のご厚意で、投稿者の中から優秀なモデル回答読者に「astah*の1年間のライセンス提供」をいただいています。

ライセンスの提供は、ちゃんとライセンス登録し、チェンジビジョン社からのメールで情報を受け取ることが条件とはなります。

今回のプレゼント当選者は、下記の方になりました(パチパチ)。

プレゼント当選者

  • ヴァンダイン様
  • 酒飲むのやめねばならん様

後程、ご連絡いたしますので、楽しみにお待ちください。

5.さいごに

UMLモデリングカフェ「Square」の再開から約1年(早い!)が経ち、なんとか2問分、皆様にお題出題と回答掲載まで進めることができました。皆様のご協力あってのモデリングカフェなので感慨深いものがあります。

最近の現場では、モデリングを行っていないところもよく目にしますが、そのような現場を支援する際には難しいロジックや業務、設計を整理して考え抜くためにも、やはりモデリングは重要な技術であり、みなさんの「対話」の中心には「モデル」がある方が漏れや認識ズレもなく納得できるシステムができるのだと感じております。

今後もスキルアップのために最低限のモデル表記上の「正しいモデル」を伝えながら、それよりも「楽しいモデリング」を目指し、投稿者や読者との対話を大切にしていきたいと思っております。

毎回お伝えしますが、私も今回のお題に関して、完璧なモデルというのは分かりません。観点が変われば違うモデルになることも内部でのモデリングで分かっています(今回のテスト駆動開発は、モノとモノの関係も書けますし、テスト→実装→リファクタリングの行為のモデルも書けます)。その点も含めて、皆様と会話し、様々な可能性やより良い観点を「見出す」ことが、私たちがモデリングカフェを再開した目的になります。

再開後の2024年度、お付き合いありがとうございました。2025年度も、皆様からの積極的な投稿をお待ちしております。

次回のお題については・・・、次号をお楽しみに!