これはREADYFOR Advent Calendarの19日目の記事です。
こんにちは、READYFORでバックエンドエンジニアをしている斉藤です。
この記事では私がREADYFOR入社時からコツコツと進めてきたRuby on Railsアプリでコードカバレッジ30%から50%にするためにやったことを時系列に紹介したいと思います。
みなさんはちゃんとテストを書いていますか?
開発が忙しすぎて後回しになってしまうなんてことは良くあるかと思います。
しかしスタート間もないサービスだとそこまで困ることはないかもしれませんが、数年経ってくると色々な弊害が出てきます。
- リファクタしたいけどテストがないから怖くてできない
- その場しのぎの継ぎ足しの変更を続けどんどん複雑なコードになっていく
- ちょっとしたコード変更にも時間がかかるようになる
- 明らかに不要そうなファイルやコードあるけど確信が持てず削除できずどんどん溜まっていく
そうなってくると開発スピードはどんどん遅くなっていってしまいます。
そしていつかはこの問題に向き合わなくてはなりません。
私がREADYFORに入社した2018年当時、コートカバレッジは30%弱(28.5%)でした。
(少なっというのが正直な感想)
入社時にコードリーディングをしていると、結構複雑で理解するのが大変だな〜という印象でした。(これは後から入社したメンバーも皆さん一様に言っていた)
そしてコードの様々な箇所にはたくさんのTODOコメントが残されており、先輩エンジニアの方々もつらみを感じつつ開発に追われていたのだろうと思いを馳せずにはいられません。
これはなんとかせねばと着手することとなりました。
メイン開発タスクの傍らで進めていくことになりますが、2020年が終わるまでに50%達成を目標にします。
テスト追加期(2018〜2019)
まずはじめにやったことは
- テストを書く体制を整える
- テストを書く意識をエンジニア全体に持ってもらう
テストを書く体制を整える
当時はすべてMinitestで書かれていたのですが、RSpecを導入することにしました。
これは正直どちらが良いということはなく好みの問題だと思いますが、RSpecのほうが書きなれているメンバーが多かったことと、ネット上や書籍の情報が圧倒的に多いためRSpecを選びました。
そしてベースとなるテストを書いて、後はそれに倣って追加していきます。
これはあまり厳密にルールを決めなかったため、後に後悔しました。
ある程度ルールを決めちゃったほうが迷いがなくなるので、ガチガチになりすぎない程度に決めておくことをオススメします!
テストを書く意識をエンジニア全体に持ってもらう
開発はどんどん進んでいきます。
これまでは必要最低限のテストのみ書く体制でしたが、これ以上テストのないコードを増やさないように新規で追加するコードに対しては必ずテストも書いてもらうようお願いしました。
皆さん積極的にテストを書いてくれるようになりました!
テストを追加していく
準備が整ったので、まずはサービスの中でも主要機能を担っているModelやControllerのテストから順に追加していきます。
ここでのコツは、余計なことはやらずテストを書くことに集中することです。
テストを書いていると色々気になり始めてリファクタしたくなるんですが、それをやり始めてしまうといつまでも終わらなくなるので、テストとリファクタは分けてやったほうが良いと思います!
はじめはFactoryBotが揃っていないのでテストデータの準備にめちゃくちゃ時間がかかりました。 半分くらいの時間はこれにかかった気がします。 ですが後々のためにここはしっかりやっておく必要があります。
また、既存コードにテストを追加するのは思った以上に大変でした。
実装した背景や意図が読みきれないので、どうしてもコードに引っ張られてテストを通すためのテストを書いてしまいがちになります。
正常系のテストばかりになりがちですが、異常系のテストもしっかり書いていきましょう!
この時点のカバレッジ:38.82%
コード削除期(2020/1〜9)
主要機能のテストが一通り終わり、どれくらい上がっただろうと楽しみに確認するも、結果は10%程度でした。。あんなに頑張ったのに。。
このまま進めても目標達成は難しそうなので、別の方法を考えます。
前述したとおり今はもう使われていないコードがたくさん残っています。
これらのコードに対してテストを書いても後で消されるだけなのでムダが多くなってしまいます。
やはりなんとかコードを先に整理したい。
CoverbandというGemの導入
問題はどのコードが不要なのかがわからない。
また予想はついても確信が持てないので消せない。
この問題を解決するために調べていたところ、CoverbandというGemがありました。
これはテストのカバレッジのように、Production環境で実行されたコードとされていないコードを可視化できるGemです。
まさに我々が求めていたもの!
ということで早速導入し、2ヶ月程度待ちました。
2ヶ月経てば日常的に使われている機能は一通り実行されているはず。
このようにファイル一覧の結果が見れます。
またファイルごとも見れます。 (緑の行が実行、赤の行が未実行)
もちろん赤い行をそのまま削除していくのは危険です。(明日実行されるコードかもしれない)
なので、しっかり確認して問題ないことを確認した上で削除していきます。
ここまで絞れると確認するのもそんなに時間はかかりません。
ここでのコツは、あまり細かく見ないことです。 if文の中だけ赤いなどは一旦無視して、メソッド単位で見ていくと楽です。
最後にAutifyでテストも実行して確認します。
これでだいぶ安心できますね!
この結果、たくさんのファイルやコードを削除できました。
この時点のカバレッジ:45.70%
テスト追加、コード削除並行期(2020/10〜12)
コード整理が終わったので、テスト追加を再開しました。 ここからは地道にやっていきます。
まずCoverbandで必要なコードかをチェックした上で、
- 必要ならテスト追加
- 不要なら削除
で進めていきます。
残ったコードは普段から目にしていて仕様をある程度理解していることが多いため、テストを書くスピードも爆上がりしました!
2020年も残りわずか、ラストスパートをかけます。
50%を達成できたのか?
この記事が公開される12/19時点では50%には満たなかったのですが、残り1週間頑張ろうと思います!
あくまで安全でスピーディーに開発できる環境を作るのが目的なので数字にこだわりすぎる必要はありませんが、目標を決めて進めると頑張れます!
追記
クリスマスになんとか50%達成できました!
まとめ
- やみくもにテストを追加していくのはやめよう
- 必要なコードと不要なコードを可視化しよう
- コードを先に整理しよう
いかがでしたでしょうか?
泥臭い話であまり面白くはなかったかもしれませんが、同じような経験をしている方は多いのではないでしょうか?
この記事が少しでも参考になれば幸いです。
明日は古くからREADYFORのサービスを支えてくださっているバックエンドエンジニアのotaizoが担当します。お楽しみに〜!