テストコードの始め方

テストとは

  • プログラムが期待された通りに動くかどうかを確認する作業
  • 手動で行う場合や、ツールを使う、テストコードを利用する場合などがある

テストコードを利用したテスト

  • プログラムが正しく動くかどうか、プログラムを利用して検証する
  • 引数や状態を与えてやって、その時に期待される結果が返ってくるかをコードで確認する
  • 一般的には、テスト用のライブラリを利用して行う

単体テスト用ライブラリ

言語 ライブラリ
C CUnit
C# xUnit.net, NUnit
Java JUnit
JavaScript QUnit, Mocha, Jasmine

C# での単体テストの例

コードで見た方が、何をする事なのかわかりやすいと思います。

Assert.Equal(0, Add(0, 0));
Assert.Equal(1, Add(0, 1));
Assert.Equal(2, Add(1, 1));
  • テスト用のライブラリ xUnit.net を利用した例
  • 関数 Add は2つの整数の引数を取り、その和を返す関数
  • 関数 Assert.Equal は二つの引数が異なる(同じではない)と異常をだす
    • 1つ目の引数が期待される答え(expected)
    • 2つ目の引数が実際の値(actual)
  • これらのコードを実行すれば、関数の戻り値の整合性の確認がとれる
  • 前提となる条件、状況が必要な場合には、それらもコードで与えてやることになる

テストコードを書くメリット

検証作業を自動化できる

  • テストコードを走らせれば、検証できるので、検証作業を自動化することが出来る
  • テストコードを自動で走らせるソフトを利用する

リファクタリングしやすくなる

  • チューニングやリファクタリングを繰り返しても、コードを走らせるだけで『壊してないかを』確認できる
  • 安心して修正することが出来る

リリースを素早くできる

  • テストコードのカバー範囲が増えていけば、人がしなければならない検証作業を減らすことが出来る
  • よって、リリース前の確認作業を減らすことが出来る
  • 究極の理想状態 (全ての動作の確認をテストコードでできてしまう状態) に到達できれば、コードを書いた瞬間に出荷判定が出来る
    • 現実には難しいですが・・・
    • ただ、継続的インテグレーションの目標はこの辺だと思います

プログラムが正しく動くことを客観的に保証できる

  • テストコードを走らせれば、誰でも同じ検証が出来る (ので、そもそも人がしなくてもいい)
  • バージョン管理にテストコードも一緒に入れておけば、後からその時点での確認もできる

そもそも、テストコードは仕様書みたいなものである

  • メソッド単位で挙動をコードに書くので、仕様書のようなものである
  • 仕様書からテストコードを作るソフトもあるらしい(個人的には逆が欲しい・・・)

設計手法が洗練される

  • 「テストが書きやすいコードは良いコード」という意見が巷にはある (私も同意見)
  • テストが書きやすいコードは、状況の再現が容易なコードでもあるので
    • 引数で状況を再現してやる訳だし
  • テストコード上で、状況と呼び出されるメソッドと結果が一目で見てわかる状況になるので、不整合が違和感として浮かび上がりやすい
    • 『こうすれば、こうなるのが、このメソッド』とコードで書くわけなので、この三つがずれてる設計や命名だとテストコードがいびつなものになる

テストコードを書くデメリット、難点

そもそも、テストコードを書かなければならない

  • テストコードを書かないことには検証できないので面倒くさい
  • 納期が短いと『そんな余裕はない』ということも・・・
  • そんな時のために 静的コード解析 ツールは存在するわけですが・・・ (高い・・・)

テストを書いたからと言って『完璧』になるわけではない

  • 全ての検証作業でそうな様に、テストの内容に漏れがあれば検証としては不完全なものになる
  • そもそも、ハードウェアが無いと出来ないことは、テストコードだけではどうしようもないですし・・・

とりあえず・・・

テストを書けば、完璧な検証がすぐにできると言うような銀の弾丸的な効果はありませんが、ソフトウェアが複雑化しながら納期が短くなる昨今では、どこかでやらなければならなくなるモノだと思います。