Findy Engineer Lab

エンジニアの"ちょい先"を考えるメディア

開発生産性を支えるテスト自動化とその効果的な浸透

2023年9月、ファインディ株式会社は「フロントエンドの開発生産性」と題したオンラインカンファレンスを開催。第一線で活躍しているエンジニアを招いて、フロントエンド領域における開発生産性を向上させる組織づくりや戦略について語っていただきました。

本稿では、株式会社リンクアンドモチベーションにてフロントエンドエンジニアを務めている中上 裕基さんのセッション「開発生産性を支えるテスト自動化とその効果的な浸透」の内容をご紹介します。

2022年より同社で働く中上さんは、入社後にフロントエンドのテストが自動化されていないことに気が付きました。「このままでは、いずれテストが追いつかなくなってしまう」と危機感を持った同氏は、テスト自動化を推進することを決意。いくつかの取り組みを経て、現在は高いカバレッジ率を誇るまでにテストコードが普及したそうです。当初は、テストコードを書いたことがないメンバーもいたという同社で、どのようにしてテスト自動化を浸透させていったのでしょうか?

■プロフィール
中上 裕基(なかがみ ゆうき)/@nakagam3
株式会社リンクアンドモチベーション
MCユニット 新規開拓グループ/リード・フロントエンドエンジニア

2015年にフロントエンドエンジニアとしてキャリアをスタート。 その後アジャイル開発に出会い「どうすればチームが気持ちよくいいモノを届けられるか」に興味を持つようになった。 その探究のためアーキテクチャやQA、開発プロセスの設計と幅広く取り組んできた。 リンクアンドモチベーションに入社後はプロダクト開発に従事しつつ、 フロントエンドとQAを中心に生産性・開発者体験の向上に取り組んでいる。

開発生産性向上のために着目したのは「テスト自動化」

中上:リンクアンドモチベーションは、組織・人事のコンサルティング会社です。創業以来、2,000社以上の企業様をご支援してきました。現在は「モチベーションクラウド(組織改善のための従業員エンゲージメント向上サービス)」「コミュニケーションクラウド(社内コミュニケーションを活性化するサービス)」「ストレッチクラウド(管理職育成サービス)」といった三つのSaaSプロダクトを提供しています。AI組織改善アドバイザーやAI成長支援アドバイザーといった、ジェネレーティブAIを内包した機能の開発に注力しているのも特徴です。ちなみに、私は主要プロダクトとなる「モチベーションクラウド」のフロントエンド開発を担当しています。

弊社の開発組織は、2018年に内製化に着手しました。そこから組織を形成しつつ、開発生産性の向上に取り組み、今ではFour Keys メトリクスのHigh~Elite レベルに到達しています。

私が入社したのは2022年で、入社前は「開発生産性の向上に頑張って取り組んでいるいい会社だ」という印象がありました。しかし、実際に入社してみると、リードタイムやデプロイ頻度は高まっているものの、フロントエンドのテストに関わる改善は未着手の状態でした。「リリース時にAutifyでE2Eテストをする」「最後にまとめて手動で全体QAをする」といった形だったのです。

これでは、いつかリードタイムにテストが追いつかなくなってしまいます。しかし、自動テストにしたくてもアプリ開発者は忙しい。「開発生産性に取り組みましょう」と呼びかけるだけでは、何か施策を打ったとしても形骸化してしまう可能性があるでしょう。

どうすれば、みんながテストを書いて開発生産性の向上に取り組めるようになるのか。本日は私たちが行った、テスト自動化を浸透させるための取り組みについてお話しします。

最初に取り組んだのは、テストアーキテクチャでの思考整理

中上:まずは「理想の姿を描こう!」です。自動テストと一言でいっても、色々なものがありますよね。自動テストツールも複数ありますし、最終的にどういった形にするのが一番いいのか、当時は私自身が説明できない状態でした。そのため、まずはそれを整理しようと思いました。

整理するために調べて出てきたのが、「テストアーキテクチャ」という考え方です。明確な定義はないようですが、本日は「プロダクト全体の品質を評価するテストをどのように実現するか、という基本的な構造を表現したもの」と定義してお話しします。

文字だけではわかりにくいと思うので、実際に私が作成したテストアーキテクチャをご覧ください。

図の一番左にあるのが、Testing Trophyです。フロントエンドのテストはインテグレーション層を厚くしたいと考えていて、そのバランスを表したものです。この図は、Testing Trophyを基本として、各層の中でどういうことをやっていくのか、という点をまとめたものです。

E2EはAutifyでも一部自動化されていますが、シナリオテストやスモークテストについては、リスキーなもののみテストをしています。そのほか、性能試験と、脆弱性試験もありますが、バックエンドはRSpecでテストが書かれていたので、こちらはある程度サポートされている状態でした。図の左側のフロントエンドについては、理想とするものを書いています。

フロントエンドの中を一つずつ説明すると、一つ目が静的解析ですね。TypeScriptやESLintなどが代表的だと思います。基本的に低コストでスピードが早く、TypeScriptは型チェックをしてくれて、ESLintだとコーディング規約のチェックができるといったイメージです。担保したいのは、可読性や保守性になるかと思います。

その上のユニットテストについては、人によって定義が異なると思うのですが、私たちの中では「開発者が、自分の意図した実装ができていることを確認するための最小単位のテスト」と定義しています。そのため比較的、開発者目線の観点になると考えています。例えば、境界値分析のテストであったり、条件分岐網羅をしたり、そのほか例外処理ができているのかなど、自分が意図したコードが書かれているかをテストしています。ここまでが、開発者が自信を持って「自分が意図したものができている」と言うためのテストです。

上の二つがインテグレーションテストで、それをさらに分けて、コンポーネント結合テストというのをつくりました。 ユニットテストで担保されたもの、パーツであったりコンポーネントが連動してシステムを提供する形になっていて、その連動しているシステムがユーザーに提供する振る舞いを保障するためのテストです。 つまり、ユーザー目線のテストですね。例えば、入力したキーワードで検索できるか、検査結果がない場合は「空です」とわかるようにする、といったイメージです。使い道としては、リファクタリングをして内部の構造を変えても、ここのテストが通っていれば基本的には大丈夫だと判断できるテストにしたいと思っています。ユニットテストは、内部の構造が変わると構造の一つひとつにテストが書かれている形になるため、壊れやすかったり、もしくは書き捨てたりすることになります。そのため、コンポーネント結合テストが、システムの振る舞いを保障する形にしたいと思いました。

一番上のブラウザ結合テストについては、技術的なレイヤーで切っています。私たちが提供しているSaaSはWebアプリケーションで、必ずブラウザを通して提供することになるため、ブラウザ固有のネイティブなAPI(ファイルAPIやクロスブラウザなど)の観点でテストしなくてはいけません。そうすると、使うツールが変わるので、ブラウザ結合テストとコンポーネント結合テストを分けているのです。

これらを全て実施できたら、テストに関する問題は解決されると思いました。しかし「これでお願いします」と依頼したとしても、アプリ開発者は対応しきれないだろうなとも思いました。そこで、テストアーキテクチャをもとに次の施策を考えました。

メンバーの意欲を高めるコツは「Can」と「Will」

中上:リンクアンドモチベーションでは、下図のようなフレームワークをモチベーションの公式としています。

Must(やるべきこと)は、会社から個人に与えられたミッションです。Can(やれること)は、ミッションを達成する能力が備わっている、もしくは「自分ならできる」と思えること。Will(やりたいこと)はキャリアや夢であったり、誰かのために行動したいと思えることです。これらの三つが重なっている部分はモチベーションが高い部分と定義しています。この三つの輪の重なりを広げていくことで、主体的かつモチベーティブに働くことができ、成果創出につながると考えています。

このフレームワークをテスト自動化の導入に当てはめてみると、ユーザーのためにも品質は大事なことですし、Mustの観点ともマッチしています。しかし、Can/Willの観点では、あまり当てはまる要素がないなと思いました。テストコードを書いたことがない人はテストをするイメージが湧かないでしょうし、「現状で品質は悪くないのだから、テストの必要はない」という意見もあると思います。

そこでまずは、Can/Willの要素を感じられるテストから実施するアイデアを思いつきました。要は、開発者にとってメリットを感じやすく、コストが少ないものから手をつけていこうとしたのです。

テストアーキテクチャの各項目について、それぞれ分析して、メリット・デメリットを出したのが上図です。これらを見て、一番最初に着手するのはユニットテストがいいのではないかと思いました。ユニットテストはテストサイズが小さくてフィードバックが速いため、実装を間違えていてもすぐに気が付くことができます。それにより、テストのメリットを感じてもらいやすいのではないかと考えたのです。

なお、全てにテストコードを書くと作業コストがかかりますが、Testing Trophyではユニットテスト全てではなくポイントで書くという形になっているので、範囲を絞ればコストの面も問題ないと判断しました。対象としたのは、リポジトリと共通コンポーネントの部分ですね。前者は通信周りでケアレスミスが発生していたからで、後者はさまざまなところで使用されているためレバレッジが効くと思ったからです。

テストツールには、下図のものを採用しました。

これらをセットアップをして、準備ができテストを書けるようになった後にも、Can/Willを育んでもらうために二つの取り組みを行いました。

一つ目が、みんなのCanをつくるライブコーディングです。テストをしたことがないメンバーに、完成したテストコードを見せたとしても、あまりイメージができないでしょう。そこで、テストコードが書かれている過程まで全部見せられると良いのではないかと考えたのです。具体的には、一人の代表者に一つのリポジトリを対象に真っ白な状態からテストを書いてもらい「どのように書くのか」「どのような観点でテストをするのか」といったことをその場で解説しながら実際にコーディングしてもらいました。ライブコーディングに参加したメンバーからは「実際にテストコードを書くイメージを掴めた」というコメントをもらっており、この取り組みは成功だったと思っています。

二つ目は、一人ひとりのCanを育んでいくためのペアプロです。一度ライブコーディングを見たからといって、すぐにテストコードを書けるわけではありません。メンバーの精神的サポートという意味合いも込めて、実業務でテストコードが書けるまでは、ペアプロでフォローする体制にしています。バーチャルオフィスサービスのGatherに「ペアプロの森」というのも用意していて、困ったらすぐに相談できる場所を作っているのもポイントです。

ペアプロについては、CanだけではなくWillにもつながったと思っています。実業務でテストコードを書いていると、ちょっとしたケアレスミスが起こってしまうのですが、ペアプロをするようになってからは、ミスにすぐ気が付くことができるようになったのです。それにより、普段であれば結合テストをするまでは気が付かなかったようなミスの見落としがなくなり、自動テストのメリットを実感してもらえました。

そして、これらの取り組みを通してテストコードを普及させることができたのです。

CIでカバレッジなどを縛っているわけではなかったのですが、ほとんどのファイルにテストを書いてくれましたし、適切なカバレッジになったと思います。カバレッジを目標にするのではなく、テストができている安心感を重視して、CanとWillを優先したことで最終的にはMustにつなげることができたのだと思います。

新たな仲間とともに理想の環境を目指して活動中

中上:最後にご紹介するのが「仲間を見つけて活動を広げよう!」というお話です。

ユニットテストにフォーカスした結果、テストを書くことを定着させられました。しかし、本当は実現したいことがまだまだあります。そういった状況の中で、Can/Willを育む取り組みを通してテストのメリットを実感したメンバーから「もっとテストを拡充したい」という意見をもらいました。テストを浸透させるためには、一緒に取り組みを推進してくれる仲間が必要だと思ったので、「じゃあ一緒にやろう」と声をかけていきました。

少しずつ仲間が増えていくことで、ユニットテストだけではなく、インテグレーションテスト(コンポーネント結合テスト/ブラウザ結合テスト)に挑戦できる土台が整いました。現在の状況としては、インテグレーションテストを導入しようとしているところです。

ツールのセットについては、上図のような形で導入しようかなと考えています。ちなみに、このツール選定についてもCan/Willが絡んでいます。インテグレーションテストの課題は、実行速度と難易度です。

ブラウザを使うとどうしてもテストの実行速度が遅くなってしまうため、開発者体験が悪くなってしまいます。また、テストが失敗したときに、デバッグが大変になると「テストって本当に必要?」「すぐコケるからテスト追加するのやだな」のようにWill/Canを失ってしまう懸念がありました。しかし、Storybookならtest runnerでブラウザを使わずにテストができますし、スピード面も問題ありません。実際に画面で動いてるのを確認しながらテストを作ることができるのもポイントですね。失敗したとしても、Storybookで実際の動作を確認しながら、何度もデバッグできるので、テストコードに慣れていない人でも扱いやすいだろうと思いました。

今後は、テストアーキテクチャの描いた理想の姿を実現することを目指して、取り組みを進めていきたいと考えています。

メンバーに寄り添うことを忘れず、まずは動き出してみよう!

中上:新しい取り組みを進めてもらうには、理想像を伝えた上で、実現に向けてCanが生まれるようにフォローをすること、Willを実感してもらうことが重要です。CanとWillが育まれると、メンバー自身が自然と次の取り組みにも前向きになってくれるという実感を得ることができました。

テストを導入したいと考えている方に向けてメッセージを送るとすると、まずはCanとWillを考えて行動してみてください。私たちの取り組みの中で、一番効果があったのはWillを実感してもらえたことだったと思います。CanとWillにフォーカスすれば、仲間が少しずつ増えていって、活動が広がっていくのではないでしょうか。