[動画で解説]和田卓人の“テスト駆動開発”講座

第11回 テストの資産価値

この記事を読むのに必要な時間:およそ 2 分

ニコニコ動画:http://www.nicovideo.jp/watch/sm2325613

宮澤さんからの質問

単体テストを,どこまで,どの単位までというのはよく議論されると思うのですが,「不安」というのは人それぞれ違いますよね。特に新人の人だと,単体テストは不安だらけだと思うんですよ。なので,すごい小さいことまでテストに書く。

そうした場合,仕様変更とか,リファクタリングとかで変更があったときに,そのテスト自体がいらなくなる可能性がありますよね。

新人の人だと,それに対して「もったいない」と感じると思うんですよね。「コードが変わるのはしょうがないけど,テストをわざわざ変える,テストがガッツリ消えちゃうというのは納得がいかない」と。

そういう気持ちを持っている人に対して,どう思いますか?

そうですね。またよい質問をいただきました。「テストの資産価値」という話をこれからしたいと思います。

小さいテストがすべて真っ赤っかに……

私も「不安」ですし,新人の人だったら不安がいっぱいでしょうから,たくさんの小さいテストができることはあると思います。

その場合,小さい単位のテストを基盤にして,それらの学習結果やそれらの不安をもとにしたテストコードと,それらの上で実際に書かれたコードが存在することになります。

それに対して仕様変更があった場合,小さい視点のテストが全滅してしまう,もしくは真っ赤っか(テスト失敗だらけ)になってしまうということはよくあります。

そのときに,そのテストを一つ一つ直していくことに意味があるのか,割に合うのかという話が出てくると思います。実プロジェクトではよく遭遇する事態だと思います。

整理すると,まず最初にサイクルとして大きいテスト(受け入れテストや,スコープの広い機能テストなど)\を作りました。そして,小さいテストから積み上げて開発をしていきました。あるとき大きいレベルで仕様変更があったときに,その大きい機能を満たすために積み上げていった小さいテストが,全部真っ赤っかになってしまった,というような場面です。

テストの資産価値

私は,「テストの資産価値」という考え方を持っています。

リファクタリングで小さい粒度のテストが赤くなったときには,もうそのテストは役目をある程度果たしていると考えています注1)。

ですから,テストをその時点で捨ててしまうこともあります。ただし,小さいテストを捨てるという判断をするときには,当然それらのテストを包含している大きいテストがあることが前提です。

たとえば,小さいテストがいっぱいあり,それらの小さいテストの学習結果や,それらの小さいテストによる不安の克服をベースにしてできあがった大きい粒度のテストがいくつかあったとします。

私は,実際にテストとしてメンテナンスしていく価値を持っているのは,この大きいテストケースのほうだと考えています。この大きいテストケースをグリーンにするために,小さいテストケースのレッド,グリーン,レッド,グリーンの繰り返しがあったと考えるのです。

注1)
ここで「あれっ」と感じた方がいらっしゃるかもしれません。通常リファクタリングの世界では,レッドバーを見てはいけませんでしたね。グリーンのままで,つまり外部から見た振る舞いを変えないままでコードの改善を行うのがリファクタリングだったはずです。ここで問題になるのはテストの種類と粒度です。小さい粒度のテストとはテスト対象のスコープを少数のクラスに絞り込み,モックオブジェクト技法(次回説明します)などを使ってテストしているテストコードのことです。

階段,積み木,はしごというメタファ

私はよくテスト駆動開発の例え話として,階段や積み木,はしごの話をします。

提供したい機能を「高いところにある」とイメージしてみます。高いところまで行きたいときに,最初に受け入れテストとして,ここまでいきたいですというテストを書くんですね。

テストは書いたものの,書いた時点ではテストはもちろん通らない(成功しない)です。目標とする地点まで至るために,土台として小さいテストを積み上げていって,最終的に大きいテストが通るようになります。

そのようなとき,小さい単位で積み上げていったテストの1個1個の総和と,大きい視点のテスト1個は,資産価値が同じだと私はとらえています。要するに,小さいテストを全部足した価値と,それらを包含する大きいテスト1個の価値は同じだと考えているのです。

テストのメンテナンスコスト

価値は同じでも,メンテナンスコストは全然違いますよね。小さいテストのほうが数は断然多いですし,細かい内容になってます。大きいテストのほうはもっとずっと粗い視点ですよね。

大きい視点での仕様がちょっと変わったために,積み上げていった関連する小さなテストが全部真っ赤っかになってしまったとき,大きい視点のテストの変更は当然行います(さらに言えば,テストファーストをしているのなら,「先に」変更されるはずですね)。

赤くなっていた大きい視点のテストを,仕様変更作業を行うことによってグリーンにしました。このとき,メンテナンスをまだしていないレッド状態の小さいテストが非常にいっぱいあるという状態になります。

そのようなときに,テストの資産価値を考えます。大きいテストと小さいテスト群はだいたい同じ価値ですので,「大きいテストがメンテナンスされたことで,小さいテスト群は,もう用済みになったのではないか」というようなことを考えるのです。小さいテストのメンテナンスコストが気になるのであれば,大きい機能を満たすために積んでいった踏み台としての小さいテストは,仕様変更のあとで赤くなってしまった時点で外してしまってもよいのではないかと考えています。

「もったいない」と言われたときは……

先ほど「もったいない」という言葉が出てきました。

誰でも,自分が一生懸命作ったものを消すことには抵抗があります。だから,説明をきちんとしなければ,きちんと説明できなければなりません。

まず大前提として繰り返しますが,小さいテストを捨てていいのは,それら小さいテストを包含している大きいテストがあるときだけです。

同じ意味合いを持ったもっと粗いテストがある場合,コストを考えると小さいテストのメンテナンスは段々に重荷になってしまいますし,精神的にも負担です。

私はそういうときに,テストの資産価値という視点で説明を行って,「新機能をテスト駆動で開発するところで活躍してくれたテストだけど,そういう小さいテストたちは今やもう役目を終えたので,メンテナンス対象から外してしまいましょう。消してしまいましょう」という話をしています。

テストをレッドのまま放置してはいけない

テストをレッドのまま放置してはいけません。メンテナンスしてグリーンにするか,消すかの二択です。

なぜかというと,テストをレッドなまま,動かないまま放っておいてしまうと,プロジェクトが段々と不健康な状態になってしまうんです。「この単体テストはレッドバーなんだけど,それはそれでいいから」という感じでプロジェクトを進めてしまうと,レッドバーを見ても危機感を感じなくなってしまうのです。

プロジェクトは基本的に,小さい単位のユニットテストは常にオールグリーンの状態,すなわち進捗管理に使う受け入れテスト以外のテストはオールグリーンの状態で進めていかなければならないと考えています。

レッドバーが出たら,何かがおかしいと感じるような状態をキープしましょう。レッドバーは炭坑のカナリヤの役割を果たすと考えてみてください。

プロジェクトのセンサーとしてのテストの質を維持するために,資産価値が低くて用済みになってしまった赤くなったテストたちは,プロジェクトの健康のために捨ててしまいましょう。

著者プロフィール

和田卓人(わだたくと)

タワーズ・クエスト株式会社 プログラマ 兼 取締役社長。
2003年頃XPやテスト駆動開発に目覚める。後年「チームかくたに」のコーチとしてXPやTDDをチームで行った経験をもとに,『WEB+DB PRESS Vol.35』と『WEB+DB PRESS Vol.37』でTDDやリファクタリングについての巻頭特集を執筆。現在はSeasar.orgのコミッタとしての活動もしつつ,社長として会社を回している。

URLhttp://d.hatena.ne.jp/t-wada

コメント

コメントの記入