マネジメント目線から考える「テストコードを書く」を習慣化させるために大切なこと

この記事は [Ateam Lifestyle Inc. Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ateam-lifestyle) 1日目の記事です。

はじめまして。株式会社エイチームライフスタイルでエンジニアチームのマネージャーをしています、@aiji42 です。

皆さんはテストコードを書いてますか？
恥ずかしながら、私自身そして私が所属する開発チームのプロジェクトでは、1年半前までは、全くと言ってよいほどテストコードが書かれていませんでした。
しかし、1年半前からチーム内でさまざまなトライアンドエラーを繰り返し、現在では私も含めてメンバー全員が「テストコードを書く」ということを習慣化し、継続的に取り組んでいます。

この記事では、この1年半の中で行ってきた取組みの中から、実際に効果的だったことをまとめたいと思います。
タイトルの通り、「マネジメント目線」でまとめてはいますが、メンバー・プレイヤーの方々にも知って実践していただきたい内容となっていますので、様々なエンジニアの方々の参考になりますと幸いです。

## チームで習慣化するために大切なこと

### 成功体験とコストを正しく捉える
今までテストコードを書いていなかったチームが、「テストコードを書こう」というきっかけの多くは、不具合の発生だと思います。しかし、喉元をすぎればなんとやらで、一時的な学習コストや導入コストが先に目についてしまい、結局「リリースのたびに手動テストをがんばる」ということに落ち着いてしまいます。
テストコードの大切さ、テストコードを書くことによる成功体験を知っていれば、目先の一時的なコストに負けて習慣化を諦めるという誘惑に、打ち勝つことができます。

実際、私は下記のことを実践しました。

#### テストコードが書かれているチームのメンバーに頼って、成功体験を聞く
人の成長を促進させるための重要な要素は**成功体験**です。テストコードを書くことの習慣化も同じで、成功体験は非常に重要な要素だと思います。しかし、チームにテストコードを書いた経験がないのであれば、成功体験も同様にチーム内にはありません。となれば、積極的にテストを実践している他のチームを頼り、多くの成功体験を聞いて自分ごとのように捉えて真似ることが重要です。
座談会のような形で自身のチームメンバーを巻き込めると、なお良しです。実際のテストコードの書き方で迷ったときなど、メンバーが自主的にチーム外に情報を収集しようというきっかけになります。

#### テストコードを書くコストはスピードとトレードオフではないということを知る
これに関しては、幸いにも多くの方が知見を示してくれています。とくに [@t_wada](https://twitter.com/t_wada) 氏の「質とスピード」というスライドは非常に参考になります。定期的に目を通すとより理解が深まるかと思います。ちょうど先日、2020年秋100分拡大版が公開されていました。
[![thumbnail](https://files.speakerdeck.com/presentations/9ca54caac3db4344bdd140015dc5e081/slide_0.jpg?16782471)](https://speakerdeck.com/twada/quality-and-speed-2020-autumn-edition)
[質とスピード（2020秋100分拡大版） / Quality and Speed 2020 Autumn Edition](https://speakerdeck.com/twada/quality-and-speed-2020-autumn-edition)


### 戦略を考える

テストピラミッドをご存知でしょうか？

![test-pyramid.png](https://martinfowler.com/bliki/images/testPyramid/test-pyramid.png)
引用: [TestPyramid](https://martinfowler.com/bliki/TestPyramid.html)

- ピラミッドの上の方は・・・
    - ユーザーに近い環境
    - 実行速度が遅い
    - 不安定
    - 高コスト
- ピラミッドの下の方は・・・
    - ユーザから遠い(局所的)
    - 実行速度が遅い
    - 安定している
    - 低コスト

とされています。そのため、テストコードの比率はこのピラミッドに沿うような形である方が望ましいです。

しかし、必ずしも**最初からこのピラミッド通りの形を目指さなくても大丈夫**です。
テストを整備する際課題として声が多いのは、テストデータの準備です。ある程度プロジェクトが成長してからテストを整備しようとすると、関連テーブルや依存関係が多かったりで、導入のハードルが上がります。テスタビリティを考慮せずに構築しているので当然のことだと思います。いきなり Unitテストから始めるのではなく、プロダクションやステージング環境に対しての E2Eテストから始めれば、このような課題は考えなくてすみます。
まずは、手を付けやすいところから始めていき、**テストに対しての成功体験を積む**ことが重要です。そして、定期的にチームの状態やプロジェクトの進行状態を鑑みて、**徐々にピラミッドの形を意識していく**とよいです。

私のチームではまずは、Unitテストからではなく E2Eテストから手を付けました。
実際に採用したのは [Cypress](https://www.cypress.io/) です。ある程度 JavaScript が書ければ、ユーザの操作を手続き的に記述していくだけでテストが組めるため、導入しやすいです。これで、まずはテストコードを書くということに慣れ、そのあと Rspec や Jest で Unitテストを書いてもらうようにしました。
もし、予算に余裕があるのであれば、[Autify](https://autify.com/ja) など、ノーコードのテストSaaSを利用しても良いかもしれません。

### 見える化する
チーム一丸となって取り組むのであれば、メンバーの貢献を可視化すると、自然にモチベーションが湧いて、良いサイクルに入れます。

一番手っ取り早いのは、カバレッジの可視化です。プロジェクトのリポジトリにカバレッジがバッチとして貼られているだけで、モチベーションが変わってきます。
<img width="300" alt="カバレッジ1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46467/4d968091-d94c-8729-b925-ca0638a30f22.png"><img width="250" alt="カバレッジ2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46467/40dbcd04-d251-a470-5291-8fde627c978b.png">

カバレッジが可視化されていると、会社のMBO制度とからめて、「◯月◯日までにカバレッジxx%を目指す」というような目標設定も可能になります。

また、プルリクエスト単位でカバレッジの上昇/低下が確認できると、メンバーひとりひとりの貢献がわかりやすくなると同時に、リリース前にアンカバーなコードやケースに気づけるようになります。
![pullrequest1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46467/2b8cc9a3-63e4-6275-1955-34cb3f945ead.png)
![pullrequest2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46467/457a9e5c-b26c-0832-69e0-4f0ace11141e.png)

私のチームでは、「カバレッジが低下するプルリクエストはマスターマージしない」というルールを設定しています。

### 仕組みを考える

せっかくテストコードを書いても、自動的に実行される仕組みや、テスト結果に応じたリリースのハンドリングが行われる仕組みがなければ、効果は半減してしまいます。
CI/CDに組み込んで実行し、テストが通らないリリースを未然に防いだり、あるいはリリース後に早期に問題に気づける仕組みの構築を、テストコードを書くということとセットで行いましょう。

また、E2Eテストは先述の通り、実行結果が比較的不安定な傾向にあります。手元のブラウザでは問題なく表示・挙動しているがテストが通らない、というような事態に遭遇することもあります。ある程度成熟したチームであれば、自己修復が期待できますが、経験の浅いチームではリリースを優先してしまい、テストコードの修復が後回しになり、最終的にメンテナンスされなくなるということもありえます。
私のチームでは、E2Eのテストをステージング環境で実行し、Failed の場合にはCIが停止して、デプロイが強制的にストップするようになっています。導入当初は、予期せぬテストの失敗で悩まされたり、チーム内でのリリーススピードを優先させるべきというような、意見の衝突も実際にはありましたが、何度も議論を重ねてこの体制を維持しています。**テストコードが正しくメンテナンスされる仕組みを、ハードとソフトの両面から構築していく**ことが大切です。

## おわりに

つらつらと書き記しましたが、山本五十六の「やってみせ、言って聞かせて、させてみせ、ほめてやらねば、人は動かじ。」という格言にもあるように、「テストを書こう」と口で言うよりも、まずは自ら率先して書くということも忘れないでください。

ということで、マネージャーの私がチームに対してテストコードを書くということを習慣化させるために意識したことをまとめました。
「プロジェクトにテストコードがなくてー」と嘆いているエンジニアの方々の役立ててもらえれば幸いです。