あなたのチームではコードレビューやテストをどうやっていますか？

# やりたいこと
Advent Calendar に参加するので、以前に開発体験を向上させた内容を共有してみようと思います。
内容としては、コードレビュー時の内容やテスト自動化についての取り組みといったよくあるものですが、何かの参考になれば幸いです！

:::note warn
内容については、数年前のものなので忘れている部分や全部は公開できない部分があるので、割りとざっくりだったり一部ぼかしたりしています。
:::

# 背景
数年前の開発時の話になるのですが、6名程度のチームで開発を行っていました。コードは GitHub で管理し、機能開発用のブランチを作って PR を出して他のメンバーのレビューを受けて問題なければマージするというよくある流れです。
それなりのスプリントが終わった頃、レトロスペクティブで1つの Problem が挙がりました。それが、「コードレビューに時間がかかる」というものでした。

たしかにスプリントを重ねてもあまりベロシティは上がらず、メンバーのスキルを鑑みてもやや低めだなとは思っていました。そこにも関係していそうだなーと感じ、当時スクラムマスターをやっていたこともあり、この Problem を次スプリントの Improvement として取り組むことにしました。

# なんで時間がかかっている？
次のスプリントが始まり、さっそくなぜ時間がかかっているのか原因を特定していきます。
まずは、チームでその内容について話す時間を取り、メンバーからの意見を吸い上げました。挙がった意見は以下のような感じです。

1. ビルドに時間がかかる
1. テストに時間がかかる
1. 何をレビューすべきか迷う
1. 他アプリとの結合テストができていない

## それぞれ原因を深掘りしてみる

### 1. ビルドに時間がかかる
当時、開発していたのは自動車向けの組み込みアプリケーションでした。自動車に搭載されているカメラやセンサデータ、アプリケーションログなどを収集してサーバにアップロードする機能を持つアプリケーションです。開発は C 言語で行っており、ビルドが必要でした。テストを行う際もテストコードのビルドが必要なので、テストケースが増えるにつれてビルド時間も長くなっているという状況でした。
また、当初使っていたビルド用の Makefile はシステム全体のアプリがビルドされるものだったので、余計なものまでビルド対象になっており、それも時間がかかる要因になっていました。

### 2. テストに時間がかかる
これもテストケースが増えるにつれてテストの実行時間が長くなっている状況でした。当時は各担当者が手動でテストを実行しているという状態だったので、待ち時間が多く非効率になっていました。自動化よりも実際の開発タスクを優先していたので、後手後手になっていた結果です…

### 3. 何をレビューすべきか迷う
ある機能を追加・変更した際、基本的には担当者が実装とそのテストコードを書いて PR を出すという流れでしたが、レビューの際に Reviewer が追加・変更内容の確認だけでなくローカルでテストの実施している場合があり、前述の通りそのテストに時間がかかっているという場合がありました。これはレビューを担当する人それぞれで異なっており、やっている人もいればやっていない人もいました。そういった部分でレビューの観点が統一されておらず、品質にも影響が出ているような状況でした。

### 4. 他アプリとの結合テストができていない
センサデータやログなどを収集するという機能上、他アプリケーションとの結合テストが必要ですがセンサなどは実際の車体にしか搭載されていないため、車体でのテストフェーズで確認するしかなく、そこでうまく動かないことが分かるというケースがありました。そこで手戻りも発生してしまい、リリース期日に間に合わせようと遅くまで残業するということも発生していました。

# どう改善するか？
チーム内で話し合い、以下のような方針としました。それぞれの対策に対して優先度をつけ、今後のスプリント内で取り組んでいくことになります。

|  | 対策 |
|--|--|
| 1 | ケースに応じてビルド対象を絞る |
| 2 | CI/CD でテストの自動化に取り組む |
| 3 | レビュー項目を定義する |
| 4 | センサや他アプリを模擬するアプリを作成する |

# 具体的にどうやった？

## 1. ケースに応じてビルド対象を絞る
以下のケースに応じてビルド対象を絞った Makefile を作成し、ビルド時間の改善を行いました。特に、デバッグ時にはビルドする回数が多いので大きく効率化できました。
実はすでにそういった Makefile を独自に作っていたメンバーもいて、チーム内で会話することによって他メンバーにも共有できたのは非常によかったと思いました。

| ケース | 範囲 |
|--|--|
| デバッグ時 | 担当アプリが影響する範囲 のみビルド <br> アプリ本体のコードやそのテストコードが対象 |
| PR 発行前 | 他アプリケーションをすべて含む範囲 |

## 2. CI/CD でテストの自動化に取り組む
手動で行っていたテストを CI/CD　パイプライン上で行います。当時は、GitHub Actions でパイプラインを構築し、手動で行っていたテスト類を行うようにしました。
また、何かパイプライン上でエラーが起きれば Slack へ通知するようにしたので問題が起きた場合も気づきやすい形にしました。

## 3. レビュー項目を定義する
Reviewer それぞれでバラバラだったレビュー項目を改めて定義しました。内容としては 1, 2 などのビルドやテストの観点や、その他必要な項目をチーム内で話し合って決めていきました (具体的な項目は省略します)。
レビュー項目を定義したことで、レビュー内容のばらつきがなくなりレビューにかかる時間も短くなりました。

## 4. センサや他アプリを模擬するアプリを作成する
前述の通り、車体でしか動作を確認できないケースがあったので、そこを模擬するためのアプリを作成しました。各センサデータのフォーマットは決まっているので、その通りにデータを作成し開発しているアプリ側に受け渡したり、インターネットとの通信機能を持つアプリも模擬して作成したりして、受信と送信部分を模擬することができました。
このアプリにより、実車で試験する前にデータの受信・送信についてのテストができるようになり、品質も向上し生産性が大きく改善されました。

## 改善結果
取り組んだ改善に対して改善結果は以下の通りです。


|  | 対策 | 改善結果 |
|--|--|--|
| 1 | ケースに応じてビルド対象を絞る | ビルド時間を約20%削減できた |
| 2 | CI/CD でテストの自動化に取り組む | テスト時間を約30%削減できた |
| 3 | レビュー項目を定義する | レビュアー間でのばらつきがなくなり、一定の品質を担保できた |
| 4 | センサや他アプリを模擬するアプリを作成する | 実車評価前に問題に気づくことができ、生産性があがった |

# ということで
以前の生産性向上についての内容でした。
振り返ってみると、やはりある程度のルールや自動化は必要だなと改めて感じます。特に自動化は早く導入するほど効果があるので、スタート直後にやっていてもよかったのかなと思います。
また、6名程度のチームであっても個々人間で持っているノウハウが違っていたので、スクラムにおいて対話は非常に重要だなと感じました。

皆さんのチームではどういった形で生産性や開発体験を向上させているでしょうか？それぞれのチームに合った方法はそのチームでしか作り出せないと思うので、そのあたりもコメントなどしてもらえると嬉しいです。


以上です。