DSL / Testing with DSLs


Testing with DSLs(DSLのテスト)

まだ途中です。あとでさらに手を入れる予定。

一言要約

DSLだってやっぱりテストしたい!

要約

テスト駆動開発が大好きな私としては、当然DSLもテストしたい。ということでDSLのテストについて考えてみた。

セマンティックモデルのテスト

セマンティックモデルのテストとして行うのは、モデルに値を投入したときに期待通りの出力が得られるかどうかを確かめること。このテストにはパーサーやDSLスクリプトは不要で、モデルのインターフェイスに直接アクセスすればよい。

先に示したシークレットパネルコントローラを例にして考えてみよう。このセマンティックモデル(ステートマシン)をテストするには、"導入" の最初に示したコードが使える。

 @Test
 public void eventCausesTransition() {
   State idle = new State("idle");
   StateMachine machine = new StateMachine(idle);
   Event cause = new Event("cause", "EV01");
   State target = new State("target");
   idle.addTransition(cause, target);
   Controller controller = new Controller(machine, new CommandChannel());
   controller.handle("EV01");
   assertEquals(target, controller.getCurrentState());
 }

……が、実際にはもう少し手直しすることになるだろう。

  • 改善案その1: 必要最小限の機能だけを提供する小さなステートマシン群を作り、それらを組み合わせて使うようにする
    1. 遷移のテスト用、コマンドのテスト用などにそれぞれ個別のステートマシンを作ってみる
    2. 次のようなスーパークラスを用意する
  • 改善案その2: より大きめの多機能なモデルを作成し、それに対して複数のテストを実行する
    • グラント嬢のコントローラをテストフィクスチャとして使う

パーサーのテスト

  • DSLスクリプトの小さな断片を作って、パーサーがそこから正しい構造を作成できるかどうかを確かめる。
  • セマンティックモデルを比較するメソッドを定義してそれを使うやりかたもある。
  • Notificationパターンを使う方法もある。

スクリプトのテスト

DSLスクリプトだって立派なコードだ。「シンプルで明白なので敢えてテストするまでもない」とか言う人もいるけど、TDD大好きな私としては当然スクリプトもテストしたい。

スクリプトのテスト方法として一般的なのは、テキストのフィクスチャを作れるような環境を作ってスクリプトを実行し、その結果を比較するというもの。

スクリプトのテストは、統合テストとしても使える。もしパーサーやセマンティックモデルに問題があれば、スクリプトのテストも失敗するからだ。

ファウラーへのフィードバック

担当者のつぶやき

  • 全訳のほうは字面だけ追っていってもなんとかなりますが、要約するには内容をきちんと理解する必要がある。予想どおり、要約のほうが強敵でした……。
  • 文中でリンクされていたxUnit Test Patterns読書会も細々と開催中。次回は10/4開催予定です :-)

みんなの突っ込み

  • 宣伝乙 -- 角田? 2009-09-21 (月) 18:58:58

まとめ (議事録)