まだ開発中のウェブサイトをテストしています。
多くの場合、DOM 内の要素の ID、クラス、テキスト、または位置が変更されます。そして、私が使用してきたロケーターは要素を見つけることができなくなります。
しかし、機能はまだ正常に機能しています。実際のリグレッションがない場合に、いくつかのテストが失敗することは望ましくありません。
したがって、要素ごとに 1 つのロケーターを使用する代わりに、ロケーターのコレクションを使用します。
public static final ArrayList<By> LOGIN_ANCHOR_LOCATORS = new ArrayList<By>();
static {
LOGIN_ANCHOR_LOCATORS.add(By.id("loginLink"));
LOGIN_ANCHOR_LOCATORS.add(By.linkText("Login"));
LOGIN_ANCHOR_LOCATORS.add(By.xpath("/html/body/div[5]/a"));
}
要素を見つけるための私の方法は次のようになります。
public WebElement locateElement(ArrayList<By> locators){
// create an element to return
WebElement element = null;
// until the desired element is found...
while (element == null){
// loop through the locators
for (By locator : locators){
// try to find by locator
element = customWait.until(ExpectedConditions.presenceOfElementLocated(locator));
// if not found...
if (element == null){
// log the failure
logFailingLocator(locator);
}
}
}
return element;
}
コレクション内の最初のロケーターを持つ要素を見つけようとし、失敗した場合にのみ次のロケーターを試します。
コレクションはArrayList
(順序は挿入順序によって定義されます) です。これはfor loop
、リストに追加された順序で各ロケータを試行することを意味します。
特定の順序でロケーターを追加して、上記のリストを初期化しました。Id が最初です。DOM 内の要素の位置が変更されても ID が保持されているかどうかがわかるため、正しい要素を見つける可能性が最も高い方法です。Xpath が最後にあるのは、id/class/text が変更されたとしても、DOM 内のその位置に同じタイプの要素がまだ残っている場合、それはおそらく正しい要素ですが、他のロケーターよりも確実性が低い可能性があるためです。
NoSuchElementException を無視する流暢な待機を使用しています。
// Wait 5 seconds for an element to be present on the page, checking
// for its presence once every quarter of a second.
Wait<WebDriver> customWait = new FluentWait<WebDriver>(driver)
.withTimeout(5L, TimeUnit.SECONDS)
.pollingEvery(250L, TimeUnit.MILLISECONDS)
.ignoring(NoSuchElementException.class);
そのため、1 つのロケーターが失敗しても、ループは中断されません。失敗を記録するだけで、次のロケーターの試行が続行されます。
すべてのロケーターが失敗した場合、要素は null のままになり、テストは失敗します。その理由は、機能/機能の実際の回帰である可能性がはるかに高くなります。
定期的にログをチェックして、1 つまたは 2 つのロケーターに失敗している要素がないか確認し、その間に pageObject でそれらを更新しますが、テストは引き続きスムーズに実行されます。
この方法でプロジェクトをセットアップすることの長所と短所は何ですか?