Chapter6

Light States

車と交差点の信号機のためのシステムを構築する。

2つの方向性がある。

  • 交差点の仕様
    • 信号の点灯状態が正しく遷移すること
  • 構築の仕方
    • テストを FitNesse? で決定表 (デシジョンテーブル) として実装

State Specification

ドイツの信号機システムについて仕様化ワークショップを始める。

  • 遷移
    • 赤→赤と黄の同時→緑
    • 緑→黄
    • 黄→赤

さっそく表にしよう。

Table 6.1 Valid な遷移

前の状態 次の状態
赤、黄
赤、黄

Table 6.1 全ての遷移

前の状態 次の状態
赤、黄
赤、黄
黄点滅 黄点滅

The First Test

  • まずは FitNesse? をダウンロードするところから。
  • ダウンロードしたら java -jar fitnesse.jar -p 8080 で実行。
  • 最近のやつだと最初に Wiki ページを用意してくれる。
  • Traffic Light システムのためのテストスイートとなるページを作る
  • ページを作成したら Tools>Properties からページの種類を Suite に変更する
    • Add ボタンが追加される
    • Suite ボタンが追加される
  • Suite ボタンを押すとテストが実行できるようになった
    • (注釈:厳密なTDDでは新しいものを追加するときはテストを書いてから云々。著者は3年くらいFitNesse使って慣れてるから、この手順でも大丈夫なんだと主張)
  • 最初のテスト
    • 信号機の状態のテスト
  • この後のテスト (予測)
    • 交差点のいろんな状態に関するテスト
  • 最初のテストと後のテストは性質が違うことが予想される
    • 予めテストスイートを別にしておく
  • 忘れそうだけどワークショップでは状態遷移を明らかにしたい
  • 決定表は SLiM で利用できる記法を使う
    • 1行1行がテストケース
    • ヘッダ文字列の最後にクエスチョンマークが
      • 無い:システムへの入力
      • 有る:システムからの出力 (検証される)
  • 信号機の状態遷移では、入力も出力も信号の色 (Listing 6.5)
  • まずは最初の失敗するテストができたところ (Figure 6.2)

Diving into the Code

Java 開発環境のセットアップは本書のスコープ外なのであまり説明はしません…

  • レッド、最初のテストが失敗
    • TrafficLights? クラスと引数無しのコンストラクタを作成する
  • レッド、失敗の原因が変わる
    • setPreviousState と nextState メソッドの空実装を追加
  • レッド、失敗の原因が変わる
    • nextState メソッドの仮実装…
  • グリーン
    • 次のテストケースを追加
  • レッド、失敗の原因が変わる
    • setPreviousState で渡された状態を保持するようにして
    • nextState は直前の状態から次の状態を決めるようにして
  • グリーン

Refactoring

  • 1つの機能を実装した
    • 次の機能に進んでもよさそうだけどちょっと待って!
      • TDD で開発した (ドヤァ) ので、テストコードとプロダクションコードが密結合すぎる。分離しないといけない
      • パッケージ空間無しに開発してしまったので修正されるべき
パッケージ
  • ちゃんとしたツール (IDE) を使ってるならクラスの移動に頭を悩ませることはない
  • でも FitNesses? には伝えないといけない…
    • テストページの冒頭にパッケージの記述 (import 文) を追加する
点灯状態列挙型 (The LightState? Enum)
  • 点灯状態は列挙型にするべきなんじゃないかと思えてきた
  • TDD で変更しました (ドヤァ)
  • 不定な状態への対処
    • ドイツの法律「信号機は、設定が間違っていたら点滅しないといけない」
    • 実装しました
Editing LightStates?
  • 列挙型を導入したのでサポートコードの修正も必要
  • FitNesses? のテストは文字列値を使ってるので、それを変換したりする
    • 巨大は if then elseif else ができつつある
    • 決っしてよい設計とは言えない
  • 値クラス (Domain) に対する編集クラス (Editor) を導入する
    • LithtState? に対する LightStateEditor?
    • PropertyEditorSupport? のサブクラスとして作成
  • ここでも TDD で進める (ドヤァ)

Summary

  • 信号の点灯状態の遷移を表で表した
  • 受け入れテストとユニットテストを別の概念として導入した
  • 私たちはテストによって問題領域の理解を深めていく
    • 信号機の状態を LightState? クラスで表現したら、サポートコードはシンプルになっていった
  • アウトサイドインなアプローチの利点
    • コードがドメインから乖離してしまうことを防げる
    • もしテストを既存のコードベースに合わせようとしたらこうはいかなかった
  • 受け入れ基準から設計に落としていく
    • いいと思います
Last modified:2014/06/28 07:18:36
Keyword(s):
References:[担当割当表/Part2]