AIのおかげで「割に合わなかったこと」が実行できるようになった—Bootstrap移行のビジュアルリグレッションテスト環境を構築した話
はじめに
メディフォンでフロントエンドエンジニアをしている岩渕です。クラウド型健康管理システム「mediment」の開発に携わっています。
今回、Bootstrap 4から5への移行にあたって、ビジュアルリグレッションテストの環境を構築しました。Claude Codeを使い、他の業務と並行しながらでもかなり短い期間で環境構築し、担当者に渡せる状態にできました。
この記事は「AIすごい」という話ではありません。前からやりたかったけど割に合わなくてやれなかったことが、AIのおかげでやれるようになった、という話です。
目次
はじめに
Bootstrapのメジャーバージョンアップ。確認どうする?
ビジュアルリグレッションテストで楽になるのは前からわかっていた
AIに相談しながら構築したら、作業自体は半日で終わった
ステップ1:壁打ちで方針を固める
ステップ2:方針が決まったら実装に入る
Storybook VRTの追加
カバーできていない部分もある
やれるからこそ、何をやるかの判断が重要になる
おわりに
Bootstrapのメジャーバージョンアップ。確認どうする?
medimentのUIはBootstrap 4ベースで構築されていますが、Bootstrap 4は5にメジャーバージョンアップされています。Bootstrap 4は既にEOL(サポート終了)を迎えており、jQuery依存の脱却やユーティリティAPIの刷新など内部の設計思想が大きく変わっているアップデートで、対応の優先度を上げて取り組むことにしました。
テスト環境にて手元でアップデートしてみたところ、画面のあちこちが崩れます。クラス名の変更(ml-* → ms-*など)、廃止されたコンポーネント、data属性の変更。差分は広範囲にわたります。
問題は確認作業です。medimentは数百画面規模のSaaSで、ロールごとに異なる画面があります。これを目視で全部確認するのは現実的ではありません。
画像1(実際に崩れた画面)
テストについては、共通コンポーネントの単体テストを少しずつ整備し始めている段階で、今後も拡充していく方針です。ただ、見た目の崩れを検出できるビジュアルリグレッションテストまでは手が回っていませんでした。
自分は移行作業の担当ではありませんが、担当のエンジニアが全画面を目視確認することになるのが目に見えていました。崩れた画面を機械的に検出できる仕組みがあれば、だいぶ楽になるはずです。
ビジュアルリグレッションテストで楽になるのは前からわかっていた
ビジュアルリグレッションテストという仕組み自体は以前から知っていました。変更前と変更後のスクリーンショットを比較して、差分のある画面を自動で検出する。PlaywrightにはそのためのAPIが組み込まれていることも把握していました。
ただ、この仕組みをゼロから整備するとなると、それなりの工数がかかります。
ツールの選定と比較。対象ページのURL洗い出し。ログイン処理の実装。テストデータの準備。ページネーションや個別ページの重複排除。動的コンテンツのマスク処理。まともにやろうとすると、調査と実装で数日から1週間以上はかかります。
Bootstrap移行の確認のためだけにそこまでやるかというと、正直割に合わない。結局「手動で確認した方が早い」という判断になりがちです。
これまでもそうやって見送ってきたテーマでした。
AIに相談しながら構築したら、作業自体は半日で終わった
今回は、AIに相談しながら進めることにしました。使ったのはClaude Codeです。
自分の中にはアイデアと最低限の知識はありました。「PlaywrightのVRT機能を使えばいけるだろう」という方向性は見えていた。ただ、ツールの比較や設計の詳細を一人で全部調べて詰める時間はない。そこをAIとの壁打ちで補いました。
進め方として意識したのは、いきなり「作って」と丸投げしないことです。まずAIと壁打ちしながら方針を固めて、使うツールや設計の方向性がはっきりしてから実装に入る。この2ステップを踏むことで、途中で迷走せずに済みました。
ステップ1:壁打ちで方針を固める
最初にチャットで「VRT的な仕組みで崩れを検出できないか」と相談しました。自分の中にPlaywrightという選択肢はありましたが、他にもっと良い方法がないか確認しておきたかった。
BackstopJS、Playwright、Chromatic、reg-suitなど複数のツールが比較つきで返ってきました。そこに「E2EでCypressを使っている」「Playwrightの環境もセットアップ済み」と伝えたところ、「Playwrightでやるのがおすすめ。BackstopJSをわざわざ入れる必要はない」と明確に絞られました。
さらに「CIで回す予定はない」「テストは書かずにスクショの比較だけしたい」「URL一覧も自動で欲しい」と要望を伝えると、提案がどんどん変わっていきました。テスト設計ではなくスクショ撮影&比較のスクリプトに。URLはクローラーで自動収集する方式に。制約を正直に伝えるほど、現実に即した提案になっていきました。
設計が形になってきた段階で、運用上の問題点もぶつけました。「before/afterを同時に起動できない」「ページネーションの先は見る必要がない」「個人ページも1つで十分」。AIは現場の運用事情を知らないので、こういうフィードバックを伝えないと、使えるものにはなりません。
ステップ2:方針が決まったら実装に入る
方針が固まった後は、実装フェーズに移りました。
特に効果が大きかったのはURL洗い出しです。「VRTのURLに漏れがないか確認して」と頼んだところ、プロダクトのコードベースを自分で読みに行き、DjangoのURLconfやVue Routerのルート定義を解析して対象ページを洗い出しました。APIエンドポイントや重複の除外、テストデータが必要なページの特定まで行い、さらにMySQLに接続してテストデータのIDまで自動で取得しました。最終的にVRTの対象として380ページを整理できました。
自分がやったのは「プロダクトコードの場所」「DBのパスワード」「データがないURLはスキップで」と情報と判断を渡すことだけです。なお、Claude Codeがアクセスしたのはローカルの開発環境で、データもすべてダミーデータです。
Storybook VRTの追加
Playwright VRTで画面単位のスクショ比較ができた後、共通コンポーネント単位の確認にはStorybook VRTも構築しました。共通コンポーネントはStorybookに登録済みだったので、storycap + reg-cliでスクショを撮ってBS4/BS5の差分を比較する仕組みを入れました。Storybook公式のVisual TestはChromatic(SaaS)に依存していて無料枠に制限があることもわかり、ローカル完結のツール構成を選びました。
既存のStorybook設定ファイルを渡したところ、CSSテーマが2種類あることも把握した上でそれぞれのテーマでスクショを撮る手順まで出してきて、スムーズに進みました。
最終的に、Playwright VRTで380ページ、Storybook VRTで共通コンポーネントをカバーする環境が立ち上がりました。動作確認などの手間はありましたが、普通にゼロから整備することを考えるとかなり短い時間で形にできたと思います。
画像2(VRTの差分レポート画面)
カバーできていない部分もある
正直に言うと、今回構築した環境は万能ではありません。
URLベースでページを開いてスクリーンショットを撮る仕組みなので、モーダルの中身、タブやアコーディオンを切り替えた後の表示、特定のデータがないと表示されない画面などはカバーできていません。
それでも、大半のページの崩れを機械的に検出できるだけで、担当者の手動確認の負担は大きく減ります。差分レポートを開けばBefore/After/Diffが一覧で見えるので、どこから修正すればいいかの優先順位もつけやすい。
ここで完璧を目指すと、結局「そこまでやる工数が割に合わない」という元の問題に戻ってしまいます。まず実用的な範囲でカバーして、必要に応じて拡充していく方が現実的です。
構築した環境は移行担当のエンジニアに渡し、「助かる」と言ってもらえました。その後、担当者がこの環境を使いながら修正を進め、Bootstrap 5への移行は無事に完了しています。移行作業自体もClaude Codeを活用して進めてもらいました。
移行を担当したエンジニアに感想を聞いてみました。
担当者のコメント
目や手だけでは追いにくい差分の一括大量検出を担保してもらい大変助かりました。このツール無しでは今回の移行はここまでスムーズではなかったと思います。
ちなみに、今回作ったビジュアルリグレッションテスト環境はCIに組み込んで毎回回すような定常運用は考えていません。ライブラリやフレームワークのアップデートなど、広範囲に見た目が変わる可能性があるタイミングで都度活用できればいいなと思っています。
やれるからこそ、何をやるかの判断が重要になる
今回の経験で一番感じたのは、AIによって実行コストが下がると「やれること」が一気に増える、ということです。
ビジュアルリグレッションテスト環境の構築は、以前なら「やりたいけどやれない」リストに入る類の作業でした。工数を考えると手動確認の方が早い場合も多い、でもAIに相談しながらなら半日でできるとなると判断基準が変わります。
ただ、やれることが増えた分、何をやるかの判断がより重要になります。
今回やったのは「移行担当のエンジニアの確認作業が大変になる」という具体的な課題があったからです。課題が明確で、解決手段のイメージもある程度ありました。AIはそのイメージを具体化して実行するコストを大幅に下げてくれました。
逆に言えば、課題が曖昧なまま「AIで何かできないか」と考えても、たぶんうまくいきません。自分の中にアイデアや最低限の知識があって、何をやりたいかが見えている状態でAIを活用するからこそ、会話がかみ合って実用的なものが出来上がる。
AIに何をやらせるか。どこまでやるか。どの課題を今解決すべきか。その判断はエンジニアの仕事です。AIが実行コストを下げてくれた分、その判断の重要性は増していると思います。
おわりに
Bootstrap移行は無事に完了しました。
この記事で伝えたかったのは「AIで効率化できました」ということよりも、「前からやりたかったけど割に合わなくてやれなかったことが、AIのおかげでやれるようになった」ということです。そしてやれるようになったからこそ、何をやるかを判断する力がより大事になった、ということです。
同じような「やりたいけどやれない」リストを抱えているエンジニアの方に、少しでも参考になれば幸いです。