この記事はエムスリー Advent Calendar 2020 17日目の記事です。明日以降も面白い記事が続きますので、是非購読・拡散お願いします。
エムスリーエンジニアリンググループ QA の窪田です。私がエムスリーに入社したのが去年の11月なので、およそ1年。あっという間でした。この一年で自動テストを含めて色々なことに取り組んできました。本記事では IE の E2E 自動テストに取り組んだ内容をお話したいと思います。
背景
m3.com 開発チームでは週に1日、不具合分析の会が設けられています。詳しくは 福林の過去記事参照。 この会ではその週に発生した不具合(開発環境、本番問わず)を1件ごとに分析をして、原因の洗出しと再発防止策の策定を実施しています。IE 動作固有の予期せぬ不具合は頻度は少ないものの、その他のブラウザより多く発生しておりそのたびに対策を考えていました。ただし、開発環境での不具合事例が多かったため、埋め込み防止(事例の共有)や、手動確認方法の改善にとどまっていました。
しかし、先日、影響範囲外と思われていた部位で IE での表示に影響が出ていたことが発覚し、自動テストなどで、リグレッション確認ができないと根本的には防げないというチームメンバー内での結論になり、IE の自動テストでの確認の検討に着手しました。
本番不具合の傾向
ということで、本番で起こった不具合でかつ、PC ブラウザ依存の不具合がどれくらいあるかについて調べてみました。世の中には色々なブラウザがありますが代表的なものには以下が挙げられます。
- Internet Explorer
- Edge
- Google Chrome
- Firefox
- Safari
これらのブラウザでどれだけの不具合が発生しているでしょうか。
実際に過去2年分の障害データを見てみると、ブラウザの種類が起因で発生したものは全体の3%で、うち、操作不能等の障害は1%にも満たないという事実があります。 これにはある程度理由があって、例えばデザインだと共通のデザインの部品が整備されており、それが適用されているため、新たに不具合が発生することが少ないなどです。逆に言うと新しく作ったデザインや実装の場合、きちんと確認しないと、デザイン崩れや操作ができないといった事態が発生する可能性が標準の部品を使用した場合より上がります。また、上記ブラウザ種類が起因で発生したもののうち80%以上は Internet Explorer で かつ新規の部品を使用したときに発生したものです。本番ではない、開発環境でのテストでも概ね同様な比率になっています。
整理すると、本番不具合全体では以下の通り。
内訳 (全本番不具合のうち) | 割合 (%) |
---|---|
ブラウザ起因 | 3 |
それ以外 | 97 |
また、ブラウザ起因のみに着目した場合は以下の通り。
内訳 (ブラウザ起因の本番不具合のうち) | 割合 (%) |
---|---|
IE でのみ発生 かつ 新規の部品を使用したもの | 83 |
それ以外 | 17 |
これらの傾向から、ブラウザバリエーションの自動テストは一旦は不具合分析会で出た方針と同様 IE のみの検討とし、新規の部品を多用しているプロジェクトへの導入を目指すことにしました。
E2E テスト導入検討
今までの分析を踏まえて IE だけのために開発、メンテナンスコストを多大にかけたくないという思いがありました。そのため今までの経験上、動作の不安定さなどメンテナンスコストがかかりがちな Selenium の運用は避けるといった方針で検討を開始しました。 弊社では、以前から QA Wolf と reg-suit を組み合わせた VRT (Visual Regression Test) を SET のメンバーが推進(先日ソフトウェアテスト自動化カンファレンスで発表)しており、結果も出ていたためそれを真似して適用すれば検討も導入も楽なのでは? と思い、とりあえずは VRT ですすめることにしました。ブラウザ起因の本番不具合はいずれも、表示に異常があるものであり、VRT で検出可能です。
では、Selenium 以外で IE を動かせるツールについて調べてみると、意外と選択肢は少なく、Selenium WebDriver と TestCafe くらいなもので、Selenium は上記の通り。TestCafe で検討を進めます。
TestCafe で IE を動かす
TestCafe とは、ブラウザを用いた End to End のテストが実行できるテストツールです。 JavaScript と TypeScript を用いてテストコードを書くことができます。
個人的には IE を動かすことができるということと、画面読み込み、表示を待って色々と操作してくれる事が嬉しいです。公式ページにも書いていますが、
- メジャーな環境ならだいたい動く
- 1分でセットアップできる
- オープンソースかつ、無料利用が可能(TestCafe Studio は有料)
という導入のしやすさもあります。Node.js がインストールされている前提で、
npm install testcafe
これでインストール完了となります。
テストコードも非常に簡単にかけます。 こちらの記事: 個人的ベストE2Eフレームワーク"TestCafe"の紹介 を参考にさせていただきました。
今回の例は以下になります。
import 'testcafe'; import { Role, Selector } from 'testcafe'; const testDoctor = Role('https://www.m3.com/login', async t=>{ const loginButton = Selector('button').withText("ログイン"); await t .typeText('#loginId', 'xxxxx') .typeText('#password', 'yyyyy') .click(loginButton.nth(0)); }); fixture ('example test') test('top', async (t:TestController) => { await t .useRole(testDoctor) .navigateTo('https://hogehoge.m3.com/') .takeScreenshot({ path:'sample/top.png' }); }); test('detail', async(t:TestController)=> { await t .useRole(testDoctor) .navigateTo('https://hogehoge.m3.com/detail/xxx') .takeScreenshot({ path:'sample/detail.png' }); });
TestCafe の機能の中で、"User Roles" は便利だなと思いました。テストの中でユーザのログイン状態を維持したまま複数のテストを実施したり、ユーザを切り替えながらテストをしたい時があると思います。 そのときに非常に便利です。上記サンプルのうち、以下の部分が該当です。例では1ユーザのみですが、同じ書き方で複数ユーザを定義できます。公式サイト参照。
const testDoctor = Role('https://www.m3.com/login', async t=>{ const loginButton = Selector('button').withText("ログイン"); await t .typeText('#loginId', 'xxxxx') .typeText('#password', 'yyyyy') .click(loginButton.nth(0)); });
今回の目的は、過去の分析結果から IE できちんと表示できているかを確認できれば良いので、テストコード的にはスクリーンショットを取るだけです。
test('top', async (t:TestController) => { await t .useRole(testDoctor) .navigateTo('https://hogehoge.m3.com/') .takeScreenshot({ path:'sample/top.png' }); });
testcafe コマンドで、テストを実行します。引数でブラウザ種類とプロキシなども指定できます。
testcafe ie testExample.ts --proxy testproxy:8888
reg-suit でVRTを実現する
TestCafe で取得したスクリーンショットを比較していきます。reg-suit の導入も簡単で、以下のコマンドを打つだけです。
npm install reg-suit
初期設定は以下コマンドを打つと、拡張機能の追加や、クラウドストレージなどの情報を求められます。 今回は S3 を使用しました。
reg-suit init
初期設定が終わると、設定ファイル (regconfig.json) はこんな感じになります。今の時点では CI に組み込めていないのでプラグインも少ないです。
{ "core": { "workingDir": ".reg", "actualDir": "screenshots/sample", "thresholdRate": 0, "ximgdiff": { "invocationType": "client" } }, "plugins": { "reg-publish-s3-plugin": { "bucketName": "example" }, "reg-simple-keygen-plugin": { "expectedKey": "expected", "actualKey": "actual" } } }
とりあえず1回動かしてみて、現在の状態を S3 にアップロードして準備完了です。testcafe でスクリーンショットを取り直して、以下コマンドを打つと、現在の状態を取得、画像の比較、結果出力、画像のアップロードまで実施してくれます。
reg-suit run
結果は以下のように出力されて、比較結果の HTML が S3 上に出力されます。
[reg-suit] info Comparison Complete [reg-suit] info Changed items: 2 [reg-suit] info New items: 2 [reg-suit] info Deleted items: 0 [reg-suit] info Passed items: 0 [reg-suit] info The current snapshot key: 'actual' [reg-suit] info Report URL: https://example.s3.amazonaws.com/actual/index.html
比較結果HTMLを目視で確認します。例えば、以下のような出力になります。diff 表示は画像を重ねて差異がある部分を赤く表示、blend 表示は画像を重ねて、差がある部分を赤い矩形で囲って表示するものです。例がgoogle検索なのでわかりにくいかもしれませんが、このようなちょっとした変化にも気付けます。
これ以外にも 画像を横に並べて見るモードや、新旧画像を切り替えて表示できたりなど、変更箇所をわかりやすく見ることができます。
まとめ
まだ、導入の途中ですが、CIに組込んで開発中に常に動かせるようにしていきたいです。testcafeは比較的動作が安定しているので、運用もそこまで大変でないと思っております。また、テストコードは今の所 URL を指定してスクリーンショットを取るだけなので、メンテナンスが非常にしやすく誰でもメンテナンスできるのでは無いかと考えています。今後も、SET メンバーを中心に自動テスト導入を進めていく方針です。
QA Wolf x reg-suit の詳細記事は SET のメンバーが書いてくれるはず……。
[PR] We are hiring!
エムスリーの QA / SET では、自動テストの検討、テスト手法の導入、プロセス改善など様々な品質改善活動を実施しています。品質改善活動をガシガシ推進していきたい方、開発メンバーと楽しくプロダクトを良くしていきたい方はエムスリーで一緒に QA しましょう。まずはカジュアル面談からでも、お待ちしてます!