📑

テスト駆動開発(TDD)やってみた!

2025/02/12に公開

こんにちは!ソニックムーブでエンジニアをやってる新卒3年目の福田です!
普段自社サービスのcomsbiの開発を行ってる民です😊

そんなcomsbiですが、開発をするにあたってテストのルールとかテストの粒度とかあんまり決められてないなと思ってた今日この頃。
テストを最初に作ればテストのルールとかもうまくできていいんじゃないかなと思いました!

そんな悩みにテスト駆動開発(以下TDD)っていいんじゃないと気になり、TDDで1案件動かしてみました!
最初は個人的にそこまで魅力に感じなかったですね。ですが一方で、案件内のメンバーはTDDの満足度が高く、今後も使っていきたいって感じでした。そして、議論していく中で、TDDの本質ってここだよねってことも気づきました。議論って大事だなぁ。。。

てことで、そんなTDDについて、特徴やらそこで出たメリット・デメリットとかを話せればと思います。

テスト駆動開発(TDD)概要

テスト駆動開発(Test-Driven Development, TDD)は、ソフトウェア開発手法の一つで、テストコードを先に書いてから実装を行うのが特徴です。従来の開発手法では、コードを書いた後にテストを実施しますが、TDDでは「テストを書く → テストが失敗する → 実装を行いテストを通す → リファクタリングする」というサイクルを繰り返します。

TDDの特徴

テストファースト

最初にテストを書くことで、求められる仕様を明確化し、余計な機能を実装せずに済みます。

短い開発サイクル

「テストの失敗 → 実装 → リファクタリング」を短いスパンで回すため、小さな単位で開発が進められます。

リファクタリングが容易

テストが担保されているため、コードの品質を向上させるリファクタリングを安心して行えます。

TDDの長所

バグの早期発見

テストが常に動作するため、バグを早い段階で発見しやすくなります。

保守性の向上

コードがテストによって保証されているため、変更を加えても動作が保証され、メンテナンスが容易になります。

開発の効率化

仕様が明確になるため、手戻りが減り、開発の効率が向上します。

ドキュメントの代替

テストコードが仕様の一部として機能するため、ドキュメント代わりになります。

TDDは最初の学習コストがかかるものの、長期的なプロジェクトでは高い品質と効率性を実現できる有用な開発手法となっています。品質を上げるのにはとても役立そうです。

実際の開発で感じたメリット/デメリット

今回、TDDをするにあたり、以下の流れを基本形として開発することにしました。

  1. 該当クラスのテストをまずは書く
  2. 該当クラスのテストが通るようにとりあえず動くコードを書く。テストが通ればOKなのであらゆる不正手段を使ってOK
  3. レビューに出す(テストケースが漏れてないかの確認)
  4. テストを確認しながら正常に動くコードを書いていく。リファクタリングを行いながら進めるのがいい
  5. レビューに出す

上記で開発を実践し、案件内のメンバーにもヒアリングを行ってメリットデメリットを抽出しました。

メリット

仕様に沿ったコーディングができる

テスト項目を挙げる時点で、作成するクラスについての仕様を整理し、実装に移れるのがGoodだと思いました!
複雑なシステムほど、作成から入ると抜け漏れが発生したり、テスト忘れが発生したりするので、最初にテストで整理できるのは一番の魅力だと思ってます。

テストさえできればリファクタリングし放題

テストが要件通りにできて、間違えなく動くことがわかってしまえばこっちのもの、あとは好き勝手本体のコードをいじることができます。
仮にいじりまくってもテストが通れば大丈夫です。テストさえ通れば絶対に合ってるといえるので!

テストもしっかりレビューできる

comsbiではシステムを作成するときにテストコードと一緒に出すことが多い気がしてます。(自分だけかも)そうなるとレビューする方も大変。結構テストコードが疎かになってしまいます。
でもテストコードからレビューを出すのであればテストコードが正しいかどうかを見ることができるのがGoodです!

テストさえ通ってるのであればコードのレビューは誰がしてもOK

これ今回の案件ではやらなかったんですが、テストコードさえ通ってしまえば、仕様を把握してない人でもコードレビューができるようになります!(書き方等)
仕様部分はテストコードが補填してくれてるんで、ユニット内での書き方とかにレビューの時に注力できるって感じですね!

デメリット

簡単なコードだとただただ面倒

例えばDBから該当データを取り出すだけの処理をテストする場合、大体頭の中にコードが出来上がってます。
テストの要件を出すとしてもだいぶ少なく、そもそもTDDでやる必要あるのか?従来通り実装コードから書いた方が楽じゃないかと思ってしまいます。

でも今回が初案件だった新卒の子は意外とテストから書く方がやりやすかったと話してくれました。ここの部分は慣れの問題で、テスト駆動開発を行い続ければむしろテストから書くほうが良くなったりするのかもしれないです。

仕様の追加等をした時にごちゃごちゃになる

いざ、実装コードが完成!となってもシステム開発とは戻りがちょこちょこ発生します。。。
そうなったら最後、今まで信頼をおいてたテストコードを書き換えないといけないです。

今回のやり方だと戻りが発生していた時の方法まで考えてなかったので、そうなったが最後、たちまちテストコードに信頼が置けなくなり、結局ごちゃごちゃになってしまいました。。。
特に複雑なコードほど、ここの部分に信用を置けなくなっていき、振り返る際にたちまち頭が焦げてしまいます。。。

ただ、ここの部分についてはそもそも複雑すぎるコードがいけないんじゃないかという意見が出ました。テストコードが複雑になるときはときはそもそものコード自体が悪いってことを意識した方が良さそうです。

本質の話

こんな感じでメリット・デメリットを話していったとき、メリットの部分で以下のような意見が出てきました。

  • テストコードをペアプロで話し合ったのがよかった
  • テストを先に書くことよりテスト項目を話す方がいいのでは?

実際考えてみると、自分がTDDを導入しようとしたところは以下の観点でした。

そんなcomsbiですが、開発をするにあたってテストのルールとかテストの粒度とかあんまり決められてないなと思ってた今日この頃
テストを最初に作ればテストのルールとかもうまくできていいんじゃないかなと思いました!

これの本質って「仕様に対するテストの項目をしっかりと考えた上でテストを書いた方がいい」だと思いました。
つまり、TDDで大事な要素として「仕様通りのテスト項目が用意できているかどうか」なのではないかという結論になりました。決してテストを先に書くのが大事ってことではなさそうです。

確かにテスト項目が正しいのであれば、あとはその項目に沿ったテストを書けばいいわけだし、そのテストが通るコードを実装できればコード自体も問題ないです。さらにそのテストは仕様書の代わりにきちんとなれます。

上記を考えたとき、テスト駆動を行うにあたり最も理想的な進め方は以下だったのかなぁと思いました。

  1. 該当処理のテスト項目について考える
  2. レビューに出す(案件内のリーダーに出す。ペアプロで話し合ってもいい。)
  3. テストコードを書く
  4. テストが通るようにとりあえず動くコードを書く。テストが通ればOKなのであらゆる不正手段を使ってOK
  5. テストを確認しながら正常に動くコードを書いていく。リファクタリングを行いながら進めるのがいい
  6. レビューに出す(これは誰に出してもいい。)

もちろんこの順番で書くことが望ましいですが、DB検索を行うだけの処理など簡単なコードに限り3〜5は入れ替えてもいいのかなぁと思ってます。難しいコードはテストから書いた方がメリットを感じられそうですが、簡単なコードでテストから書いて煩わしく感じてしまうなら、それは本来の目的を失ってるように感じるからです。あくまでTDDをやることが目的ではなく、より仕様に沿った保守性の高いコードを書くことが目的ですからね。

6についてですが、これは案件外の人に見てもらうのはだいぶアリだと思っています。テスト項目はレビュー段階で保障されているので、仕様を理解してなくっても案件外の人がレビューすることは可能です。案件外の人にも見てもらえれば会社やチーム内でコードの書き方とかを統一するきっかけになれるのでいいのかなあと思います!

テスト項目のレビューについてはリーダーのみのレビューでも特段問題ないとは思います。ただ、ペアプロとかで話し合った方が色々な目線からテスト項目を吟味できるのと、案件内のメンバーとの仕様把握のきっかけに繋がるのでペアプロでするのがおすすめかなぁと思ってます。
テスト項目はみんなで考えるようにしましょう。

反省とこれから

初めてのTDDの実践。振り返ってみると思うようにはいかなかった気はします。やっていく中では自分はメリットを感じなかったです。
ですが、案件内のメンバーはTDDの満足度は高めで、これからも使っていきたいという立ち位置でした。これは結構いいことだと思っていて、磨いていけばより良い開発環境を作ることができるのではと感じました!テスト駆動の知見を溜めていき、自分自身でもメリットを感じられるようになるまで磨いていきたいですね。

本質の「テスト項目の確認」というところは本当に大事というのは案件を通じても感じました。今後、ここの部分はうまいこと仕組み化していき、より良いTDDの開発環境を作っていければいいなぁと思います!

株式会社ソニックムーブ

Discussion