Slide 1

Slide 1 text

微妙な違いも⾒逃すな! ビジュアルリグレッションテスト! PHP Conference Japan 2020 2020.12.12 Yuta Ohashi

Slide 2

Slide 2 text

blue_goheimochi ⼤橋 佑太 株式会社オウケイウェイヴ PHP(Laravel), JavaScript(Vue.js/Nuxt.js), ランニング, サッカー, フットサル, 浜松まつり, ポケモンカードゲーム, さわやかのげんこつハンバーグ おおはし ゆうた

Slide 3

Slide 3 text

3 ⽬次 • ビジュアルリグレッションテストとは? • Atomic Designで考えるUIコンポーネント設計 • UIコンポーネントのカタログ化 • テストのためのツール • CI環境を含めたテストの全体像 • よかったこと&改善できそうなこと • やってみて感じた導⼊障壁 • まとめ

Slide 4

Slide 4 text

ビジュアルリグレッションテストとは?

Slide 5

Slide 5 text

5 ビジュアルリグレッションテストとは? • 「⾒た⽬」の変更を検出するためのテスト • 対象はページ全体やUIコンポーネント • 今回はUIコンポーネントの事例をお話しします • 変更前と変更後のスクリーンショットを⽐較して差分を確認する ことで、意図しない崩れを検知できる

Slide 6

Slide 6 text

6 ビジュアルリグレッションテストとは? どこが変わっているでしょうか? Before After

Slide 7

Slide 7 text

7 ビジュアルリグレッションテストとは? 微妙な違いも⾒逃さなかった! Before After リンクテキストの⾊変更 & アンダーライン追加

Slide 8

Slide 8 text

8 Before After ビジュアルリグレッションテストとは? 微妙な違いも⾒逃さなかった! リンクテキストの⾊変更 & アンダーライン追加

Slide 9

Slide 9 text

Atomic Designで考えるUIコンポーネント設計

Slide 10

Slide 10 text

10 Atomic Designで考えるUIコンポーネント設計 Atomic Designとは?

Slide 11

Slide 11 text

11 Atomic Designで考えるUIコンポーネント設計 Atomic Designとは?

Slide 12

Slide 12 text

12 Atomic Designで考えるUIコンポーネント設計 Atomic Designとは? • Bread Frostさんが考案した、デザインシステム • UIの構造を5段階で表しているのが特徴 • Atoms(原⼦) が集まってMolecule(分⼦) に、Moleculesが集まって Organism(有機体) に、Organismsが集まって‧‧‧‧Pageができる • Webページの要素を分解して、⼩さい部品の組み合わせ(UIコンポーネン ト)と考える • Vue.jsやReactなどのコンポーネントシステムとも相性が良い

Slide 13

Slide 13 text

UIコンポーネントのカタログ化

Slide 14

Slide 14 text

14 UIコンポーネントのカタログ化 Storybook

Slide 15

Slide 15 text

15 UIコンポーネントのカタログ化 Storybook • コンポーネントをカタログのような形で管理‧閲覧できように するためのツール • 定義ファイルを⽤意することで、コンポーネント1つ1つが Webブラウザから閲覧可能になる • Vue.js、React、Angularなど主要なフレームワークに対応

Slide 16

Slide 16 text

テストのためのツール

Slide 17

Slide 17 text

17 テストのためのツール • Storycap • reg-suit

Slide 18

Slide 18 text

18 テストのためのツール Storycap

Slide 19

Slide 19 text

19 テストのためのツール Storycap • Storybookをクロールしてスクリーンショットを撮ってくれる ツール • 指定したディレクトリに、取得結果を出⼒してくれる

Slide 20

Slide 20 text

20 テストのためのツール reg-suit

Slide 21

Slide 21 text

21 テストのためのツール reg-suit • 画像の⽐較をしてくれるツール • Storycapで取得したスクリーンショットを変更前‧変更後のもので⽐ 較する • 差分の結果をHTMLで⽣成してくれる

Slide 22

Slide 22 text

22 テストのためのツール Storycapでコンポーネントのスクリーンショットを取得 Before After

Slide 23

Slide 23 text

23 Before After テストのためのツール reg-suitでBeforeとAfterのスクリーンショットを⽐較 リンクテキストの⾊変更 & アンダーライン追加

Slide 24

Slide 24 text

CI環境を含めたテストの全体像

Slide 25

Slide 25 text

25 CI環境を含めたテストの全体像 AWS • CodeBuild (AWS CodeBuild) • Storybookのビルド、Storycapでのキャプチャ取得、reg-suitで⽐較、などなど⼀ 連の操作‧指⽰をする • S3 (Amazon Simple Storage Service) • ビルドしたStorybook、reg-suitでの⽐較結果を保存する • ECR (Amazon Elastic Container Service) • Storycapでスクリーンショットを取得するために、Chromiumをインストールした コンテナイメージを事前にpushする

Slide 26

Slide 26 text

26 CI環境を含めたテストの全体像 前提 • CI環境 • AWS • CodeBuild • S3 • ECR • リポジトリ • Github Enterprise

Slide 27

Slide 27 text

27 CI環境を含めたテストの全体像 1. プルリクエスト作成をトリガーにテストが開始される • CodeBuildを呼び出しテストを開始 2. Storybookをビルド 3. Storycapでスクリーンショットを取得 4. reg-suitで前の結果と今回の結果を⽐較する • 前の結果=プルリクエスト対象ブランチがマージされた際に作成されたスク リーンショット 5. テスト結果をプルリクエストにコメントする

Slide 28

Slide 28 text

28 CI環境を含めたテストの全体像 CodeBuild Github Enterprise 作業内容をGithub EnterpriseにPushする。 git push ECR S3 Storybook⽤Bucket Chromiumが⼊ったコンテナイメージ 前回のStorybookのスクリーンショット

Slide 29

Slide 29 text

29 CI環境を含めたテストの全体像 CodeBuild Github Enterprise プルリクエストを作成する。 pull request ECR S3 Storybook⽤Bucket Chromiumが⼊ったコンテナイメージ 前回のStorybookのスクリーンショット

Slide 30

Slide 30 text

30 CI環境を含めたテストの全体像 CodeBuild Github Enterprise Github EnterpriseからのWebhookを経由して、CodeBuildが実⾏される。 この際、buildspeck.ymlに記述されている内容を実⾏する。 Notify(Webhook) ECR S3 Storybook⽤Bucket Chromiumが⼊ったコンテナイメージ 前回のStorybookのスクリーンショット

Slide 31

Slide 31 text

31 CI環境を含めたテストの全体像 CodeBuild Github Enterprise ECRに登録してある、ビジュアルリグレッションテスト⽤のコンテナイメージ(Chromiumなどの必要ツー ルが⼊っている)をdocker pullする ECR S3 Storybook⽤Bucket Chromiumが⼊ったコンテナイメージ 前回のStorybookのスクリーンショット docker pull

Slide 32

Slide 32 text

32 CI環境を含めたテストの全体像 CodeBuild Github Enterprise Storybookをビルドする(npm run storybook-build)。コンテナはボリュームマウントして実⾏する形にし ているので、ビルド成果物はコンテナの外に出⼒される。 build Storybook ECR S3 Storybook⽤Bucket Chromiumが⼊ったコンテナイメージ 前回のStorybookのスクリーンショット

Slide 33

Slide 33 text

33 CI環境を含めたテストの全体像 CodeBuild Github Enterprise StorycapがChromiumを利⽤し、Storybook全体をクローリングしつつ各UIコンポーネントのスクリーン ショットを1つ1つ取得する。 Crawl Take screenshots ECR S3 Storybook⽤Bucket Chromiumが⼊ったコンテナイメージ 前回のStorybookのスクリーンショット

Slide 34

Slide 34 text

34 CI環境を含めたテストの全体像 CodeBuild Github Enterprise S3から⽐較対象となる前回のStorybookのスクリーンショットをダウンロードする。 Download prev screenshots ECR S3 Storybook⽤Bucket Chromiumが⼊ったコンテナイメージ 前回のStorybookのスクリーンショット

Slide 35

Slide 35 text

35 CI環境を含めたテストの全体像 CodeBuild Github Enterprise reg-suitで、今回のStorybookのスクリーンショットと前回のStorybookのスクリーンショットの差分を取 り、HTMLレポートを⽣成する。 ECR S3 Storybook⽤Bucket Chromiumが⼊ったコンテナイメージ 前回のStorybookのスクリーンショット run reg-suit

Slide 36

Slide 36 text

36 CI環境を含めたテストの全体像 CodeBuild Github Enterprise Storybook、スクリーンショット、reg-suitのHTMLレポートはアーティファクト(CodeBuildの成果物)とし て、S3にアップロードする。 ECR S3 Storybook⽤Bucket Chromiumが⼊ったコンテナイメージ 前回のStorybookのスクリーンショット 今回のStorybookのビルド成果物 今回のStorybookのスクリーンショット 今回のreg-suitのHTMLレポート Upload artifacts

Slide 37

Slide 37 text

37 CI環境を含めたテストの全体像 CodeBuild Github Enterprise 結果をプルリクエストにコメントする。 ECR S3 Storybook⽤Bucket Chromiumが⼊ったコンテナイメージ 前回のStorybookのスクリーンショット 今回のStorybookのビルド成果物 今回のStorybookのスクリーンショット 今回のreg-suitのHTMLレポート Comment to pull request

Slide 38

Slide 38 text

38 CI環境を含めたテストの全体像 1. プルリクエスト作成をトリガーにテストが開始される • CodeBuildを呼び出しテストを開始 2. Storybookをビルド 3. Storycapでスクリーンショットを取得 4. reg-suitで前の結果と今回の結果を⽐較する • 前の結果=プルリクエスト対象ブランチがマージされた際に作成されたスク リーンショット 5. テスト結果をプルリクエストにコメントする

Slide 39

Slide 39 text

39 CI環境を含めたテストの全体像 テストが完了するとこんなコメントがプルリクエストにつきます

Slide 40

Slide 40 text

40 CI環境を含めたテストの全体像 テストが完了するとこんなコメントがプルリクエストにつきます S3にアップロードされた StorybookのURL

Slide 41

Slide 41 text

41 CI環境を含めたテストの全体像 テストが完了するとこんなコメントがプルリクエストにつきます S3にアップロードされた StorybookのURL S3にアップロードされた reg-suitのレポートのURL

Slide 42

Slide 42 text

42 CI環境を含めたテストの全体像 テストが完了するとこんなコメントがプルリクエストにつきます 変更されたコンポーネント 追加されたコンポーネント 削除されたコンポーネント 変更がなかったコンポーネント が分かる! S3にアップロードされた StorybookのURL S3にアップロードされた reg-suitのレポートのURL

Slide 43

Slide 43 text

よかったこと&改善できそうなこと

Slide 44

Slide 44 text

44 よかったこと&改善できそうなこと よかったこと • レビューがとてもしやすくなった • CSSのリファクタリングがしやすくなった • 意図しない崩れが起きづらくなった

Slide 45

Slide 45 text

45 よかったこと&改善できそうなこと よかったこと 変更されたコンポーネント 追加されたコンポーネント 削除されたコンポーネント 変更がなかったコンポーネント が分かる! S3にアップロードされた StorybookのURL S3にアップロードされた reg-suitのレポートのURL

Slide 46

Slide 46 text

46 よかったこと&改善できそうなこと よかったこと • レビューがとてもしやすくなった • 対象プルリクエストの修正でコンポーネントを壊していないか?が確 認できる(⼿元でStorybookを⽴ち上げて確認しなくてもよい) • レビューする側としてもとても安⼼感がある • 追加‧変更‧削除されたコンポーネントがそれぞれわかるので、コー ドレビューの補助にもなっている

Slide 47

Slide 47 text

47 よかったこと&改善できそうなこと よかったこと • CSSのリファクタリングがしやすくなった • デザイナーから上がってきた声 • ビジュアルリグレッションテストで差分がでなければ正しくリファク タリングができたというのが分かる • ⼤胆に修正することができた • ⽬視での確認を減らすことができた

Slide 48

Slide 48 text

48 よかったこと&改善できそうなこと よかったこと • 意図しない崩れが起きづらくなった • 「ビジュアルリグレッションテスト」と話してきたが実はあまりデグレが発⽣して いない • 全体にかかるようなCSSを修正した場合(line-heightを⼀括で変えるなど)にたまにあるくらい • コンポーネント単位で作成するようになったことにより、変更がコンポーネントの 中で閉じるようになったためだと考えている • コンポーネントを組み合わせてページを構成した際に、marginの設定もれなどで 要素がくっついてしまうというようなことはあるので、ページ全体に対してのテス トもうまくできるように考えていきたい

Slide 49

Slide 49 text

49 よかったこと&改善できそうなこと 改善できそうなこと • 不安定なコンポーネントを減らす • テストの実⾏時間を短くする • UIコンポーネント設計が難しい

Slide 50

Slide 50 text

50 よかったこと&改善できそうなこと 改善できそうなこと • 不安定なコンポーネントを減らす • ⾮同期読み込みがあるようなコンポーネントはStorycapのスクリーン ショット取得のタイミングによって変更してないのに差分が出てきて しまうことがある • ⽇付に依存しているコンポーネント

Slide 51

Slide 51 text

51 よかったこと&改善できそうなこと 改善できそうなこと • テストの実⾏時間を短くする • 1回のテストに10分前後かかってしまっている • Dockerコンテナ経由でのビルドをしないようにする • テストの並列実⾏ • 開発フローの⾒直し

Slide 52

Slide 52 text

52 よかったこと&改善できそうなこと 改善できそうなこと • UIコンポーネント設計が難しい • 基本的にはAtomic Designに則ってコンポーネント設計をしている • 最⼩単位のAtomは分かりやすい • これはMolecule?これはOrganism?と複数のコンポーネントを組み合わせ たものをどこに配置するかよく相談している • 5つの段階だと少ない‧‧‧ • 試験的にOrganismのコンポーネントをページ別に分けて運⽤してみたりしている がまだまだ改善の余地がありそう

Slide 53

Slide 53 text

やってみて感じた導⼊障壁

Slide 54

Slide 54 text

54 やってみて感じた導⼊障壁 • フロントエンド‧バックエンドの開発の分離 • デザイナーとの共創

Slide 55

Slide 55 text

55 やってみて感じた導⼊障壁 フロントエンド‧バックエンド開発の分離 • 組織が分かれている必要はないかもしれないが、コード上でフロントエ ンドとバックエンドが分かれている必要はありそう • 既存のプロダクトにシュッといれられるかというとつらそう‧‧‧ • 今回の事例では、アプリケーションのリプレイスを進めているプロダク トだったということは導⼊障壁をかなり下げていると思われる • フロントエンドはNuxt.js、バックエンドはLaravelという技術選定から⾏えた • この辺りの開発体制を調整するのにすごく⼒を割いた

Slide 56

Slide 56 text

56 やってみて感じた導⼊障壁 デザイナーとの共創 • フロントエンドチームができることにより、デザイナーとより 協⼒(1つのチームとして機能すること)が必要 • Atomic Designなどの知識共有、⽂化の共有 • 同じリポジトリを利⽤しての開発 • 開発側としてもよりUIやデザインといった領域を知る必要がある • サンプルリポジトリを作ったり、トレーニング、情報共有などを⾏った

Slide 57

Slide 57 text

まとめ

Slide 58

Slide 58 text

58 まとめ • ビジュアルリグレッションテストは「⾒た⽬」をテストする • 今回はUIコンポーネントのテストを紹介 • Atomic Designを取り⼊れUIコンポーネント設計を⾏い、StorybookでUI コンポーネントカタログを作成 • Storycap、reg-suit、CodeBuild、S3、ECRを使ってテスト環境を構築 • レビューがとてもしやすくなった! • 意図しない変更を検知しプルリクエスト上で確認できる • 意図した変更(追加‧変更‧削除)も分かるのでコードレビューの補助となる • ただし、導⼊障壁はやや⾼いと感じている

Slide 59

Slide 59 text

微妙な違いも⾒逃さなかった! ビジュアルリグレッションテスト!