テスト自動化において、永遠について回る「スローテスト問題」。
万能の解決策はありませんが、少しでも工夫して、自動テストの実行時間を削減しなければいけません。
GUIレスブラウザを使うことで、スローテスト問題の軽減につながります。
まず前半で、スローテスト問題およびGUIレスブラウザについて解説し、後半では実際にヘッドレスモードを使用してみます。
1.スローテスト問題とは
スローテスト問題とは、テスト自動化で実行時間が想定よりも長くかかってしまい、ソフトウェアの開発作業に影響が出てしまうことです。
「ん?テスト自動化したのなら、人の手でテストするよりも実施時間は短くなるはずでは?」と思われた方もいるかもしれません。
もちろんその通りです。ここでいう「スロー」とは1件1件のテスト実行にかかる時間ではなく、それらをまとめて、一度に実行するテスト全体の実行時間が増えることを意味しています。
1件のテスト実行が1秒で終わったとしても、テスト件数が5000件あれば1時間以上かかります。たとえばCIなどの仕組みを使って、コミットごとにこれらのテストをすべて実施するような運用にしていた場合、1.5時間に1回程度のコミット頻度でしか正常にCIが回せなくなるということになります。
これではせっかくの仕組みが宝の持ち腐れです。
スローテスト問題は「必要悪」
テスト自動化によってスローテスト問題が発生したとしてもテスト自動化は推進していくべきでしょう。
なぜなら手動テストであれば、その何倍、何十倍もの時間がかかってしまうからです。
テスト自動化の取り組み自体がうまく作用しているのであれば、スローテスト問題はどうしても発生してしまう、「必要悪」のようなものと考えましょう。
テスト自動化が効率的になればなるほど、たくさんのテストを実行させる要求が高まりますが、一方で、時間は有限なので、同じやり方を続けていたのでは実行できるテスト件数はいつか必ず頭打ちになります。
常に改善を続けていかなければならない「いたちごっこ」ではありますが、スローテスト問題の発生自体は、逆に開発プロセスの効率化が進んでいる、とみなすべきでしょう。
2.スローテスト問題の対処方法
スローテスト問題を軽減するには、いくつかの方策が考えられます。
大きく分けると以下の3つです。
時間あたりの実行可能なテスト件数を増やす
実行可能なテスト件数を増やすには単純にハードウェアなどのリソースを増強するなどの方法が考えられます。
必要十分な数までテスト件数を減らす
逆に必要なテストのみを実施するようにし、不要なテスト件数を減らす考え方もあります。
コードやオブジェクトの依存関係を把握し、影響のあるテストのみを実施する、などの対処方法があるでしょう。
1件あたりの実行時間を減らす
特に1件のテストを実施するのに多くの時間がかかる、E2Eテスト(エンド・トゥ・エンド・テスト)において効果を発揮します。
3.WebシステムのE2Eテストと実行時間
E2Eテストとは、システムが組みあがった状態で、ユーザーの操作からシステムの内部動作まで、つまりシステムの操作側の端からシステム側の端まで一貫して動作させるテストのことです。
システム全体を通してテストするわけですから、単体モジュールのテストなどに比べれば、1件あたりの実施時間は非常にかかります。特にWebシステムの場合、システム側の動作もさることながら、ユーザーが操作するブラウザの起動や実行にかかる時間が極端に影響してきます。
皆さんも、このコラムをWebブラウザを通してご覧になっていると思いますが、ブラウザの起動時、ホームページが表示されるまでには多少時間がかかるのではないでしょうか。最近のブラウザは高速化が進んでおり、不快に感じることも少なくなってきました。
それでもブラウザの起動直後にすぐ画面が表示される、とまでは至っていません。
人間が操作する分にはほとんど影響がありませんが、自動テストのように、一度に何百回、何千回と実行するような場合には、その少しの「待ち」が大きなオーバーヘッド(余分な処理)となるわけです。
なぜ、そのように時間がかかるのかというと、ブラウザのようなGUIアプリケーションの場合、データの処理だけでなく、その情報を画面情報としてレンダリングし、OSとやり取りをして画面に表示させる、という処理を行う必要があるからです。
4.GUIレスブラウザとは
ブラウザを使用した自動テストに上記のような問題があるのなら、「じゃあ、画面表示をなくせばいいじゃん」ということで、「GUIレスブラウザ」や「ヘッドレスブラウザ」と呼ばれるものが開発されています。「オーバーヘッド」を「なくす(レス)」からヘッドレスブラウザです。
以前は「PhantomJS」というものがあり、代表的なGUIレスブラウザとしてよく利用されてきました。しかし最近開発が終了し、github上のリポジトリは2018年6月にアーカイブ化されました。
代わって登場したのが現在多くのユーザーに使用されているWebブラウザである、ChromeとFirefoxのヘッドレスモードでの実行機能です。
代わって、というよりもそれらの機能が実装されたため、PhantomJSの開発も終了したといえます。
Webシステムのテストにおいて、ブラウザ間の互換性は常について回る問題です。GUIレスブラウザにおいてもブラウザの互換性が大きな問題となります。
先のPhantomJSが代表的なGUIレスブラウザとして利用されてきた理由は、ChromeやFirefoxで使用されていたレンダリングエンジンである、「WebKit」を内部で使用しているからです。
簡単に言い換えれば、それらのブラウザと表示が同じになる、ということです。
ただし、現在ではそれらのブラウザも別のレンダリングエンジンを使用していますし、ブラウザの高性能化にともない、Javascriptの実行エンジンの違いも大きな影響を及ぼすことになりました。
そういったWebブラウザの高機能化や多様化に加え、テスト自動化技術の向上によるE2Eテストの普及もあり、公式のブラウザがヘッドレスモードに対応することは時代の要請であった、と言えるかもしれません。
5.GUIレスでの実行
ここまで、テスト自動化につきものの「スローテスト問題」について、そして「GUIレスブラウザ」について解説してきました。ここからは、ChromeとFirefoxのヘッドレスモードを実際に操作してみて、ヘッドレスモードありの場合と、なしの場合の違いを検証してみましょう。
筆者の動作環境は以下の通りです。
- OS:Windows8.1 64bit
- 実行環境:Python3.6.4 64bit
- 使用ブラウザ:Firefox, Chrome
- ブラウザ操作ライブラリ:Selenium webdriver
当然のことながら、セットアップや実行時にはインターネットに接続している必要があります。
環境構築については詳述せず、概要のみ記載します。取り立てて複雑なことを実施するわけではありません。
まず、Pythonを公式サイトからインストールします。
その後、コマンドプロンプトで下記のコマンドを実行すると、Python用のSelenium webdriverがインターネットからダウンロードされ、インストールされます。
pip install selenium
Seleniumのインストールと合わせて、ブラウザを操作するためのドライバを取得しておきます。
Firefox用のGeckoDriverと、Chrome用のChromeDriverを用意しておきましょう。
これらは、ソースコードのファイルと同じディレクトリに配置します。
さて、プログラムを書いていきましょう。下記のコードを記載したファイルに「headless.py」という名前を付け、適当なディレクトリに保存しておきます。
from selenium import webdriver
def main():
# ブラウザのオプションにヘッドレスモードを指定
options = webdriver.FirefoxOptions()
options.add_argument('--headless')
# 設定したオプションでブラウザオブジェクトの生成
browser = webdriver.Firefox(options=options)
# Googleのトップページを表示
browser.get('https://google.co.jp/')
# スクリーンショットの取得
browser.save_screenshot('image.png')
# ブラウザ操作終了
browser.quit()
if __name__ == '__main__':
main()
このソースコードを書いたファイルをPythonで実行します。コマンドプロンプト上で、下記の2つのコマンドを実行してみてください。
cd [ソースコードを保存したディレクトリのパス] python headless.py
そうすると、Googleのスクリーンショットが保存されます。そのとき、画面表示はされません。
ソースコードの7行目、
options.add_argument('--headless')
の、行頭に、コメントアウトをする、「#」を付けて実行してみてください。
# options.add_argument('--headless')
そうすると、Firefoxが立ち上がって、同じ動作をします。
6.効果の検証
何度か実行して、プログラムが終了するまでの時間を測ってみてください。筆者の環境では、だいたい3,4秒、ヘッドレスモードの方が早く実行されます。
実際にどれくらいの差があるのか、FirefoxとChromeで、モードを変えて20回実行し、平均を取ってみました。
ヘッドレスモードなし | ヘッドレスモードあり | |
---|---|---|
Firefox | 18.15秒 | 15.58秒 |
Chrome | 13.19秒 | 10.48秒 |
ヘッドレスモードの方が2.5秒程度、パーセンテージとして15%~20%ほど早い結果となりました。
今回のコードでは開いた後の操作が画面キャプチャだけだったため、それほど大きな差にはなっていませんが、多数のテストケースを実行するような場合であれば、より大きな違いになるでしょう。
ただし、2倍も3倍も変わるわけではないため、スローテスト問題を解決するには、他の方法と合わせて検討する必要があります。
まとめ
スローテスト問題とは、テスト自動化で実行時間が想定よりも長くかかってしまい、ソフトウェアの開発作業に影響が出てしまうことです。
一般的に使われているブラウザにヘッドレスモードが搭載されたことにより、Webブラウザを使用したE2Eテストの自動化は、より取り組みやすくなりました。
しかし、スローテスト問題が抜本的に解決されるわけではないため、テストケースの効率化などと合わせて継続的な改善が必要にはなるでしょう。
その改善方法のひとつとして導入してみてはいかがでしょうか。