#Locatorパフォーマンスの重要性
初めての投稿になります。
さて、E2Eテストでは、各要素に頻繁にアクセスすることになるため、そのパフォーマンスはテストに要する時間に直接影響を与えるものです。そのため、要素へアクセスする最適な方法を理解することはテストに要する時間短縮に寄与すると考えられます。ここでは、ブラウザ毎に各Locatorのパフォーマンスを計測してみます。
#前提条件
- ブラウザ
- Internet Explorer 11
- IEDriverServer 3.3.0
- Microsoft Edge 38.14393.0.0
- MicrosoftWebDriver 3.14393
- Chrome 56
- chromedriver 2.28
- Firefox 52
- geckodriver 0.14
- Internet Explorer 11
- テスト環境
- nodejs 6.9.2
- selenium-webdriver 3.3
#テスト内容
以下のhtmlを使用し、最下層(id=test3)の要素を取得することとします。
<div id="test1" class="test1">
<div id="test2" class="test2">
<div id="test3" class="test3"></div>
</div>
</div>
計測に利用するクエリ
driver.findElement(By.id("test3"));
driver.findElement(By.className("test3"));
driver.findElement(By.css(".test1 .test2 .test3"));
//xpathは全称セレクタとします
//1. シンプルケース
driver.findElement(By.xpath("//*[@class='test1']//*[@class='test2']//*[@class='test3']"));
//2. 要素を一度キャッシュし、その要素から子要素を探索する
//*キャッシュ部分は計測に含みません
var element = driver.findElement(By.id("test1"));
element.findElement(By.xpath("*[@class='test2']//*[@class='test3']"));
#計測結果
ブラウザ毎に各1000回実行し、その平均値を算出しました。
Locator | Internet Explorer | Microsoft Edge | chrome | Firefox |
---|---|---|---|---|
By.id | 50.1ms | 1.8ms | 4.6ms | 3.2ms |
By.className | 50.0ms | 1.6ms | 4.2ms | 2.9ms |
By.css | 50.1ms | 1.6ms | 4.2ms | 3.0ms |
By.xpath | 34.4ms | 1.6ms | 4.3ms | 3.1ms |
By.xpath(cache) | 50.4ms | 1.8ms | 4.7ms | 3.2ms |
#考察
まず、第一に言えることはIEのみ総じてパフォーマンスが低いことです。一方、他のブラウザで各Locator間の速度差はほぼ認められませんでした。また、どのブラウザにおいてもBy.id、By.className、By.cssの速度差は認められませんでした。ソースコードを見ますと、By.idおよびBy.classNameは内部的にBy.cssに変換されているようなので差がないのだと思われます。
https://github.com/SeleniumHQ/selenium/blob/master/javascript/node/selenium-webdriver/lib/by.js
次に、IEにおけるLocator間の速度差を見てみますと、By.cssよりもBy.xpathの方が高速という結果でした。前述の通り、By.idで取得してもBy.cssに変換されてしまうため、WebDriverではその効果が得られないということでしょうか。
最後に、2つのxpath同士を比較してみますと、要素をキャッシュしない場合(By.xpath)と、要素をキャッシュする場合(By.xpath(cache))とでは、キャッシュした方が遅くなっています。これは僅かではありますが他のブラウザでも同様の傾向が見てとれます。Webアプリ開発の延長線で考えますとキャッシュしたくなるところですが、WebDriverの場合は返ってパフォーマンスの低下を招くようです。
#結論
今回の検証では、Locatorで最速はxpathであり、IEを除くLocator間の速度差はほとんど認められないため、Locatorを使い分けるよりはxpathで統一してしまう方が良いと言えます。
またパフォーマンスの観点からは、要素のキャッシュはせずに常にフルパスで取得することが望ましいと言えます。しかしながら、可読性の観点からは返ってメンテナンス性を損なうことをも考えられるため、ボトルネックに成り得るかの見極めが重要でしょう。
今回はIE8等の古いブラウザでは検証できなかったため、機会がありましたらそれらも検証したいと思います。
*本検証はマシン環境、ブラウザやWebDriverのバージョンによって異なる結果が得られる可能性もございますので、参考程度に捉えていただけますと幸いです。