Posted at

テストを書くかどうか議論するの不毛だから、どうやってテストを書きやすくするか議論しよう

More than 1 year has passed since last update.

スピード感重視なのでテストは書かない。テストはなぜ開発を遅くするかという記事がバズりました。みんなテストについて思うところがあるようだ。テストを書くべきか否かは机上の空論になりがちで不毛なので、どうやってテストを書くか、テストの書き方、について、種を巻いた私が書いておく。

もっと詳しい方からのお話お待ちしています


書くこと

テストの書きやすくするためのいろいろ(箇条書き)


書かないこと

テストの基本


テストファースト

実装ありきでテストを書くのではなく、テストありきで実装を変える。

はっきり言って、テストを考慮せずに実装されたコードは、書き直さずにはテストできない。

そういう点で、テストなしで実装する選択肢は不可逆なので、初期実装では特に注意が必要。


クリーンアーキテクチャ(DDD)

クリーンアーキテクチャの考え方はテストファーストを語る上で重要。私個人としてはまだクリーンアーキテクチャをマスターしてないが、見様見真似でも劇的に効果がある。

基本的には、レイヤーを分けて、依存関係を一方向に限定すること。特にテストを語る上で重要なのが、インターフェイスをビジネスロジックから分離する点。ビジネスロジックは、使っているストアがmysqlだろうがS3だろうがElasticSearchだろうが、全く感知しない。どんなストアであっても同じように動作する。同様にUIがなんであってもビジネスロジックは感知しない。

何が嬉しいかというと、


  • 変更に強い

  • テストを書きやすい

  • フレームワークやデータストアに依存しない

といった感じ。

クリーンアーキテクチャは、なんも考えない場合に比べてテストコストが遥かに低い。

具体的なやり方は長くなるので調べてくれ。


TDD

テスト駆動開発は、テストファーストの文脈で一緒に語られやすい手法。ただ、テストファーストとは違う部分もあり、一概には語れない。(なお、上に書いた私のバズった記事では、Learning resources以外の文脈ではTDDについて一切触れていないのに、TDDの記事だと誤解なさった方が多数いた)

基本的な考え方は、タスクをテストとして書いて、先に動かして後からきれいにするという感じ。こちらも具体的な方法は長くなるから調べて欲しい。

注意点は、TDDにおけるテストは開発におけるマイルストーンみたいなもので、実運用する際のテストとは根本的に異なる、という点。TDD時に書いたテストを流用することがあるのは確かだが、「TDDで書かれたテストは実運用に耐えない(からTDDはよくない)」みたいな批判は的外れもいいところ。

よくある批判は、ユニットテストの粒度が細かくなりすぎること。


自動化

大切なことなので書いておく。自動で実行できないテストはごくまれにしか実行されない。ちょっとコード書いたらさくっとテストできるのが理想。(状況次第では分単位、時間単位でかかるけど)

想定通りに動いているかどうかを常に担保しておくのは非常に安心感がある。

自動テストの恩恵に預かり、テストいいじゃん、と思ってもらうと、同僚がテストを真面目に考えるようになる。

キーボード・ショートカット設定しておくくらいがちょうどよい。


スタブとかモックとか

実際に使うのが難しいツール(クラウド上のサービスとか)のそれっぽい偽物を用意して、テストする手法。TDDはモック地獄を生み出しがち、とたまに言われる。

スタブとモックは違うものだけどこちらも調べてくれ。


まとめ

ぶっちゃけクリーンアーキテクチャの話だけでこの記事の8割は終わっている。設計段階でミスするとどうしようもなくなる。インターフェイスは必ず分離しよう。

前回の記事でテストの習得コストの高さを無視するな、みたいなコメントを頂いたが、技術がないことを開き直るな、と言っておく。

私もまだまだ未熟なので精進します。