はじめに
先日小〜中規模のWebサービスを数年運用して学んだことをまとめていきます。と書いたので、まずはテストに関する話題を今回まとめようと思います。
この記事の全体像
最近はチーム全体でテスト書く習慣が完全に身についてるのですが、そこに至るまでの過程を振り返ると色々あったことに気づいたので以下まとめていきます。
なお、過去3年を振り返ってみて、以下の3つに分類できそうなので、この区分で以下整理して書いていきます。
- 初期
- 2016年5月〜
- 中期
- 2017年6月〜
- 最近
- 2018年10月頃から
初期
お仕事関わった当初、そのサービスのテストの充実度についていうと
- ちょっとだけrequestスペック書かれていた。
- 基本的にテストを書くという習慣がない
- CI環境も当然ながら無し
という感じでした。
また、この頃の初期の自分のテストに関するスキルについて言うと
- 別の案件でRails/RSpecという組み合わせで、request/controller/model specは一通り書いていた
- ただ、別の人が書いたものを見よう見まねで書いてるレベルだったので、ふんわりとした理解で書いていた。
という感じでした。
初期の問題踏まえて取り組んだこと
- 自分自身のテストに関するスキルが正直大したことがない状況だった
- ただその状態で、今後新しい機能の開発をしたり、不具合対応をするのが不安だった
- (きっかけは覚えてないのですが)この時期からPRのレビューをしっかりする習慣が出てきたことで、コードの改善について、当時の開発メンバー全員が割と意識を持つようになった
というようなことが重なり、現場の責任者の方に提案してちょっとづつ改善してきました。
具体的には
- GitHubにテスト改善的なラベルを作る
- そこで、当面の目的・目標を書く
- 既存仕様がよくわからない所が多いので、コードの現在の振る舞いを確認する 仕様化テスト を頑張って書く
ということをしていました。
初期の限界
仕様化テストでちょっとだけ安心を得たけど、それほど大きな改善につながってる感じがしてませんでした。
というのも
- その処理のControllerに色々な処理が入り混じってる
- テストを実行しづらい構造になってる
という状況だったので、この複雑な処理の全体像がざっくり見えてきても、根本的な所は何も解決しないので、その処理の見直しを考えるというIssueを作って、さらなる改善をしようと考えました。
ところが、そのタイミングで売上を伸ばすための企画よりの仕事をちょっと頼まれてそこからしばらくの間、改善系の作業に着手できなくなった 😥 ことで、そのままこの初期が終わったという感じです。
中期
企画よりの仕事が一区切りついた2017年の6月頃に新しい機能開発の話がでました。
この頃のGitHubのIssueを見てると
- 新規開発する処理はRailsEngineの仕組みを使って開発する前提だったので可能な限りcontroller/model specは書く
- なぜRailsEngineだったかは別に書きます
- CircleCI+NightwatchでUI自動化テストするプロトタイプ作る
- エンジニア経験が浅い人(しかも外国の方)がチームに加わったので、既存実装理解をしてもらいつつ、これまでカバーしてない処理のテストを書き溜める
という感じで作業を進めてました。
なぜCircleCI+NightwatchのUI自動化テスト?
初期(2016年5月〜)には、CIとかUI自動化テストという発想が全く持てない位に、各種リソース(人&時間)余裕がなかった気がします。
ただ中期の時は時間的な余裕が多少あったことに加え
- 個人的には、この仕事に関わる前に一時期クローラーを作る仕事をたくさんしていたので、Nightwatchみたいなものを使うのは得意だった
- 新しい機能開発で毎回手動テストは辛いのは明白だった
- UIを刷新する上に PC/スマホ x ユーザー属性 x 申込み方法 という組み合わで考えると20パターン以上あった。
ということを踏まえて、CircleCI+NightwatchのUI自動化テストを整備しました。
※ 完全な余談ですが、クローラーを作ることに比べると、自分たちでマークアップしたHTMLは当然ながらスクレイピングしやすい構造だったので作業しやすかった 👍
中期の限界
- 単純にテストコードの数は増えていったのですが、ビジネス的に重要な処理について、テストコードの充実度はまだまだ改善の余地がある
- CircleCI+NightwatchのUI自動化テストとかが出来たのは嬉しい反面、だんだん CircleCIの実行時間が長くなっていった
というような課題が出てきました。
最近
2018年10月頃から一定期間だったのですが、とても頼りになるエンジニアが2名チームに加わりました。
最近の成果その1
その人達が本来やるべき開発の合間に
- CircleCIの処理の見直し等
- FactoryGirl (Bot)のcreate/ build / build_stubbed を正しく使い分ける
- その他細々としたもの
という改善をやってくれたおかげで、現在は
- RSpecの方は600弱のテストケース(CircleCIの並列実行の仕組みを利用)
- UI自動化テストのほうは350個程度のテストケース
がCircleCIでそこまでストレスを感じない時間で実行されるようになりました 💪
最近の成果その2
こちらは、テストだけにとどまらない話なのですがapp配下のディレクトリ単位でREADME.mdを作って、それぞれの処理の大まかな設計方針を言語化しておくようにしました。
※ 外国の方がチームにちょっとづつ増えていく傾向にあるので、出来る限り英語化もしてる
設計方針を書いてる処理についてはすでにいくつかのパターンでテストも書かれてるため、
- Ruby/Railsにそこまで精通してない人に対して
- ある程度お手本となる実装サンプルがある
- 経験豊富な人
- 過去の経緯を説明しつつ、現状の設計方針でより良い方法があればそれを前提に設計考えなおして、実装&テストも改善しやすい
という効果が得られてます。
最後に
テストがほとんどなかった3年前の状況から今に至るまでを振り返ってみました。
振り返りついでに、もしも今の自分が3年前にアドバイスするとしたらおそらく以下のようなことを話すかなと思うので最後に触れておこうと思います。
- ほとんどテストコードが無い状況でCapybara使ってrequestスペック書くのは割と良かった。
- 当時、一番ヤバいなぁと思っていた所から着手していた。
- t-wadaさんの組織にテストを書く文化を根付かせる戦略と戦術(2019夏版)でちょうどそんなことが書いてある
- 当時は選択肢としてNightwatchで良かったけど、その後の情報はキャッチアップしたほうが良い
- ある程度、テストを書く&PRのレビューの習慣が身についてきたら、レビュー目的は言語化しておくのがベター