Testuję stronę, która jest wciąż w fazie rozwoju.Plusy/minusy za korzystanie z wielu lokalizatorów na element Selenium?
Często zmienia się identyfikator, klasa, tekst lub pozycja elementu w DOM. A wtedy lokalizator, którego używam, nie będzie już w stanie znaleźć elementu.
Ale funkcje nadal działają poprawnie. Nie chcę, aby kilka testów zawodziło, gdy nie ma rzeczywistej regresji.
Zamiast pojedynczego lokalizatora dla każdego elementu, mam kolekcję lokalizatorów.
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"));
}
Moja metoda znajdowania elementu wygląda następująco:
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;
}
on próbuje znaleźć element z pierwszego lokalizatora w kolekcji, i tylko wtedy, gdy nie powiedzie się, spróbuj następnego lokalizatora.
Kolekcja to ArrayList
(kolejność jest określona przez zamówienie reklamowe), co oznacza, że mój for loop
spróbuje każdego lokalizatora w kolejności, w jakiej zostały dodane do listy.
Zainicjowałem powyższą listę, dodając lokalizatory w określonej kolejności. Id jest pierwszy, ponieważ wyobrażam sobie, że pozycja elementu w DOM zmienia się, ale zachowuje swój identyfikator, to będzie to sposób, w jaki będę najprawdopodobniej zlokalizował właściwy element. Xpath jest ostatni, ponieważ nawet jeśli id / klasa/tekst ulegnie zmianie, ale nadal istnieje ten sam typ elementu w DOM w tej pozycji, to prawdopodobnie jest to właściwy element, ale może mniej pewny niż inne lokalizatory.
używam biegle czekać który ignoruje 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);
Więc kiedy jeden lokator się nie powiedzie, to nie będzie przerwać pętlę - po prostu loguje awarię, a następnie jeszcze dalej, spróbuj następnego lokalizator.
Jeśli wszystkie lokalizatory ulegną awarii, element pozostanie pusty, test się nie powiedzie, a znacznie bardziej prawdopodobny jest faktyczny regres funkcji/funkcjonalności.
Okresowo sprawdzam logi dla dowolnego elementu z 1 lub 2 lokalizatorami powodującymi niepowodzenie i aktualizuję je w mojej jednostce pageObject w międzyczasie, podczas gdy testy nadal działają płynnie.
Jakie są plusy lub minusy związane z tworzeniem mojego projektu w ten sposób?
Świetne pytanie, Pat! W mojej pracy korzystamy z [@FindBy] (http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/support/FindBy.html). Czy rozważałeś to jako alternatywę? Przykład: '@FindBy (className =" reducedPrice ") private List reducedPrice;'. –
Brian