「単体テストが面倒くさい」に立ち向かう ―5つの弾丸

やらなきゃいけない。
でもやる気が起きない。
そんなときがありますね。

特に単体テストは、プロダクションコードの進捗に直接は寄与しませんし、技術的にもチャレンジングなところはありませんから、モチベーションを上げるのに苦労するのも無理はありません。

そこで対処方法を挙げてみました。

リファクタリングする

AAA (Arrange, Act, Assert)Arrange が面倒で、立ち尽くすことがあります。

チャンスです。
面倒なのはメソッドが複雑な証、リファクタリングしましょう。
具体的には、メソッドの抽出クラスの抽出を検討しましょう。

本筋から外れる依存処理を外部に切り出すことができれば、単体テストも簡素化でき、変更時に受ける影響も限定的になります。

単体テストを書くのは変更時のリスクを減らすためでもあります。
変更の影響が広範囲のテストコードに及んでしまっては元も子もありません。

簡素化できれば実装も楽しくなる、一弾二狼です。

Act を先に書いちゃう

これ私よくやります。
リファクタリングは施した(あるいは見送った)。
それでもなお(あるいは当然に)、Arrange を面倒に感じてしまうことはあります。
人間ですから気持ちの波もあるでしょう。

そんなとき、まず Act を書いてしまいます。
考えなくてよいこと、迷う余地のないことから始めるのです。
そこに必要なコードを足していきます。

渡す引数が準備できなければコンパイルエラーになるでしょう。
いいんですそれで。
プログラマはエラーが嫌いです。
問題を放置できません。
本能的に反応します。
ああ、解決しなきゃ。
引数はどう準備したらいいだろう。
いったん解決欲に火がついたら、テストが通るまで我には返れません。
モチベーションはそれまで安泰です。

プログラマの性を利用して、自分を巧みに引き込む作戦です。
やや大げさでしたが、意外に功を奏しますので、ぜひ一度お試しを。

モック処理を共通化する

毎回同じようなことを書いてる気がする。
決まったことに手数とコードが費やされる。
これらは悪い徴候、つまり改善のチャンスです。

モック化の肝要な点は Setup ですが、変数宣言、インスタンス生成、VerifyAll など定型的なコードが増えがちです。
テストメソッド間で共通する定義や処理は、テストクラスに共通化することもできるでしょう。
ただし、一部のメソッドでしか使わない依存オブジェクトまでやみくもにモック生成するのは無駄です。
また、テストクラスにフィールド定義するのも疲れますし、フィールドが増えて追加するのも面倒です。

DIコンテナを活用してモック化の枠組みを構築することで、こうした煩わしさから解放されることができます。
前記事に引き続き、手前リンクで恐縮ですが、一例としてご紹介します。

[.NET] 単体テストがさくっと書ける!モック化の枠組み(Moq + Unity)
[.NET] 単体テストがさくっと書ける!モック化の枠組み(Moq + Autofac)

プロジェクトにあわせた仕組み化を検討しましょう。
単体テストにかける(結果的にかかる)工数の大きさと、単調なことに費やす心理的負荷の生産性への影響度を考えれば、どうすれば効率化できるか、時間をかけて吟味する価値は十分にあると思います。

カバレッジの数値目標を立てる

ゲーム的な達成感がやる気のアクセルになります。

ただし、ノルマ化には注意が必要です。
義務感でかえってやる気を損ねかねません。
うまくポジティブな目標に落とし込むことが大切かなと思います。

また、数値稼ぎが目的になってしまうおそれもあります。
乱雑なテストコードを書き殴ったり、形式的で意味の薄いケースが氾濫してしまうのは避けたいところです。
単体テストのリファクタリングは、プロダクションコード以上に意図を汲み取るのがたいへんで苦労することがあります。

数値は極度に単純化された一つの指標にすぎず、品質を直接に担保するものではありません。
わかりやすいから重宝されるだけで、あくまで事実はソースコードの中にあります。
補助的に使用しましょう。

機械になる

脳のメモリを消費しない。
対象メソッドのロジックを上から追いながら、機械的にテストコードに変換していく。
処理の意味など考えない。

実はこれ、だめです。
単体テストは、想定漏れや不適切なクラス構成、命名に気づく貴重な機会です。
せっかくの機会を、プロダクションコードの正当性を表明するためだけに費やすのはもったいない。

これはリファクタリングにも通じることですね。
デッドコード、はい、消します。
気持ちがいいのはとてもよくわかります。
でもちょっと待ちましょう。
メソッドを作って呼び間違えているだけでは?
単に余分なだけなら運がいいと思わなければいけません。
リファクタリングが必要なコードベースを相手にしていることを忘れずに。
せっかく臭いを発してくれているわけです。
リファクタリング自体は既存の動作を保持するのが基本ですが、その過程で潜在的な不具合が見つかることは多々あります。
機械的に処理してしまうのはもったいないです。
まずは嗅ぎましょう。
そして臭いの元を突き止めましょう。

戻りまして。
機械的な作業は機械がやってくれます。
人間がやっているとしたら分担が間違っています。
人間でいましょう。

この記事が気に入ったらサポートをしてみませんか?