オルタナティブ・ブログ > An Agile Way >

アジャイルに行こう!

EoTとユニットテスト

»

ここでのテストは、開発者テスト、の中の、ユニットテストの話。XPとTDDの文脈において、設計を駆動するテストについてです。(※最近、テスト、と言う言葉を慎重に使わないと、いろんな他の方面から誤解を招く、ということを知って、文脈を特定しておきます。^^;;)

テスト容易性(EoT=Ease of Testing)が重要な設計品質である、ということを以前書いた。もう少し具体的な根拠を書きたい。

ユニットテストをたくさん作るということは、設計に対してどんな意味を持っているのだろう?物理的にいうと、「プログラムのエントリーポイントを増やしている」ということになる。

blog6

エントリーポイントとは、プログラムのスタート地点である。通常であれば、プログラムはmainという名前の決まったエントリーポイントから呼び出され、多くのモジュールを通過して終了する。しかし、ユニットテストを導入することによって、多くのテストメソッドが独立したエントリーポイントなる。main以外にも多数のエントリーポイントが作られ、テスト対象のモジュール(クラスやメソッド)はさまざまな道筋(文脈)で呼び出されることになる。こうして多くの道筋で使われることで、モジュールの文脈依存が小さくなり、この結果分かりやすく再利用しやすいテスト対象モジュールが取り出されることになる。さらに、モジュールの良い名前の採択が進む(文脈を表す名前でなく、責務を表すメソッド名が現れる)。そして、――これが最も大切なことなのだが―テストがあることによって以降のソフトウェアの変更が小さなコストでできるようになる(EoTは、EoC(Ease of Changing)の前提条件でもある)。

結論として、テストしやすい設計とは、「再利用性の高い設計」、「変更容易性の高い設計」を、テストというより具体的な言葉によって方針化しているといえる。以前、XPをやり始めたチームで、「このメソッドはユニットテストできません」という発言をよく聞いた。例えば、「タイマー起動である条件に合致するユーザをDBから選択し、そのユーザのアドレスにメールを送る」というメソッドをテストしようとしており、これはテストできない、という言い分である。これは典型的な間違いだ。まず、「タイマー起動」、「DBから条件に合致するユーザを選択」、「メールを送付」という3つに分けてテストできないか、と考える。テストを基点としてモジュール分割を考えるわけだ。タイマー起動のメソッドについては、時間をパラメータとし、すぐに起動されるイベントをテストしよう。メールを送付できることをテストするのは難しい。そこでMock(スタブ)を登場させる。メールの送付が他のクラスの責務であれば、自クラスのテストとしてはMailerMockを定義して、そこにメッセージが送られていることをテストすればよい。基本は、

「テストしやすいように、責務を分割する」

ことだ。この指針が、EoT(Ease of Testing)の本質だ。テストはモジュール分割のよいナイフになる。

Comment(2)