開発プロセス内でPlaywrightを活用して自動化を進めている話

# はじめに
こんにちは！atama plusでQAをやっている池上です。
[atama plus Advent Calendar 2023](https://qiita.com/advent-calendar/2023/atamaplus) 21日目です。
ここでは最近ホットなE2E自動テストツールを組み込んだ開発プロセス、組み込み後の成果などを紹介できればと思います。
QAでE2E自動テストを開発プロセスに組み込みたいと考えている方や、Playwrightを導入してみたいといった方の参考になれば幸いです！
本記事では以下の構成でご紹介していきます！
* atama plusのテストの歴史とPlaywright導入検討
* Playwright自動化を組み込んだ開発プロセス
* 自動化の方針と実装方法
* チャレンジ中のこと
* 最後に

# atama plusにおけるテストの歴史とPlaywright導入検討
### atama plusにおけるテストの歴史
まず、atama plusにおけるテストプロセスの歴史と自動化の背景を簡単に紹介します。
atama plusの開発では、複数チームが同一のプロダクトに対して改修を行い、リリース前に各チームのプログラムを統合した状態で「リリーステスト」を行っています。

組織拡大に伴いプロダクトへの機能追加も加速したことで、リリーステストのケースも増加し、テスト消化にかかる時間もどんどん増加していきました。
この頃はすべてのテストケースを手動で実施していました。
テスト消化の時間増加に対する打ち手の一つとして、リリーステストの効率化を目的に、2020年から自動テストを取り入れ始めました。

### Playwright導入検討
自動テストを取り入れ始めた2020年当初はWeb上で自動テストをサポートしてくれるプラットフォームを導入していました。
しかし、その自動テストツールではShadow DOMに対応していないことから、自動化の範囲が限定的でなかなか自動化の範囲が増えないという課題がありました。
そこで、プロダクト全体をカバーできるような自動テストツールについて、以下のような観点で導入検討を進めました。（記載した観点は一部の代表的なものとなります。）
* プロダクトとの相性
* 実装の容易さ
* 環境準備の容易さ
* 対象ブラウザの豊富さ
* 公式ドキュメントの豊富さ
* 実行速度
* 初期/ランニングコスト

複数の自動テストツールについて、実際に弊社プロダクトに対してテストコードを実装するなど検証を行った結果、Playwrightを採用することになりました。

# Playwright自動化を組み込んだ開発プロセス
本章では弊社で実際に行っているPlaywrightを組み込んだ開発プロセスについて紹介します。
QA組織としては、自動化を進めることで以下のような状態を目指していました。

目指す状態：
テスト自動化に必要なコストを払い手動でのテストのコストを削減することで、
QAは機能が当たり前に動くだけでなく、探索的テストやより良い価値提供に向けた活動に注力できるようになる。

上記の状態を目指すために、開発プロセス内にテスト自動化を組み込むことで実現していくこととなりました。
開発プロセスに組み込むにあたり、QA向けにPlaywrightについてのオンボーディングを行ったり、開発に関わる各職種のみなさまとの調整を行ったりしました。総じていい反応をいただき、QAが自動テストを推進していくことを快く受け入れていただきました。

ここからは開発プロセスについて記載していきます。
まず、弊社内での開発は以下のように進んでいくことが多いです。
1. 仕様詰め 
2. 見積もり(リファインメント)
3. プランニング
4. プログラム実装・フィーチャーテスト設計
5. フィーチャーテスト実施
6. リリーステスト
7. 本番リリース

これに対して開発プロセスの各フェーズに、以下のように自動化についての内容を組み込みました。
* 見積もり(リファインメント)
(チーム全体)自動化するかどうかを話し、見積もりに含める。
* プランニング
(チーム全体)DoD(完了の定義)を確認し、自動化するかどうかを確認する。
* プログラム実装・フィーチャーテスト設計
(QA)フィーチャーテストテスト設計の中で、手動テストで実施する部分、自動テストで実施する部分、新規に自動化する部分などを含めて必要なテストを詳細に設計する。
* フィーチャーテスト実施
(QA)既存のPlaywrightの自動テストケースがある場合にはリグレッションテストとして実行する。
(QA)新規に自動化する部分はこの段階でPlaywrightで実装する。
* リリーステスト
(QA)既存のPlaywrightのテストケースおよび新規作成のテストケースを含めて、各チームの開発資産を統合した状態でPlaywrightのケースを実行する。

### チームとしての取組み・成果
DoDには「E2Eテストが実装されているか」だけでなく、「E2Eテスト以外の自動テスト(UnitTestなど)が実装されているか」という項目も同時に追加しました。
DoDに項目を追加したことで、各フェーズで自動テストについて話すタイミングができ、チーム内で自動化するかどうか、および、どういう自動テストを実装するかがしっかり議論されるようになってきた実感があります。

### QA組織としての取組み・成果
当初の課題であった「リリーステストのケースも増加し、テスト消化にかかる時間もどんどん増加していく」点については、上記開発プロセスを進めてきたことで、手動で実施しているリリーステストケースの増加を一定抑えることができるようになりました。
加えて、実装した自動テストをリグレッションテストとして気軽に実行できることで効率化にもつながっている実感があります。

自動テストは上記のような手動テストケースの削減を含むテストの効率化にフォーカスされがちですが、手動テスト・自動テストそれぞれにメリットはあるので、開発内容に応じて適切に使い分けることも重要だと思っています。
1つの開発内容のみならず全体の自動化方針までQA組織として活発に議論することが増えてきました。
これに対して弊社QA組織では、さらなる自動化の推進や改善活動を進めていくために、QA組織内に「Playwright管理者」という役割を作りました。
Playwright管理者を中心に、開発プロセスが円滑に進められるように、自動化の全体方針や開発規約の策定、実装のサポートなど、日々メンバーの意見を聞きながら改善活動を回すことができるようになってきています。

# 自動化の方針と実装方法
ここでは、実際の「自動化の方針」「実装方法」について紹介します。
### 自動化の方針
一般的にE2Eテストの自動化は機能変更の影響を受けやすく壊れやすいため、メンテナンスコストがかかると言われています。
それを抑えるために「自動化の対象を絞る」ことと「コードの保守性を高める」の2つの視点で自動化の方針を定めています。具体的には以下の通りです。

* 自動化の対象を絞る
・ユーザー影響度の高い機能・導線を対象にする。
・HappyPathやふるまいベースで自動化する。
・テスト観点の確認することが難しい場合には諦める。
* コードの保守性を高める
・なんらかのエラーなどが発生したとしても、再実行可能なテストコードで作成する。
・他のテストの影響を受けないよう、1つ1つのテストを小さく独立性を高くして作成する。

### 実装方法
実装手法として、画面要素などを記述するページクラスとテスト内容を記述するテストクラスを分ける**ページオブジェクトモデル**を採用しています。
（Playwrightの公式サイトでも紹介されている手法です。公式サイト：https://playwright.dev/docs/pom ）
また、弊社ではPlaywrightのテストコードの実装およびテスト実行をQAが実施することが多いです。
開発経験がないメンバーも多いことからテストコードのほとんどは日本語で記載されています。日本語で記載することでどのようなテストであるか直観的に読みやすくしています。

具体的な実装内容についても少しご紹介します。
ページクラス側では画面要素の指定や操作を記載します。
複雑な画面では、エンジニアと協力し、保守性が高くなるように画面要素の定義を行ったり、ときにはdata-testidを付与してもらうこともあります。
以下はページクラスの例です。（紹介にあたって必要な部分のみ記載します。）
```ログインページ.ts
// 画面要素の指定
this.ログインボタン = page.getByRole('button', { name: 'ログイン' });

// 操作
async ログインボタンをクリックする() {
    await this.ログインボタン.click();
}
```

テストクラスではページクラスで定義した要素やメソッドを使ってテストを書いていきます。
ページクラス側で画面上の操作をメソッドとして日本語で記載しておくことで、テストクラス側で呼び出す際にイメージしやすく、比較的簡単にテストクラス側の実装を進めることができます。
以下はテストクラスの例です。（ページクラスと同様に紹介に必要な部分のみ記載します。）
```ログインテスト.spec.ts
// ページクラスで記載した操作を利用
await ログインページ.ログインボタンをクリックする();
// 期待値の確認
await expect.soft(page).toHaveURL('https://www.hogehoge/nextpage');
```

しかしながら、実際にテストコードを実装していくことは開発経験がないメンバーにはハードルが高いので、以下のような機能を積極的に使うことで解消しようとしています。
* Record機能
・実際のブラウザでの操作をテストコードにリアルタイムで反映させることができる。
・画面要素だけでなく、期待値についてもテストコードに反映させることができる。
* Pick locator機能
・ブラウザでカーソルを当てるとその画面要素がセレクターとして表示され、コピー&ペーストすることでテストコードに反映できる。
* Show browser機能
・テストをブラウザを立ち上げた状態で実行でき、リアルタイムで動作を確認できる。（しかも手動より速い！）

私も実際に上記の機能を使ってテスト実装していますが、これなしでは実装したくない！と思うくらい重宝しています。
他社様の記事になりますが、以下の記事で動画付きで詳細にまとめられていますので詳細が気になる方はどうぞ！
[PlaywrightのVSCode拡張を使って効率的にテストを書く](https://zenn.dev/cybozu_frontend/articles/6c2a54196f056d)

# チャレンジ中のこと
まだまだPlaywrightを使った自動化で推し進めたいことがあります。
以下は直近で進めていきたいと考えていることです。
* ビジュアルリグレッションテスト
一部の画面で試験的にビジュアルリグレッションテストを実施していますが、軽微なレイアウト変更でもなかなか検知ができない状態です。NGとなる差分割合の調整やテスト実施方法など試行錯誤中です。
* CI/CDへの組み込み
いつでもどの環境でもリグレッションテストとしてテスト実行ができるようにCI/CDへの組み込みも検討中です。テストデータの都合やFlakyなテストもあることから弊社SREチームとも連携しながら進めています。
* 利用ブラウザの拡張
現状はChromeをメインにテスト実施をしています。ブラウザが変わるとテストで考慮する項目が増えたり、レイアウトも少なからず変わるため、1つ1つ課題をクリアしながら進めていきたいと考えています。

# 最後に
本記事では開発プロセスにPlaywright自動化を組み込んだ話、自動化方針・実装方法についてご紹介しました。
この記事がE2Eテストを推進したいQAの方や、Playwrightを導入したい方の参考になれば幸いです！
これからも自動テストのみならず様々なことにチャレンジして、弊社QA組織が掲げる「品質の良いプロダクトを早く安定的にユーザーに届ける」ために活動していきます！
明日は@shopayさんによる「負荷試験をPlaywrightとk6で刷新した話」です！
ぜひこちらもご覧ください！