しょぼちむにテストファーストについて説明してみる

このエントリーは、ソフトウェアテストあどべんとかれんだーの11日目*1ならびに、しょぼちむ Advent Calendar 2014 - Adventarの19日目エントリーです。

最初は、JJUG CCC 2014 Fallの懇親会の時に、「しょぼちむでTDD」というオーダーを受けていたので、

describe "しょぼちむ財布もってる?" do
   let (:she) { FactoryGirl.build(:syobochim) }
   it { expect(she.answers).to eq "はい" }
end 

...というのを題材に、TDDを説明してみようとおもったのですが、specがどうやっても緑にならないため*2思いのほか話が深まらないため、TDDの中の重要な要素、テストファーストについてお話ししたいと思います。

JJUG CCCのセッションの中で、「テストファーストにこだわらない」とことに言及させてもらいましたが、

実際にTDDを進めていく中で私がテストファーストを軽視しているかというとそうではなくて、むしろ重視しています。それについては直後にこう呟いた通り。

というわけで、このエントリーでは、TDD、ひいてはソフトウェアテストの中で、「テストファースト」がなぜ重要かということについて、書きたいと思います。しょぼちむはどうしたということに関しては、このアドベントカレンダーでは、↓のような話もあるし、まあいいんじゃね?

実務的な話

私がプログラマーとして、なぜテストファーストに拘るかですが、率直なことを申せば「テストファーストしてないテストは怖い」です。

テストそのものをソフトウェアコンポーネントとして捉えた時に、テストに求められている機能は、テスト対象(SUT)が意図している時に成功(Green)となり、そうでない時に(Red)となること、即ちテスト自身がテストの結果を判断できることです。

この観点から見た時に、テストファーストしてないテストの弱点は、テストを失敗させていないため、テストの信頼性がその分下がるということです。これはTDDの「まず失敗させるテストを書く」プラクティスに乗っ取ることができないためです。このことを差して、JJUG CCCのセッションでは「失敗していないテストのカバレッジは50%しかない」と表現しました。

「どのようにテストを成功させるか」と同じくらい、「どのようにテストを失敗させるか」ということは重要です。どのような条件を満たすとテストが緑になり、どのような条件で赤になるかということを明確にすることで、テストは品質を支える基盤として必要な堅牢さを得ることができます。

Testing と Checking

ソフトウェアテストには、対象のシステムを探索し、学び取る(Learing)Testingとしての側面と、アサーションが通るか、失敗するかを判断するCheckingとしての側面があります。ユニットテストに代表される、開発者のテストは、Checkingに軸足を置いています。

ソフトウェアを開発していく上で、Checkingとしてのテストの果たす役割は、どのようにステップを踏んでいけばゴールに到達できるかということを差す、道しるべとしての役割です。そして、テストが道しるべとしての役割を果たすためには、プロダクションコードを書く前に、Checkingとしてのテストをチェックポイントとして置いておく必要があります。

システム開発の工程の中では、ユニットテストだけでなく、結合テストシステムテスト、非機能要件のテストなど、様々な粒度のテストを行います。その中でのシステムテストは「指定された要件を満たすことを実証するため」に行いますが、システムテストの段階でシステムが「要件を満たしていない」ことが明らかになっても手遅れです。システムが要件を満たすことを確認するためには、上位レベルのテストのCheckする内容と、ユニットテストなどの下位テストのレベルがCheckする内容がお互いに関係を持ち、内容を補完し合っていて、テストの工程を回す中でフィードバックループを適切に回す必要があります。そして上位レベルのテストと下位テストのレベルが連携するためには、V字のモデルを描く必要があるので、やはりテストは先に作成されるべき、ということになります。

ではどうすればいいか

要は、システムを完成させるために、どうステップを踏んで、ゴールに近づいていくかです。その中でテストファーストを導入できるレベルにあれば、導入すればよいし、テストファーストを導入できる段階でなかったとしても、End to Endレベルの試験項目は先に作成するなど、システム開発工程全体の中で、Checkingする工程を適切にまわせていけばいい、ということになります。

ただ、IT技術者として、持っている手札の数は多い方がいいと思いますので、写経等で、テストファーストの考えに触れてみることは、非常に有益だと思いますので、お勧めします。

しょぼちむアドベントカレンダー、明日のエントリーはfukai_yasさんです。

*1:今日は何日だって話ですが...ごめんなさいごめんなさいm(__)m

*2:仮実装でこっちから財布わたせばいいんですかね...?