カテゴリー:
コーディング
タグ:
 テスト ブラックボックス ホワイトボックス

このエントリーをはてなブックマークに追加
更新日時:
2013年08月17日(土)
作成日時:
2013年08月17日(土)

前の記事 / 次の記事

思いっきり忘却しそうなので、考えたことを覚えている内にとりあえずメモ。

目次

1.はじめに
2.参考
3.なぜテストをするのか?
4.ホワイトボックステストかブラックボックステストか?
5.どこまでテストをするのか?
6.ユニットテストはどこまで必要か?
7.インテグレーションテストはどこまで必要か?
8.本当にTDDはいいのか?
9.終わりに

はじめに

この記事は、学問的でも論理的でもなく、最近の流行なども追ってなく、
ただ単に自分が開発をする上でどういう風にテストを扱ったら快いのかという
アイデアを淡々と記録したものです。過度な期待はしないで下さい。

参考

他にも沢山参考にしているページはあるんだろうけど、
記憶に残っていて確かに参考になったと覚えているのは次のページだけなのでとりあえず上げておく。

なぜテストをするのか?

テストの目的ってもちろん「コードの動作を保証」することだど、
それだけではないと思う。

今思っているのは次の3つ

  1. コードの動作を保証するため
  2. リファクタリングするため
  3. 証拠を残すため

1.の「コードの動作を保証するため」っていうのは、誰しも異論がないところだと思う。

けれど、「コードの動作を保証するため」だけでいいのであれば、
たぶんこの記事でこれから書こうとしていることのほとんどは不要で、
その都度思い思いのテストを書いてガシガシ通過させればいい。

で、そうじゃないと思っているので2.と3.がある。
2.と3.のことを考えると、ただ単に動作が保証されればいい訳ではないと思うし、
思わずノリでテストを書いているけれど、不要なテストというのも出てくると思う。

2.と3.について思っているとことを、
次の、「ホワイトボックステストかブラックボックステストか?」と
「どこまでテストするのか?」で考えてみたい。

ホワイトボックステストかブラックボックステストか?

2.の「リファクタリング」するため、にテストを書こうとすると、
そのテストの書き方というのは自ずと制限されてくると思う。

リファクタリングする前と後とで同一の動作を保証するためには、
リファクタリングする前のコードも後のコードも同じテストを使って同じ結果を得られる必要がある。

リファクタリングするたびにテストも一緒につくりなおすというのは
実際にはやってしまいがちだけどかなり非効率なことだと思っている。
ていうか毎回テストもつくりなおすなら「そもそもテストいらないんじゃね?」とも思う。

そう考えていくと、ホワイトボックステストかブラックボックステストの
どちらを採用すべきかというのは、リファクタリングすることを考えた場合、
ブラックボックステストを使うのが望ましいのではないかと思う。

基本ブラックボックスで書いて、頑張って珍妙なコードを書いてしまって
まともな動作に自信を持てない部分はホワイトボックスで潰しておく、
というのがいいのではないなかあと。

今のところ思っている。

どこまでテストをするのか?

3.の「証拠を残す」ためのテストと考えた場合、不要なテストが結構出てくると思う。

この「証拠を残す」というのは、客先や上司、関連部署から、
「これはどうなってるんだ?ちゃんと確認したのかね?」って言われた時に、
自信を持って「はい、確認していますこの通り」と言えるための証拠を残す、
という意味で書いている。

そう考えると、理想としては全てのコードにテストが存在することが望ましいけれど、
証拠を要求されても即座にテストコードに代わる証拠を提示できるような場合、
そのコードのテストはなくてもいいのだと思う。

あと、例えば太陽が東から昇るか、
みたいなどう考えても明らかにそうにしかならないようなテストもなくても差し支えないと思う。

テストを書いて乗ってくるとつい、色んなことを確認したくなってしまうけれど、
無駄に色んなことを確認するとそこがホワイトボックス化してリファクタリングに支障が出るので、
確認する項目が少ないより多い方が優れている、訳ではないと思う。

また、同様に、太陽が東から昇るか、くらい普遍的なことではなくても
自分の経験則や実際に実行される時の条件等から、自信をもって失敗しないと言い切れる場合、
そのテストもなくても構わないと思う。

で、実際どの程度まで突っ込んでテストすべきなのかということで、
これはるびまのどこかのページに書いてあったことなのだけど、

「不安だったらテストをする」

というスタンスがいいと思っている。

どんなに珍妙で不可解なコードでも動作に自信を持てればテストは不要だし
どんなに可読性が高くキレイなコードでも動作に自信を持てなければテストをすべきなのだと思う。

次は、テストを大きくユニットテストとインテグレーションテストに分けた場合、
それぞれ、どこまで必要かについて考えていることをまとめてみる。

ユニットテストはどこまで必要か?

基本的には全て必要だと思っている。
というかユニットテストは全て書くスタイルで開発をしたい。

気分の問題なのだけど、ユニットテストの無いコードは気持ち悪い。
もちろん、前述の不要なテストについては書かなくてもいいと思うけれど、
個々のユニットについてはテストファイルが存在していないとキモい。

で、そういうことにしておけば、
そのユニットのテストファイルに何も書かれていないか、
テスト不要とか書かれていればテストを書いていないのではなく不要なことが分かる。

でも全てのユニットにテストファイルが存在している訳ではない、
ということになると、後から見た時テストが無いのか不要なのか分からなくなる。

という気持ちの問題。

インテグレーションテストはどこまで必要か?

ここで言いたいインテグレーションテストというのは、
いわゆる自動テストとしてのインテグレーションテストをどこまでするかということ
もちろん最低限目視でのインテグレーションテストはする、

で、ある程度の規模以上のプロジェクトでなければ
これは費用対効果が薄いから無くても差し支えないだろうなと思ってる。

というか、前述の「どこまでテストするのか?」に当て嵌めて考えた時、
自分の目から全体が見えるくらいのプロジェクトだったら、
ユニットテストが通ってればインテグレーションテストでこける気がしない。
からいらない。

でもクリティカルなところはあった方が精神的に気持ちいいかな。

ただ、実際に動かしてみた時に、ユニットテストは通るけど結合したら駄目だった、
みたいなところは再発防止のためにインテグレーションテストとして書き起こす必要はあると思う。

本当にTDDはいいのか?

とか書いてる時点で、あんまりいいと思っていない訳だけど。

完全に仕様が確定した後であれば、テストから書くというのは合理的な手段だと思うのだけど、
仕様変わるかもー、的な状況だと、やっぱテスト書く手間余計なんじゃないのって思う。

TDDのテクニックとしてとりあえず対応するテストを書いてテストはフェイクのものを
書いておくっていうのがあるけど、それも、そもそもその対応するテスト自体不要に
なってしまうこともあるので、それを削除するのもだるいよなーと。

終わりに

なんか色々書いたけど結局のところいまいちよく分からないんだよね。
色々考えたりやってみたりしてるけどこの記事に書いたことも含めていまいち腑に落ちない。

探し方が悪いだけな気もするけど、「これがテストだ!」みたいな本って無いんですかね。
「これがTDDだ!」とか「これがRspecだ!」みたいな本は沢山出てくるんだけど、

実際にテストをつくる時のコツみたいのを知りたい。

プログラミングの入門書的な位置づけの本って、
何か実際に動くコードをつくりながら色んな機能について解説していくっていう
形式が多いと思うんだけど、そこでテストの項目を省かないで書いて欲しいと思う
んだよね、たぶん厚さ倍以上になるし、取っつきにくくなるけど。

こういう時はこう書くのがお約束だよ、とか
こういう時はこうも書けるよ、とか
こういう風には書かない方がいい、みたいのが

プログラミング言語そのものについては散々解説してあるけど、
そのコードをテストするためのコードについてはほとんど書かれていない、
からそれが書かれたものを読みたい。