Вы находитесь на странице: 1из 18

POP VASILE

INTEL ROMANIA

Selenium WebDriver patterns for


maintanability
Challenges
Application flow se schimba des
Design-ul paginilor e modificat de la o versiune la alta
Componentele din UI se schimba (CSS classes,
attributes, tags)
Componentele pot fi randate in o secunda sau in 6,
depinzand de conexiune, de browser, de performantele
clientului, etc.
Cod simplu, dar ineficient
@ Test

p u b lic void n otS oLovely() {

driver.get("https://reader.study.intel.com /cm # /dashboard");

driver.fi
n dElem ent(By.cssSelector("a[data-id= 'm y-library']")).click();

String prodId = driver.fi


n dElem ent(By.cssSelector("div[data-product-

nam e= 'Biology']")).getAttribute("data-product-id");

Assert.assertEquals(prodId, "txt123456");

driver.fi
n dElem ent(By.cssSelector("div[data-product-nam e= 'Biology']")).click();

}
Probleme
Daca unul din elemente e modificat (atribut, tag HTML,
etc.), va trebui modificat in toate testele unde e folosit
selectorul poate fi salvat intr-o variabila si refolosit, ca
solutie partiala

Testul face click pe un element fara sa fie sigur ca


elementul este incarcat

Testul este greu de inteles daca nu e comentat


PageObjects - LoadableComponent
@ Test

p u b lic void rath erPretty() {

Reader reader = n ew R ead er(d river).g et();

reader.clickM yLibrary();

BookC ontainer book = reader.getBookByN am e("Biology");

Assert.assertEquals(book.getProductId(), "txt123456");

book.openBook();

}
PageObjects - LoadableComponent
Simplificarea codului e data de faptul ca facem o modelare a
paginilor aplicatiei in clase Java.
p u b lic class R ead er exten d s Load ab leC om p on en t< R ead er> {
p rivate W eb D river d river;
@ FindBy(css = "a[data-id= 'm y-library']")
private W ebElem ent m yLibrary;

p u b lic R ead er(W eb D river d river) {


th is.d river = d river;
PageFactory.initElem ents(driver, th is);
}
@ O verride
p rotected void isLoad ed () th row s Error {
Assert.assertTrue(driver.getTitle().contentEquals("IntelStudy Content M anager"));
n ew W eb D riverW ait(d river, 5).u n til(Exp ected C on d ition s.visib ilityO f(m yLib rary));
}
@ O verride
p rotected void load () {
driver.get("https://reader.study.intel.com /cm # /dashboard");
}
p u b lic void clickM yLib rary() {
m yLibrary.click();
}
p u b lic B ookC on tain er g etB ookB yN am e(S trin g n am e) {
retu rn n ew B ookC on tain er(d river, d river.f i
n d Elem en t(B y.cssS elector("d iv[d ata-p rod u ct-
n am e= '" + n am e + "']")));
}

Metodele din Page model expun actiuni, nu elemente din pagina.


Orice pentru a-l face fericit pe Martin Fowler
(http://martinfowler.com/bliki/PageObject.html)
Smart waits
Problema: testul este marcat ca Failed deoarece o componenta este
incarcata prea lent
Solutie:
n ew W eb D riverW ait(d river, 5).
until(ExpectedConditions.visibilityO f(lazyC om p on en t))).click();

Testul va astepta maxim 5 secunde ca elementul referentiat de


selector sa fie afisat. Daca este afisat mai repede, testul va
continua imediat. In caz contrar, testul va fi marcat ca Failed. Exista
un set extins de ExpectedConditions predefinite, dar se poate crea
usor un ExpectedCondition custom pentru situatii speciale.
Chained actions
Chained actions este un pattern (nu neaparat specific Selenium) util in a face
codul testelor mai lizibil (apare si tendinta de abuz).

loginPage.typeU ser("vicus").typePass("youw ish").signIn();

Modificarile sunt minime in modelarea paginilor, e necesar doar ca metodele


care expun actiuni testului sa returneze obiectul curent (this).

p u b lic Log in Pag e typ eU ser(S trin g user){


usernam eBox.sendKeys(user);
retu rn th is;
}
Page components
Un pattern probabil mai rar intalnit este PageComponents. In
aplicatiile complexe unde se intalnesc componente repetate poate
deveni util modelarea componentei in obiect Java (a nu se
confunda cu PageObjects).

Page
Components
Page components
O componenta va fi modelata ca si clasa Java pe baza obiectului
WebElement care o reprezinta. Nu mai pot fi folosite annotations
@FindBy, dar putem folosi By selector pentru a evita repetarea.

p u b lic class B ookC on tain er {


p rivate W eb Elem en t elem en t;
private By coverLocator= n ew B yC ssS elector("d iv[typ e= 'cover']");
p u b lic B ookC on tain er(W eb Elem en t elem en t) {
th is.elem en t = elem en t;
}
p u b lic S trin g g etProd u ctId () {
retu rn elem en t.f i
n d Elem en t(coverLocator).g etA ttrib u te("p rod u ct-id ");
}
}
Soft Asserts
In general se doreste ca un test sa fie marcat Failed daca un
assertion este Failed. Pot exista insa situatii in care testul verifica
diferite elemente in pagina si se doreste un raport al posibilelor
probleme din pagina respectiva. Folosind SoftAssert testul va
esua daca cel putin un assertion este Failed, dar va fi executat
pana la final.
Mesajul de failure va contine o lista care cumuleaza toate
mesajele de failure ale assertion-urilor esuate.
Soft Asserts
@ Test
p u b lic void valid ateElem en ts() {
SoftAssert softAssert= n ew S oftA ssert();
LoginPage login= n ew Log in Pag e(d river).g et();
softAssert.assertTrue(login.userBox.isD isplayed(), "U ser input box not visible");
softAssert.assertTrue(login.passBox.isD isplayed(), "Passw ord input box not visible");
softAssert.assertFalse(login.signInBtn.isEnabled(), "SignIn btn should not be
enabled");
softAssert.assertAll();
}
TestNG providers
TestNG face usoara folosirea DataProviders prin comparatie cu
jUnit. Daca vrem sa repetam un test cu mai multe seturi de date,
trebuie doar sa avem in clasa o metoda care returneaza un array
bidimensional care contine datele de test. In exemplul urmator,
testul verifica un set de parole care nu respecta regulile site-ului,
validand aparitia mesajului de eroare.
In final, rapoartele vor indica un numar de teste egal cu numarul
elementelor din array-ul de date.
TestNG providers
@ Test(dataProvider = passw ords")
p u b lic void p assw d R u les(S trin g u ser, S trin g p assw d ) {
Login login= n ew Log in (d river).g et();
login.typeU ser(u ser).typePassw ord(p assw d );
Assert.assertTrue(login.hasValidationError());
}
@ D ataProvider
p u b lic O b ject[][] p assw ord s() {
retu rn n ew O b ject[][] { { vicu s", q b ad " } ,
{ _user", @ 1bad" } };
}
Questions?
@ Test

p u b lic void w aitForQ u estion (){

//w aiting for questions

n ew W eb D riverW ait(d river, 300).u n til(n ew Exp ected C on d ition < B oolean > (){

p u b lic B oolean ap p ly(W eb D river arg 0) {

retu rn q u estion s.an sw ered () || n extS p eaker.isH ere();

}});

};

Вам также может понравиться