https://d-cube.connpass.com/event/149831/
スライド中「エンジニアの斎藤」という謎の人物が出てきますが、「エンジニアの採用」の誤記でございました。お詫び申し上げます。
クロスブラウザテストの闇と闇と闇と闇末村 拓也 @ Autify Inc.
View Slide
簡単に⾃⼰紹介末村 拓也 (すえむら たくや)⽊村拓也ではないQAエンジニアCodeceptJSのコミッタQiitaに書いた 我が名は神⿓……どんなテストもひとつだけ⾃動化してやろう という記事が好評でした現在は Autify というテスト⾃動化プラットフォームを作る会社で働いています
簡単にAutifyの説明https://autify.comAIによるセルフヒーリングと、わかりやすいUIが特徴のテスト⾃動化プラットフォームですWebアプリケーションのE2Eテストを簡単に⾃動化することができますコーディングの知識は不要で、ブラウザ操作を⾃動記録してシナリオを作れますSelenium IDEの超強い版みたいなイメージですモバイルも含めた様々なOS・ブラウザの組み合わせでテストを実⾏することができます
クロスブラウザテストとは同じテストシナリオを複数のブラウザで実⾏し、互換性を確認することChromeでは動いたけどIEでは動かなかった、みたいな悲劇を防げるシナリオを使い回せるため、⾃動テストの実装コストが相対的に少ない(と期待されている)表⽰されている⽂字列の検証や、Javascriptのエラーが出ていないかどうか、あるいは表⽰崩れなどを検証することもある今⽇は表⽰崩れの検証とかの話は しませんどのE2Eテストフレームワークでも出来るとは限らない今⽇はSelenium(WebDriver)についての話をします
SeleniumとWebDriverについておさらいSeleniumは様々なブラウザの操作を⾃動化するためのフレームワークですWebDriverという、「あるブラウザの⾃動操作に特化したドライバ」を各ブラウザのベンダが作ってくれています例えばChromeならChromeDriver、FirefoxならGeckoDriverというようにWebDriverの仕様は標準化されているので、どのブラウザに対しても同じように⾃動操作の命令を出す事が出来ます
ここで質問ですクロスブラウザテストが必要な⼈︖クロスブラウザテストにしっかり取り組んで、成果を出せているという⼈︖クロスブラウザテストあきらめちゃった⼈︖
この発表で話すことSelenium(WebDriver)でのクロスブラウザテストは「可能」だが「簡単」ではない実際にクロスブラウザテストに取り組む中で得た知⾒(というか苦労話)をご紹介しますSeleniumがイケてないとかそういう話ではありませんのでご留意くださいOSSだし、みんなで良くしていけばいいよね
闇その1 - インストール肌感ですがSeleniumはじめた⼈の半分ぐらいここでつまづいてる
WebDriverのインストールはブラウザごとに必要です各ブラウザのバージョンに合わせたWebDriverのインストールが必要です間違ったバージョンをインストールすると動きませんChromeとFirefoxはブラウザとWebDriverがセットになったDockerコンテナが公式から提供されていますが、当然Linux上で動いているので、ファイルアップロードなどOS組み込みのコンポーネントはLinuxになってしまいますWebDriverのインストールを⾃動化出来る selenium-standalone というNodeJSのライブラリがありますしかし、後述の理由でEdge 18から動かなくなりました参考:https://hub.docker.com/u/selenium/
おまえはIEDriverのセットアップにかかった時間を数えたことがあるのか︖IEDriverのインストールはものすごく⼯程が多いIEDriverServerにPATHを通す「全てのゾーンで」保護モードを無効にするズームレベルを100%にするOSのズームレベルも100%にしないといけないので⾼DPI端末では事実上使えないです⼀応無視するためのCapabilityがあるらしい(未検証)レジストリの設定が必要です参考:https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver#required-configuration
「IEはもうオワコンなのでEdgeが使えれば⼤丈夫です」Edge(EdgeHTML)18からインストール⽅法が変更になりましたWindowsの設定で「開発者モード」を有効にする必要があります管理者権限でコマンドプロンプトを実⾏して DISM.exe /Online /Add-Capability/CapabilityName:Microsoft.WebDriver~~~~0.0.1.0 を実⾏するとインストールされますインストール先が公式のどこにも書いてありません(︕)ので書いておきますが C:\Windows\System32\MicrosoftWebDriver.exe です先述のNodeJSのライブラリ selenium-standalone はこの⽅式に対応してないので⾃前でインストールする必要があります
BrowserStackとか使えばいいじゃないですかBrowserStackなどのデバイスファームを利⽤すればインストール周りの苦労は激減する複数のOS・ブラウザのバージョンを選択できるため互換性テストに最適ただしクッソ遅いサーバが海外にあるためたまにBrowserStackそのもののバグを踏むことがある特定のCapabilityが無視されるなどサポートはしっかりしてるのでなんかおかしかったらすぐ聞くといいです英語だけどな︕参考: デバイスファームの有名どころhttps://browserstack.com/https://saucelabs.comhttps://crossbrowsertesting.com/
ほう、インストールを倒したのか︖ではこのCapabilitesが相⼿をしてやろうCapabilities = 実⾏対象のブラウザに期待する要件どのOS、どのブラウザで実⾏するのかなどを指定するブラウザの挙動(想定外のアラートが表⽰されたときにどうするか)などもここで決めるブラウザの起動オプションもここで設定する普段Chromeを起動するときには意識していないような起動オプション群を突然意識させられる初⼼者はここで躓くことが多い歴史的経緯で同じ役割のCapabilityが複数存在することがあり、どのブラウザにどのCapabilityが使えるかが未整理例えば unhandledPromptBehavior と unexpectedAlertBehaviour とかよく⾒ると Behavior のスペルも違うぞ︕
闇その2 - Basic認証
Basic認証とはサイトにアクセスした際に表⽰される簡易的な認証⽅法QA、ステージング環境でよく使われる
URLに埋め込めばいいだけじゃないんですか︖https://username:[email protected] のように認証情報を埋め込むと認証プロンプトをスキップできる……はずですが、念の為各ブラウザで確認してみましょう
URLにBasic認証情報を埋め込むdriver.get('https://admin:[email protected]/basic_auth')element = driver.find_element_by_css_selector('h3')print(element.text)Chrome: スキップできるFirefox: スキップできるEdge: スキップできるIE: スキップできるSafari: スキップ できないSafariは過去のバージョンではスキップできたようですが、少なくとも現在の最新バージョン(12)ではスキップできませんでした
「Safariはサポート外なので⼤丈夫です」そもそもURL埋め込みにはいろいろ問題があるjavascriptの fetch() が動作しなくなるwebDriverの /session/{session_id}/url の戻り値にも認証情報が含まれているので、アサーションの期待値にも同様に認証情報を含まないといけない今後もどのブラウザでも同じようにURLに埋め込めるかどうかはわからないURLへの認証情報埋め込みはセキュリティ上の懸念からどのブラウザでも無効にされている試しに⼿元のブラウザのアドレスバーにBasic認証の認証情報を埋め込んでみてください⾃動操作時だけ例外的に使える状態
ならばHTTP Headerを追加しよう認証情報をBase64にエンコードし、リクエストごとに Authorization:dXNlcm5hbWU6cGFzc3dvcmQ= のようなHTTPヘッダを付け加えることで認証プロンプトをスキップできるしかし、Seleniumには setHeader() みたいなメソッドはないどうしてもやりたい場合はプロキシサーバを⽴てる必要があるプロキシを経由し、HTTPヘッダを偽装するとSSLの証明書検証に失敗するいわゆるMan In The Middle Attackと同じ状態になる回避するための acceptInsecureCerts というCapabilityがあるAppiumではCapabilityではなくAppium Desktopの設定を変更する必要があるiOS13のSafariは正しく設定してもなお動きません(未解決)知ってる⽅こっそり教えて下さい
闇その3 - 各ブラウザの実装の違い
ここで問題です、この2つは何が違うでしょうか︖Automate testing for everyone!Automate testing for everyone!
答え: SpaceかNBSPかの違い(NBSP=Non-Braking SPace: 「この位置では改⾏させない」という特殊な空⽩⽂字)
WebDriver的にはどうなんだっけhttps://w3c.github.io/webdriver/#get-element-textThe Get Element Text command intends to return an element’s text “as rendered”.Get Element Text は要素のテキストを「レンダリングされた通りに」返します
というわけで、NBSPがどのように扱われるか各ブラウザで検証してみましょうdriver.get('https://tsuemura.github.io/webdriver-is-muzukashii/gettext.html')text1 = driver.find_element_by_id("text1").text # 半⾓スペースを使ったテキストtext2 = driver.find_element_by_id("text2").text # NBSPを使ったテキストprint(text1 == text2)Chrome: 半⾓スペースになるFirefox: 半⾓スペースになるInternet Explorer︓ 半⾓スペースになるEdge: NBSPのままSafari: NBSPのまま※Edgeはバージョン18で「半⾓スペースになる」に修正されました
WebDriverの仕様は標準化されているが……︖各ブラウザベンダが「仕様通りに」実装できているとは限らないブラウザの仕様が異なる以上、どのブラウザでも「同じように」動くとは限らない「⼀つのシナリオでどのブラウザでも同じように動く」 は意外とむずかしい
まとめSeleniumのインストールは思ってるよりずっと⼤変Basic認証など「当然できるだろ」と思われてることが意外と⼤掛かりになる同じテストシナリオがそのまま使えるとは限らないそして⾔うまでもなく、テストコードの記述や保守も普段のソフトウェア開発とは全然違う⾟さがある……いったいおれたちはなにと戦っているんだ
ここからポジショントークの時間ですクロスブラウザテストを⾃前で実装する前に、⼀度⽴ち⽌まって「⾃分たちはその技術を⾝につけるべきなのか」を考えてみてくださいクロスブラウザテストの環境を構築し、実装し、安定して動かすには、ブラウザの知識、Web開発の知識、インフラの知識、テストの知識……などを持った優秀な⾃動化エンジニアの斎藤が必須になります⼀⽅、有償のサービスやプラットフォームは、彼らが独⾃にワークアラウンドを実装し、これまでに挙げたような⾟さをユーザーが意識せずとも使えるようになっています有償のサービスは⼀⾒⾼く⾒えますが、⼈を⼀⼈雇うよりは圧倒的に安く上がりますし、サポートも受けることが出来ます
それでも⾃前でやってみたいあなたへあなたは技術⼒と情熱と探究⼼を持った素晴らしいエンジニアですテストの⾃動化に情熱を燃やせる⼈は貴重です、同僚や知⼈にもテストの⾯⽩さを伝えてあげて、仲間を増やしてくださいできればOSSへのコントリビュートやブログ・勉強会などでのアウトプットを通じて、あなたが踏んだ地雷を他の⼈が踏まないようにしてあげてくださいこの世界は闇ばかりです、あなたこそが光です⼀緒に⾃動テストの闇を照らしていきましょう
Enjoy Testing!