テストファーストな開発をしたら以前よりテストコードを書きたくなった話
はじめに
こんにちは。atama plusという教育系スタートアップでWebエンジニアをしているsekkenです。
この記事はatama plus Advent Calendar 2023の16日目の記事です。
本記事では、これまで「自動テストを実装する方が良い」という印象しかなかった私が、
自動テストを実装する機運が高まったのをきっかけにテストファーストを意識した開発にチャレンジしたので振り返ってみます。
テストファーストな開発をやってみたいと思ったきっかけ
機運
私が入社した当初はクライアントのテストコードが不十分でした。ちょうど自動テストライブラリにいくつか触れたり、スライドや書籍を読んだりしたこともあり、私の中でテストを書くこと自体も品質・生産性の向上につながるテストファーストな開発をやってみたいという機運が高まっていました。
- 本番不具合発生後の振り返りで、自動テスト強化が対策の一つとして上がった
- 試しにクライアントのUnitTestを15個書く修行をした
- QAリソースが逼迫したタイミングがあり、E2Eテストを初めて書いた
- 『質とスピード』を紹介してもらい、先に書くことで恩恵が得られるテストコードに興味を感じた
- 『ソフトウェア品質を高める開発者テスト』を読んで、そもそもテストコードを書かないとリリースまで発見されないバグが一定あることを知った
個人的なモチベーション
これまでの経験では、プロダクションコードの実装を終えた後にリグレッションを防ぐことを目的としたテストコードしか書いたことがありませんでした。
今回『質とスピード』を読んだことで、書く事自体に恩恵を感じられるテストコードを書きたいという思いが生まれました。
後追いでテストコード書くと後片付けをしてる気分になってしまい、気分が上がりきらず、「テストコードを書いてよかった〜」と実感する機会が少なかったのですが、「テストファーストで開発すると生産性が上がる」、「どんどんテストが通っていくのが快感」などのポジティブな影響があると聞いたことでやってみたいという気持ちが芽生えました。
チーム環境
チーム構成
チーム構成の紹介は下記noteが詳しいのでここでは割愛します。
現在、チーム内では下記のようなことが課題として感じています。- エンジニア4人に対してQAが1人で、まだまだ自動化できていないテストも多いことから、QAプロセスがボトルネックにならないようできるだけチーム全体で負荷分散することを心がけている
これまでの動き方
弊社のスクラムチームは1sprintの単位を1週間にしています。これまでは以下のような流れでスプリントが進むことが多かったです。
プロダクションコードを実装 & 動作確認し終わってから、追加開発時のリグレッションを防ぐ目的で自動テストを書いていました。
順調に進まなかった場合は、UTやE2Eの実装は次のスプリントに回すこともありました。
また、E2E実装はQAが書くべきシナリオを判断して実装していたため、知見が少ないエンジニアは実装を担当することが少なかったです。
図の中で使ってる用語
- 要件ワークショップ
- チームではチケット着手前にデザイナー/エンジニア/QAのスリーアミーゴスで集まって実例マッピングのワークショップをしています
- スクラムイベント
- 毎週水曜日にスプリントレビュー・レトロスペクティブ・プランニングをまとめて実施しています
- テスト設計
- 要件ワークショップでおおよその認識はあっているのですが、エンジニア/QA間で改めてチケットのスコープの確認をします
- 機能テストに加え、多端末テスト、リグレッションテストの必要性を議論します
- テスト詳細設計
- テスト設計資料作成、テストケース作成などテストの準備を行います
- Feature Test
- 作った機能が仕様と要件を満たし、正しく機能し、パフォーマンスやセキュリティに問題がないかを確認します
- 主に実機ベースで確認することが多いです
- UT(UnitTest)
- UnitTestの実装工程を指します
- 弊社では主にバックエンドはpytest、フロントエンドではjestでテストを書いています
- 可能な限りあらゆるケースを網羅したいですが、特にフロントエンドではテスト実装の知見が社内的にも少ない現状でした
- E2E実装
- Playwrightで書いています
- 基本的にはHappyPathシナリオを実装しています
テストファーストを意識した開発の流れ
改善後のプロセス
以前はプロダクションコードの実装が終わってから、自動テストを書く流れになることが多かったですが、TDDを意識して自動テストの実装を早い段階に持ってきました。
工夫したところ
- テストファーストな開発の流れにしたいという相談をして、QA/他のエンジニアに協力してもらう
- 弊チームの開発ではQAとの連携が重要なので、早めに巻き込ませてもらいました
- 他チームでテストファーストな開発をしていた経験があったエンジニアに当時の流れを聞いたうえで、自チームの開発プロセスにあった工夫する点を議論しました
- 要件ワークショップをやり、テスト前の認識合わせをする点がチーム独自の部分だったので、チューニングする必要がありました
- QA/他のエンジニア共に、テストファーストな開発をすることにメリットを感じていたので快く協力してくれました
- スプリント内に前工程が収まるよう、最初にスケジュールを決める
- 1週間スプリントとタイトなので、スケジュールを作ってQAと確認しながら実行していました
実際にやってみて感じたこと
よかったこと
やってよかったことを思いつくだけ紹介します。
実装前にテスト観点を洗い出すことで、仕様の考慮もれや実装ミスによる手戻りが減った
プロセス改善前は、「この部分の結論どうなったんだっけ?」「この部分は仕様が詰まってなかったね」という話が実装・テスト詳細設計の各工程で上がって、その都度確認・検討する流れになってしまっていた場合がありました。
が、テスト設計時にテストを書くことを念頭に認識合わせすると、「境界値を入れた時どうなるんだっけ」「コンポーネントのinput/outputはこれだから...」のような事が気になり、不確実だった部分が自然と開発工程の前半で明らかになる機会が増えたように感じます。
そして、ミスや手戻りが減ることによって体感的に実装工数が減っている実感があります。
エンジニアが担当できる工程が増え、チームとしてのフロー効率が上がった
先述の通り、QAプロセスがボトルネックになりやすいチーム事情もあり、チーム外業務やFeature Testに追われているQAの負荷を減らす工夫がしやすくなったように感じます。
具体的にいうと、以下のような動きをエンジニアがしやすくなり、チームとしてのフロー効率向上につながっていると思います。
- テスト設計のたたきをエンジニアが作ることが増えた
- テストシナリオの認識合わせが明確なので、エンジニアがE2Eテストを実装しやすくなった
リグレッションが怖くなくなった → リファクタリングしやすくなった
Feature Test実行時にバグが出た場合、修正後にUnitTestやE2Eテストを実行できるのでリグレッションリスクに対して安心感が感じられるようになりました。
今まではリファクタリングしたいと感じた際に、「QAリソースを考慮すると今回は諦めよう...」というケースもありましたが、今回のプロセス改善によりQAの負荷を減らすことができたため、リファクタリングに関する相談もしやすくなり、結果的により良いコードに改善するハードルが下がりました。
今後改善したいこと
UnitTestを書けない部分/実装 → UnitTestの順番になってしまう場合がある
- UnitTestフレームワークに精通しておらず、動作するがテストが通っていない状態(いわゆるレッド状態)にできない場合がありました
- 既存仕様が理解しきれず探索しながらコード書きたくなってしまった箇所があり、UnitTestと順番が入れ替わってしまいました
- ↑この辺りは慣れによって改善していく気がします
要件ワークショップでシナリオを詰めてそのままテストシナリオ化したい
- 要件ワークショップでおこなっている実例マッピングという手法は、ユーザーが操作するシナリオとして落とし込むこともしやすそうだと感じています
- 要件ワークショップで整理したルールをシナリオに落とし込むことでそれ自体がテストシナリオとなり、要件の整理からテストコードやプロダクションコード実装までよりスムーズに開発が進められそうだなと思っています
カバレッジを見ながらUTを拡充できていない
- カバレッジ100%を必ずしも目指す必要はないとされますが、実装しながらカバレッジを見て、ここは書く/書かないの判断を意識的に行えるようになるとなお良いと思いました
- まずはテスト書いてる事がえらい精神で徐々にやっていこうと思います
おわりに
今回は、テストファーストな開発をしてみて感じたことを振り返りました。
テストの設計やテストコード実装を開発プロセスの前半に持ってくることで、開発効率が上がったりコード品質向上に取り組みやすくなったりと、より良い開発ができるようになったと思います。
また、苦手意識があったテストコードの実装が以前より好きになりました。
これからもより良い開発プロセスになるよう、改善を続けていきたいと思います。
明日は @tanimuranaomichi さんの「新卒Webエンジニアが「あえて自分が詳しくない仕事にも挑戦してみよう」と思った話」です。ぜひご覧ください!
Discussion