スクリーンショット共有はもう終わり:UIレビューにプレビューデプロイが必要な理由
こんな状況を想像してみてほしい。開発者がチェックアウトページに変更を加え、自分のラップトップではすべてが完璧に見える。そこでスクリーンショットをチャットでプロダクトチームに送る。返ってきた反応は素早い。「Buy Now」ボタンが小さすぎるし、注文確認のテキストが表示されていない、と。
開発者が再度確認する。自分のマシンでは両方とも正しく表示されている。やりとりを重ねた結果、原因はデータの違いだと判明する。開発者のローカル環境にはショッピングカートに商品が入っているが、プロダクトチームが使ったダミーデータには特定の商品タイプが含まれていなかったのだ。一瞬で終わるはずのレビューが、スクリーンショットのやりとり、ミーティング、手動デバッグの無限ループに変わってしまう。
このシナリオは、毎日のように多くのチームで起きている。修正方法は思っているより簡単だ。
スクリーンショットベースのレビューの問題点
UIレビューをスクリーンショットや画面録画に頼ると、いくつかの問題が発生する。
- コンテキストが失われる。 スクリーンショットでは、ホバー状態、ローディングアニメーション、異なるデータでのページの振る舞いを確認できない。
- タイミングが遅れる。 フィードバックのたびに、誰かが新しいスクリーンショットを撮り、送信し、コメントを待ち、それを繰り返す必要がある。
- 環境の違いがバグを隠す。 開発者のマシンで動いていても、別の環境では壊れることがある。ブラウザ、画面サイズ、データ状態の違いによって、スクリーンショットでは決して捉えられない問題が露呈する。
- 非技術系のレビュー担当者がブロックされる。 プロダクトマネージャー、デザイナー、ステークホルダーは「ブランチをpullして実行する」ことができない。彼らは開発者が共有するものに完全に依存している。
核心的な問題は単純だ。コードをレビューすることと、動作するアプリケーションをレビューすることは同じではない。
プレビューデプロイが実際にやること
プレビューデプロイは、すべてのプルリクエストに対して一時的なライブ環境を作成することでこの問題を解決する。開発者がPRを開くと、CIパイプラインが自動的にフロントエンドをビルドし、一意のURLにデプロイする。そのURLを持つ誰もが、静的な画像を見るだけでなく、実際のアプリケーションを操作できる。
環境はプルリクエストが開いている間だけ存続する。PRがマージされるかクローズされると、パイプラインが自動的にすべてをクリーンアップする。手動での後片付けも、リソースを消費する忘れ去られた環境も不要だ。
実際の流れ
フローは単純だ。
以下の図は、コードプッシュからクリーンアップまでの完全なライフサイクルを示している。
- 開発者がコードをプッシュするか、プルリクエストを開く。
- CIパイプラインがフロントエンドのビルドをトリガーする。
- ビルド出力が一時的な場所にデプロイされる。
- パイプラインがプレビューURLをプルリクエストのコメントとして投稿する。
- レビュー担当者がリンクをクリックし、ライブアプリケーションを操作する。
- PRがマージまたはクローズされると、パイプラインが環境を破棄する。
静的フロントエンドの場合、これは軽量だ。ビルド出力は、PR番号に基づいた一意のパスを持つストレージバケットやCDNにアップロードされる。https://preview-1234.yourdomain.com や https://yourdomain.com/pr/1234 のようなURLがあれば十分だ。
サーバーサイドレンダリングアプリケーションの場合、一時的なサーバーインスタンスを実行する必要がある。これは、クラスター内のリソース制限付きコンテナでも、アクセス時にのみ起動するサーバーレス関数でも構わない。静的デプロイよりは重いが、すべてのブランチに恒久的なステージング環境を維持するよりはるかにコストが低い。
プレビューデプロイの恩恵を受ける人々
その価値は開発者だけにとどまらない。
- QAエンジニアは、見た目だけでなく実際の動作をテストできる。さまざまな入力を試し、エラー状態を確認し、開発者にシナリオの再現を依頼することなくエッジケースを検証できる。
- プロダクトマネージャーは、機能をコンテキストの中で確認できる。実装がデザイン意図と一致しているか評価し、UXの問題を早期に発見できる。
- デザイナーは、スクリーンショットでは平坦化されてしまうピクセルパーフェクトな実装やインタラクションの詳細を検証できる。
- ステークホルダーは、何が来るのかを早期に把握できる。技術的なセットアップや開発環境へのアクセスは必要ない。
実際のAPIとの統合テスト
プレビューデプロイは、フロントエンドとバックエンドの互換性というよくある問題も解決する。各プレビューには独自のURLがあるため、ステージングAPIや特定のAPIバージョンを指すように設定できる。チームは、他のコードを変更することなく、フロントエンドの変更がバックエンドと正しく動作するかをすぐに確認できる。
これにより、コードがメインブランチに到達する前に統合の問題をキャッチできる。間違ったペイロードを送信するボタン、異なるデータ形式を期待するフィールド、レスポンス構造を変更したエンドポイントなどが、マージ後ではなくレビュー中に明らかになる。
プレビューデプロイではないもの
期待値を設定することが重要だ。プレビュー環境は本番環境ではない。
- リソースは限られている。高可用性や24時間365日の監視は不要。
- データは代表的なものでよいが、本番規模である必要はない。
- パフォーマンスは本番には及ばないが、それで問題ない。
目的は機能検証であり、負荷テストではない。関心のあるUI状態(空の状態、エラー状態、特定のデータ組み合わせのエッジケース)をカバーする現実的なデータを使用する。データがより代表的であればあるほど、マージ前にキャッチできるバグが増える。
自動クリーンアップは必須
プレビューデプロイで最もよくある失敗は、クリーンアップを忘れることだ。環境が蓄積され、リソースが無駄になり、誰かが手動で古いデプロイを探し回らなければならなくなる。
初日からパイプラインにクリーンアップを組み込もう。プルリクエストがマージまたはクローズされたら、パイプラインがそのイベントを検出し、後片付け(ストレージバケットの削除、コンテナの停止、サーバーからのデプロイ削除)を実行するようにする。誰も覚えていなくてもいいように自動化する。
実践的なクイックチェックリスト
- すべてのプルリクエストに、一意でアクセス可能なURLが自動的に割り当てられる。
- URLはパイプラインによってPRのコメントとして投稿される。
- レビュー担当者は、VPN、特別なツール、ローカルセットアップなしでプレビューにアクセスできる。
- プレビューは、関連するすべてのUI状態をカバーするデータを使用する。
- PRがマージまたはクローズされたときに、クリーンアップが自動的に実行される。
- パイプラインは、監査とデバッグのためにプレビューURLをログに記録する。
本当の変化
プレビューデプロイは、チームがUIで協力する方法を変える。レビュー担当者は「スクリーンショットを送ってくれない?」と尋ねるのをやめ、「プレビューを確認したけど、こんなことがわかったよ」と言い始める。フィードバックループは数時間または数日から数分に短縮される。バグはメインブランチに到達する前に、到達した後ではなくキャッチされる。
次に、あなたのチームの誰かがUI変更を含むプルリクエストを開いたとき、自問してみてほしい。レビューが必要な全員がクリックできるライブURLを持っているだろうか?それとも、まだスクリーンショットを回し合っているのだろうか?