第4回
EclipseとJUnitによるテスティング


縣俊貴
橋本正徳
Project Mobster/メディアファイブ株式会社

2003/3/7
 今回から2回にわたり、システムのシートベルトとでもいうべき「テスト」について考えていきます。XPではテストに関して「テストファースト」に代表される、独自のアプローチを取っています。それらは通常の開発に慣れた人にとっては、奇異に映るかもしれません。しかし、実際に開発に取り入れて実践してみると、大変合理的な手法であることに気付くと思います。今回は「テストの意義」と「テスティングフレームワーク(主にJUnit)」について解説し、その後Eclipseを利用した効果的な単体テストの活用法に焦点を移します。

本連載の今後の講習カリキュラムはこういうイメージになる

テストのプラクティスの位置付け

 XPはテスト駆動型の開発プロセスです。テストはXPの各プラクティスの中で最も中心的な役割を果たします。テストのプラクティスを実践することで「リファクタリング」「シンプルな設計」「継続した結合」「短期リリース」「週40時間」などのほかのプラクティスが強化されます。またテストはプログラマが最初に取り入れやすいプラクティスの1つです。XPを検討する前段階のステップとして、ユニットテストを部分的に導入してみるのもよいと思います。まだユニットテストなども未体験の方は、テストを自分の開発スタイルに取り込み、XPへの扉を開きましょう!

XPにおけるテストの意義

 XPではすべてのコードに対してテストが存在します。これによって、短期間でバグが少なく、高品質のシステムを構築することができます。このことは絵空事のように聞こえるかもしれませんが、いつでも実行可能なテストを各クラスに用意することでバグの発生は限りなくゼロに近づきます。多くのシステムがたくさんのバグを抱えて、デスマーチへ突き進んでいることを考えると、この効果は計り知れないものがあると思いませんか? また、リファクタリングや仕様変更などの前に、システムのすべてのテストを実行して、改造後にもう一度テストを行えば、改造が正しく行われたことを保証することができます。

XPにおけるテスト = 自動化されたテスト

 XPでのテストとは自動化されたテストのことを指します。「自動化されていないテストはテストにあらず」というわけです。自動化されたテストならば、テストを「いつでも」「素早く」「すべて」実行することができます。一般的によく行われる「System.out」による目視やステップ実行によるテストは自動化されていないので、システムのテストとしては不十分だといわざるを得ません。普通はJUnitなどのテスティングフレームワークを利用して自動化されたテストを構築します。

コラム:プログラマはテストによって救われる?
 皆さんはテスト好きですか? 筆者は学生時代からテストと名の付くものすべてが苦手でした。もちろん、プログラマに成り立てのころもテストは面倒くさく、後回しになりがちでした。それがXPやテストファーストを実践してからは、テストが大好きになりました。もはやテストなしのプログラムは考えられません。ユニットテストなしで今までうまくいっていたのは奇跡だと思えるくらいです。テストを行うことでプログラマは「自信」を持つことができます。それは「自分が書いたコードは正しく動いている」ということへの「自信」です。また、「テストを通す」という短期的な目標が明確になり、開発自体にリズムが出てきます。プログラマはテストによって救われます。

ユニットテストと受け入れテスト

 XPには2つのテストがあります。

 ユニットテスト:ユニットテストはプログラマが書き、プログラマが実行します。ユニットテストとはクラス(モジュール)の単体テストのことです。クラスの「振る舞い」が期待どおりに動くことを中心にテストを作成します。本連載ではこのユニットテストを中心に解説します。

 受け入れテスト:受け入れテストは顧客が書き、顧客が実行します。受け入れテストを行うことで顧客はシステムの振る舞いを確認することができます。自動化された受け入れテストがあれば、システム全体としての「完成度」についていつでも知ることができます。

テストファーストプログラミング

 XPではテストファーストでプログラムを作成します。テストファーストとは実装コードのコーディングに入る前に、その実装コードに対するテストコードを先に書くことです。これには次のようなメリットがあります。

 仕様の明確化:コードを書く前にテストが作れないということは、そのコードの振る舞いがはっきり理解されていないということになります。逆の言い方をすると、テストファーストならば、コードを書くときには振る舞いがはっきりしているので、コードを書くことに専念できます。テストコードを書くことが、クラスやメソッドに対する詳細設計になります。

 すべてのコードに対してテストが作成できる:テストファーストならば、すべてのコードに対するテストが必ず存在することになります。「コードが動いたからテストは書かなくていいや」という考えを防ぐためにもテストファーストは有効です。

 ドキュメントとしての役割:テストは最高のドキュメントです。テストは、クラスの包括的な振る舞いを確認していますので、テストを見ることでクラスの使用法、仕様が理解できます。

 シンプルな設計:テストを先に書くことで、シンプルな設計/実装を行うようになります。

 ゴールの明確化:テストを先に書くことで、コーディングのゴールを知ることができます。ゴールとはテストに通ることです。これはプログラマにとって精神衛生上良い効果をもたらします。

テストファーストプログラミング

コラム:テストファーストって実現できるの?
 テストファーストって実現できるのでしょうか? 筆者はXPではないプロジェクトでテストファーストを試みたことがあります。しかし、開発期間の制限、ユニットテストが納品物として認められないなどの理由で、すべてのコードをテストファーストで書くのは難しいものがありました。その結果テストがまったくないクラスがいくつもできてしまいました。その時点では「まぁ動いているからいいか」と思っていました。しかし、結合テストやデバッグ、メンテナンス時に、テストを作らなかったことを大変後悔することになりました。正しい動作を保証してくれるユニットテストがない場合、変数名を1つ変えることにすらおびえてしまいます。また、テストを作る余裕すらないコードは、その余裕のなさが反映され、各所にバグが入り込み、そのバグ退治のためのバイパスコードが複雑に入り込んでいました。まさに「動いているものには触るな」という最悪の事態に陥ってしまいました……この経験から次のことを学びました。
  • 「テストファーストが守れる」のが最高の状態
  • 「各クラスにちゃんとテストが付いている」のが良い状態
  • 「テストがない」クラスはカルテのない末期症状の状態
 もしテストファーストが守れなくても、各クラスに対するテストは実装後でもよいのできちんと揃えておくべきです。

テスティングフレームワークを活用しよう

 テストにはテスティングフレームワークを活用しましょう。JavaにはXPの生みの親であるケント・ベック氏が開発したJUnitがあります。JUnitには次のメリットがあります。

 テストが簡単に実装できる:テストは簡単に、なるべくプログラマにかかる負担が少ない形で実装するのが望ましいでしょう。JUnitではテスト用の基底クラスを継承してテストクラスを作成しますので、最小限のコーディングでユニットテストを構築できます。

 テストが統一的に作成できる:JUnitを用いない場合、単体テストは各プログラマがそれぞれのやり方で実装してしまいます。フレームワークという枠組みがあることで、統一的かつ一貫した方法でテストを行うことができます。

 テストと実装コードの分離:JUnitでは実装クラス「Hoge」に対して、テストクラス「HogeTest」を作成します。このことにより、テストコードで実装コードを分離することができます。

 Antなどほかのツールとの連携:JUnitはほかのツールから利用されることも考慮して設計されており、AntやIDEとの連携がスムーズにできます。

テスティングフレームワーク「JUnit」のインターフェイス

コラム:テストの使用を広げていこう!
  テストはXP開発の中でなくても有意義なものです。テストを活用されている方なら誰もがそう思うでしょう。しかし、テストの使用を周りの開発者に勧めるのは困難な場合が多いのです。それは、成果物にならない点と、一見無駄に見えてしまうところ、「テスト」というネーミングのせいだと思います。私たちが行っている「テストを周りの開発者に勧める方法」は次のようなものです。
  • テストに通るたびにひとはしゃぎする(「うぉっ」「やった!」の一声だけでもOKです)

  • 休憩を取るときにこれ見よがしに「緑のバー」ののびた画面を表示したまま席を立つ

  • テストを語るときはニコニコする(しかし、ほどよい程度にしましょう。やり過ぎるとかえって危険です)

  • 「改造できますか?」と聞かれたら「テストをちゃんと作っていたので大丈夫です」と一言付け加える

  • 仕事を楽しくやる(これはテストをきちんと作ることで自然とできてしまいます。この「楽しく仕事をしている雰囲気」に引かれ興味を持ってくれるかもしれません)

 今回はテストの意義について考えてみました。次回は実践編です。Eclipseを使ったテストファーストを時間軸を追って実践していきます。また、テストを構築する際のTipsなどもご紹介する予定です。お楽しみに!


プロフィール
縣俊貴(あがた としたか)
 メディアファイブ株式会社所属。XML,フレームワークを中心に開発業務に携わる。Javaのコミュニティー団体であるMobsterを主催。現在MonsterにてJavaベースのWikiシステム「MobWiki」を開発している。

橋本正徳(はしもと まさのり)
 メディアファイブ株式会社所属。XML、フレームワーク等の開発業務に携わる。Javaのコミュニティー団体である「Mobster」を縣と共に発起、運営。現在mobsterにてバグトラッキングシステム「mobbug」等を開発している。「日本XPユーザーグループ関西支部 九州分科会」にも参加。ちなみにこの記事自身もCVSでバージョン管理し、縣と橋本とで共同所有されて書かれている。

Project Mobster(ぷろじぇくと もぶすたー)
福岡県福岡市を中心にJava言語を研究追求し、その成果物をWeb上に公開していく団体です。年齢・スキル・会社などを超えてボーダーレスに活動しております。

IT Architect 連載記事一覧

この記事に対するご意見をお寄せください managemail@atmarkit.co.jp

「ITmedia マーケティング」新着記事

「AIによる顧客体験(CX)向上」に懐疑的な見方が広がる――Qualtrics調査
Qualtricsが実施した年次グローバル調査から見えたカスタマーエクスペリエンス(CX)の現...

2025年のSNS大予測 AIの時代に「ソーシャル」はどう変わる?
もういくつ寝ると2025年……と数えるのはさすがに気が早いかもしれないが、それでも2024...

SEOで陥りがちな失敗は「アルゴリズム変更に対応できなかった」が最多に 原因は?
SEOの成功には何が必要なのか、失敗経験者へのアンケートで浮き彫りになったこととは……。