読者です 読者をやめる 読者になる 読者になる

Life is Really Short, Have Your Life!!

ござ先輩の主に技術的なメモ

テストコードをドコまで書くのかみたいな話

id:amachangとFBでちょっと盛り上がった。

自社の業務システムを組んでいるので仕様は全部自分の頭に入っているし、昔書いたコードをライブラリ化して流用した部分でカバーできてビジネスロジックもそんなに複雑じゃないこともあって、全然テストコード書いてなかった。ライブラリやフレームワークに依存しているコードのテストコードは要らないし、そういうコードも多い。

昨年10末に突貫で用意したシステムが思いのほか手応えを感じるようになり、こいつをベースに今の理想のシステムを作る事にした。売れるぞこれは、という手応えがあったので。現在はひどいコードもたくさんある現行システムと、ひどいコードを書いたおかげで当社比10倍に洗練されている新システムの2つが走ってる。現在の作業の割合は2:8ぐらい。で、後者はテストコードを書いている。

その2つを比べてみて、テストコードを書いて感じた事を書いてみる。

ビジネスロジックはテストコード必須

人間凡ミスを結構やらかすんですね。登録されているべきレコードが入っていないとか。スペルミスが原因でとか。直すのは瞬殺だけど瞬殺レベルのミスが続くと人間性疑われるので、どんな凡ミスも許されないビジネスロジックはテストコードを絶対に書くように決めた。テストコードを書いておく事で、つまんないバグが防げる。特に複数テーブルにまたがるビジネスロジックは、テストコードを書いておかないとつらい。

ライブラリに依存したコード(XML読み込みとか典型)のテストコードは要らない。そんなのテストしても品質上がらない。無駄なカバレッジ向上乙。

テストコードと実装コードの間隔を空けない

単純な問題で、何が正しいのかを忘れるんだ。3日も経つと。そして、腰が重くなる。

僕は先に実装コードを書いてローカルで動作確認後、ある程度I/Fが固まってからテストコードを後で書く派。どっちが先でも良いと思う。でも、テストコードを書いていると、テストするコードを短く書けるようにしたいと思うし、同じようなテストは限りなく纏めてコードの密度を上げようとする力学が働くように思う。ベタにassertしてるからこそ、コードが洗練される要素が見つかると思う。テストコードって地味なコードが多いので。

特に仕様が頭に入って既にゴールが見えている場合、実装コードをサクっと書いて野球でも見るしかないぜってノリで書いちゃうんだけど、1ヶ月後にすげー似ている処理がいっぱい出来たので後悔しました。テストコードを書いていれば、担保すべき動作が先に見えるのでもっとマシになってたと思う。現行システムはここでくじけた。

テストしにくいコードは危険なコード

assert文に落とすのに思いのほか時間がかかったら、そのメソッドはテストするのには複雑すぎるみたいです。ビジネスロジックはビジネスルールとDB操作の2つに大別出来るので、まずは後者の動作を担保するテストコードを書くと良いと思います。そうすると、どの単位でテストすればいいかという指針になる。ビジネスルールの担保はうまくインターフェイスとオブジェクトが抽出できていれば、かなり楽になる。オブジェクトの切り替えとルールの切り替えを寄せるイメージ。

テストコードを書いて漏れに気付く

業務アプリは特にその傾向が強いと思うんですが、何かの値が変更になったら別の値も変更しなくてはならない、ということが頻繁に起こります。注文数が増えたら増加分の在庫を引き落とすし、キャンセルになったら在庫を戻してあげる必要がある。伝票日付が変わったら、締め日処理の再集計が必要など。

意外とこういうのは実装している時にはわからなくて、テストするぞっていう段階になって「あれ、こーゆー仕様になってないと、業務としてはこれをお客さんに出すんだから、このままではシステムが正しい事にならない」ってことに気付く事がある。実装してる本人は動くコードを書いて早く帰りたいわけで。

なので、ビジネスロジックで担保しなくては行けない事に、テストコードを書く時に気付くことはよくあること。テストコードに花束を。

引数にこういう値が入ってこないと!

みたいなヤツはテストコード書いてないし、そのメソッドを実行するのに必須ならExceptionぶん投げて終わり。引数のチェックはテストコード以前の問題だと思うわ。おほほほほ。

分岐の多いテストコードに気をつけよう

それは実装コードがやっつけ感満載である可能性が否めない。ソースは俺。

テストコードの利点はデグレの防止

今動いている自社の業務システムもかなり色んなものを足していきました。で、つまらないバグがその度に出て(必要の無い分岐を通してしまったり、ある条件だけnullになったり)しまった。デグレはユーザーが一番不信感を抱くので、デグレ箇所の早期検知の為にも、ビジネスロジックにはテストコードを書いておきたい。

以上だぜ。