ぐらめぬ・ぜぷつぇんのはてダ(2007 to 2011)

2007年~2011年ごろまで はてなダイアリー に書いてた記事を引っ越してきました。

やっぱりTDDがわからない。

特に、ファイル入出力やDB接続失敗、ネットワークソケットの失敗など、外部との境界線上での失敗の振る舞いをテストする時の手法が分からない。内部完結な処理であればMockObjectでどうにかできるのだろうけど、プログラム(ここではあえて"システム"とも"アプリケーション"とも呼ばずに"プログラム"と呼称するけど)が外部環境と連携する時、外部環境の異常時の振る舞いまでプログラムの仕様として記述する場合(例えば通信プログラムやデーモンの内部APIなど)、これはTDDでサポートできる範囲なのか?

TDDは・・・どうやら、設計ツールの一つ、らしい。本来の意図としては。ところが受け入れテストや品質管理の概念と被って、誤解を招くようなので最近はBehaviourとしてBDDとも呼び出したようだけど。となれば、例えば外部環境との連携での異常状態をハンドリングするようなアプリを設計したとして、これをTDDで改善していこうとするとどうすりゃいいのだろうか?

  • ファイルI/O周りのエラー
  • ネットワーク接続のリトライ処理
  • 本当に意図しない突然のDB接続エラー*1
  • デプロイ失敗時の振る舞い*2
  • 高負荷時のdeadlock、あるいは競合問題

自分が携わったことのある通信プログラムでは、こうした「普通ありえなくね?」のレベルも設計段階で考慮したいやらしいほどのエラー処理てんこ盛りのプログラムがあるのだけれど、こういったのはどう書けばいいんでしょうかねぇ。TDDで対応できるのだろうか?
そして、ある程度箇所を絞った上で、当然受け入れ・・・というかシステムテストでもマジでこういった現象を再現させてます。DBのレコードをロック掛けてとめたところでケーブル引っこ抜いたり。
これ、TDDの対象範囲なの?例えば、「ありえなくね?どうやって起こすんだよ、この異常状態。」とか、「開発環境では発生しない再現性希な異常状態、高負荷状態」でのシステムの振る舞いというやつは、TDDの対象なのか?*3

多分、アプリとかシステムの対象領域によって、TDDってかなり有効性が変わってきそう。あるいは、相当独自のテストツールを自作しないとならないかも。

・・・わっかんねぇ・・・。もしもこうした外部環境との境界線上の異常状態に関する振る舞い、についてTDDの苦手分野・対象範囲外だとしたら・・・YakiBikiで、相当な時間を無駄にしていたかも知れない・・・。

*1:DB接続オブジェクトは正常に取得できたが、クエリーを発行しているその最中にネットワークケーブルが外れたりとか。・・・いえ、実際にとある通信プログラムではこのレベルまでいぢめるんですけど

*2:依存する物理ファイルが存在していない時など

*3:ちなみにこの手の異常については、単体テストの段階でソースコードを直接弄って、「無理矢理」発生させて挙動をチェックしたりしてる。他のプログラムとの結合テストにはいると、さすがにそれは出来ないけど、というか結合テストのレベルではその手のエラーはチェックしない。