SiG Staff Blog

会社の中で流行らそうとして、試したことを書いていく

社内でテスト駆動開発をどうやって始めるか

思い立った背景

今の会社ではxUnitテストをしておらず、このままだとコードのメンテナンスが大変になってしまうので
Unitテストを今年から導入していきたい。
いくつかのプロジェクトで、開発途中の状態からテストを追加したり、保守フェーズの時にテストを追加したりしてきた経験の中で、
こうしたほうが良いのではないかと思ったことをまとめてみようと思った。

※ 私がテスト駆動開発(TDD)をちゃんとしたことが無く、書籍や動画で見た内容と上の経験からこの様に実施していこうという内容になるので、このやり方が正しいというわけではないです。

実際にどうするかを詳しく知りたい場合は、下の様な本を読むことをお勧めします。

プロジェクトで実施しようとしたときによくある話

Unitテストをしたことが無いメンバー達に、「やりたいんだけど」と話をすると
きっと下のような話が上がると思う。

プロジェクトマネージャとか営業から

  • テストを書けばシステムの品質が上がるんでしょ。
  • 一回書けば、テストをしなくてもよくなるんでしょ。
  • テストコードを書くための予算をとれない。

ディベロッパーから

  • テストコードを書いている時間かない。
  • テストがしっかりと網羅されているかわからない。
  • どこまでをテストすればよいか不明。

これらはどれも正しいけれども、間違ってもいます。
これは「Unitテストでどこまでの事をテストするか」という事がチームで共有されていないことが原因。

Unitテストでは、

のどれを行うのか。という認識を共有する必要があると思います。

ディベロッパーは動作検証と思っていたが、営業は受け入れテストをしてあると思って、

「自動化させているのでテストはすぐ終わるんですわ。」

って話をしてしまい、ディベロッパーが苦しむ。
なんてこともあるかもしれないのです。

テスト初心者はどこから始めていくか

プロジェクトマネージャやプロジェクトリーダーは、受け入れテストをしたがると思うが、 それをしようとすると、

  • 当初の計画になかった作業(テスト用にDBを作ったり)が発生する。
  • テストが複雑なものになりがちなので、テストコードを書くのに時間が必要。

になってしまい、前述の不毛な言い争いが始まってしまう。

なので、動作検証のテストを実施するところから始めるのが良いと思う。
テストについて話しているPodCastでも、動作検証のテストを自動化させているような感じに聞こえるので、
ここからやってくのが常套手段なんじゃないかな。

”どのクラスのテストをしていくか”だけど、ドメイン駆動な感じの実装ではなく、MVCな感じで実装がされていると思うので
Mの部分でやっている事や共通で使用する便利クラスに対して実装していくのがいいかと思われる。
例えば、ModelとかServiceとかUtilityとかがメソッドが分かれていてしやすいのではないかと思います。

テスト駆動開発の進め方

和田卓人さんの動画が非常にわかりやすいので、こちらを見てください。
※ 少し長いので2倍速でみてもいいかも。

テストをどこまで書けばいいのか

和田さんがゲストで出演したPodCast - ajitofm 13: Test Driven Developmentで話題に上がっていたのですが、

「不安に思った所をテストすればいいんだよ」

と言っていました。

なるほどです。

最低限の動作検証のテストは行い、自分が「このパターンの時、思った通りに動くか不安」と思ったらそのテストも追加しろというわけ。
分かりやすい。
そんなルールだと個人差が出るじゃないかと思うかもしれないが、どんなにルールを作っても個人差が出るので同じ事。

経営陣とディベロッパーが言っていた内容について

品質が上がるのか問題

「動作検証では品質の向上や担保ができないんじゃないか?」と聞かれるかもしれません。
開発初回では、メンバーがちゃんと動作検証を行うような人がそろっている場合は、実質変わらないかもしれません。
その後に、仕様の追加などで変更があった時やリファクタリングをしようとしたに、

「以前作った箇所は動きが変わっていない」

ということが担保できるので、後々で品質保証ができる。
質の向上に関しては、フィーチャを作成しているときにテスト(どのように動作させたいか)を考えながら作らざるをえなくなるので、
質が自然と上がると思われます。
テストコードのレビューが最初は必要になるかもしれませんが。

テストコードを書いている時間がない問題

フィーチャを実装する時に絶対に動作検証を行っていると思います。
それは画面から動かすのか、メソッドを呼び出しているのかは場合によると思いますが、
その時間がテストコードを書く時間になるだけなので、そんなに時間は変わらないかと思います。

単体テストはするのか問題

現段階ではテストは動作検証しかしていないので、単体テストはしていない状態ですのでするべきかと思います。

単体テストも自動化させる場合は、テスト項目を洗い出してユニットテストとは別で管理するのがいいかと思います。
きっとテスト漏れが起きると思います。

個人的には単体テストは目視での確認など下ほうが良いと思っています。レイアウトの確認などもあると思うので。

テストをやりやすくするために

テスト駆動で開発をするなら、テストがしやすくないと開発がしにくいということ。
なので、プロジェクトで「どのクラスがどんな役割を担うのか」ということをチームで共有することが大切になる。
その為の良い設計がドメイン駆動開発(DDD)であり、チームがスクラムであることかと考えています。

現実問題として、スクラムを組める環境じゃなかったり、メンバー全員にDDDについて簡単にでもわかってもらうには時間がかかると思うので、
「いつでも、なんでも、どこでも、発言ができて、それに対してチームからリアクションがある」チーム作りをしておくことが大事。

それでもやらないとか言われる時

やらない理由を探す人によって邪魔をされる時は、
自分一人でいいから先に軽くやっちゃって、それに共感してくれるメンバー(フォロアー)を作り、「やっちゃおう」という雰囲気を作ってしまえば、
いつの間にか定着すると思います。

最後に

同じような確認を何回もして時間を浪費していたあの頃とはおさらばできることを信じて、社内の開発に浸透させていこうと思います。
ちょっと強引にでもw