Você está na página 1de 7

page objects_

PAGE OBJECTS
Organizando seus Testes Funcionais
!"#$%&!#'%#($#)*'"+!#'%#,%-&./
AUMENTANDO A MANUTENIBILIDADE DE TESTES FUNCIONAIS ATRAVÉS DA ORIENTAÇÃO A OBJETOS.

Testes são parte fundamental do processo de desenvolvimento de


software. Testes são criados com o objetivo de garantir que os re-
quisitos funcionais de um sistema são atendidos. Contudo, testar
a interface de uma aplicação (especialmente Web) não é algo tri-
vial. Ferramentas, como o Selenium, foram criadas com o objetivo
de automatizar o processo de reprodução das ações de navegação
em uma aplicação. O problema é que estas ferramentas automati-
zadas nem sempre geram um código simples de se manter. Como
solução para este problema, apresentamos o design pattern Page
Object que tem como objetivo aplicar as técnicas da programação
orientada a objetos aos testes funcionais.

!"#$%&'"()"%$*#)*%)+,(-"."/(0$''1#)2"3)')*#$2#)+" 0+$;2)(,7" ],($'" 3)5,2E,+" $" 3)'/>*" 0,55)+*" D,>)" R;-


O '$456,+)"')("5)'5)'7"8*59$"%$()%)/","2)+")"3)#$+,+"
5:3$"'$;+)"$",'':*5$7"<)'5)'"3)":*/3,3)!"5)'5)'"4:*%/$-
S)%5'"UDRV"A:)"5)("%$($"$;S)5/#$",02/%,+",'"5.%*/%,'"3,"
0+$>+,(,=9$" $+/)*5,3," ," $;S)5$'!" +):',;/2/3,3)" )" )*-
*,/'!"5)'5)'"3)",%)/5,=9$!"5)'5)'"3)"',*/3,3)7"8"()",>+,- %,0':2,()*5$!",$'"5)'5)'"4:*%/$*,/'"3)":(,",02/%,=9$7
3$:","/3)/,"3)",:5$(,5/?,+"5$3,'")'5,'"5,+)4,'",5+,#.'"
3)":(,"4)++,()*5,"3)"/*5)>+,=9$"%$*51*:,7 Testes de Interface com o Usuário (UI)
@,'"3)'%$;+/"A:)"5)'5,+","/*5)+4,%)"B);"*9$"."59$" 8*5+)" (:/5,'" )A:/0)'" 3)" 3)')*#$2#/()*5$" 3)" '$4-
4C%/2"A:,*5$")'%+)#)+"5)'5)'"3)":*/3,3)7"D)'A:/')/"(:/- 56,+)!" 5)'5)'" 3)" ^')+" G*5)+4,%)" U^GV" 0$'':)(" :(," 5+)-
5$")"()")(0$2>:)/"%$(":(,"4)++,()*5,"%E,(,3,"F)- ()*3,"(C"+)0:5,=9$-"%P3/>$'"3/41%)/'"3)"(,*5)+!"%,+$'!"
2)*/:(" GH87"I" ':," 4,%/2/3,3)" 3)" /*'5,2,=9$" )" >+,#,=9$" (,2" )'%+/5$'" )!" 0+/*%/0,2()*5)!" ,25,()*5)" ,%$02,3$'7"
3)" 5$3$'" $'" J:K$'" 3," (/*E," ,02/%,=9$" 4,%/2/5,+,(" )(" I+>:()*5$'" 4$+5)'" $" ':Z%/)*5)" 0,+," ,2>:(,'" )A:/0)'"
(:/5$"$"5+,;,2E$7" '/(02)'()*5)",;$2/+)("5)'5)'"3)"^G",:5$(,5/?,3$'7
D$+.(" %$(" $" 5)(0$" ,2>$" %$()=$:" ,"L*9$" %E)/+,+" D,+5)" 3)'5," +)0:5,=9$" ." S:'5/Z%,3," 0)2$" 4,5$" 3)"
;)(M7"N,0/3,()*5)"$"*O()+$"3)"5)'5)'"%$()=$:","%+)'- A:)")'5)'"5)'5)'">)+,2()*5)"'9$">)+,3$'",5+,#.'"3)"4)+-
%)+" )" 0)+%);/" A:)" ," +)0)5/=9$" 3)" %P3/>$" )+," %$*'5,*5)" +,()*5,'" 3)" ,:5$(,=9$7" _)+,+" 5)'5)'" 0$+" )'5,'" 4)++,-
)(" %,3," 5)'5)7" @,'" )'0)+)" :(" ($()*5$Q" R*3)" )'5C" ," ()*5,'".":(,"5,+)4,"'/(02)'-";,'5,"%2/%,+")"*,#)>,+"*,"
4,($',"R+/)*5,=9$","R;S)5$'"A:)"5,*5$")'5:3)/T"8"%$($" ,02/%,=9$")"':,'",=`)'"Z%,("+)>/'5+,3,'7"Y$*5:3$!")'5,'"
)K02/%,+"0,+,",2>:.("U0+/*%/0,2()*5)"():">)+)*5)V"A:)" 4)++,()*5,'!"%$($"A:,2A:)+">)+,3$+",:5$(C5/%$"3)"%P-
,"(:3,*=,"3)":("%,(0$"3,"5)2,"/(02/%,"+))'%+)#)+"WX" 3/>$!" *9$" '9$" %,0,?)'" 3)" >)+,+" :(" 3)'/>*" ':'5)*5C#)2"
5)'5)'T"Y$($")K02/%,+"A:)"5:3$"Z%$:"59$"3/41%/2"3)"(,*- 3)"'$456,+)!"$"A:)",%,;,"5$+*,*3$","(,*:5)*=9$"3)'5)'"
5)+"U)"%,+$VTM 5)'5)'":(,"5,+)4,"C+3:,")"%,+,7
[)'5)" ,+5/>$!" )'0)+,($'" ,S:3C\2$" ," +)'$2#)+" )'5)" D$+" $:5+$" 2,3$!" $" 0,+,3/>(," 3," R+/)*5,=9$" ," R;-

/ 46
Eder Ignatowicz | @ederign
Doutorando em Engenharia Elétrica na Unicamp,
é mestre em Engenharia Elétrica pela Unicamp (2009)
e formado em Ciência da Computação pela Universidade
Estadual de Londrina (2007). Atualmente é engenheiro de
Software na Dextra Sistemas e leciona diversos cursos de
graduação e pós-graduação na Faccamp e Unisal e editor do
InfoQ Brasil.

Leandro Guimarães | @leguimas


Biólogo formado pela Unicamp (2007) e técnico em Processamento
de Dados formado pelo Colégio Técnico da Unicamp (1999). Atua com de-
senvolvimento de software há 11 anos sendo 8 deles com Java. Atualmente,
é engenheiro de Software na Dextra Sistemas.

S)5$'" 4$/" %+/,3$!" 3)*5+)" =9$7"@:3,*=,'"*,"/*5)+4,%)"*9$"+)A:)+)("($3/Z%,=9$"


$:5+$'" ($5/#$'!" 0,+," 4,- *$"%P3/>$"3$'"5)'5)'7"I0)*,'"$"%P3/>$"3$"D,>)"R;S)%5!"
#$+)%)+" ," (,*:5)*/;/2/3,3)" A:)")*%,0':2,")'5,"/*5)+4,%)!"."($3/Z%,3$"%+/,*3$":("
3$" '$456,+)7" I" (,*:5)*/;/2/3,3)" 0$*5$"O*/%$"3)"(:3,*=,"*$"'):"%P3/>$7
3)" :(" 0+$3:5$" $:" '/'5)(," +)4)+)\')" H)'5," 4$+(,!" 0$3)($'" +)':(/+" $'" 0$*5$'\%E,#)'"
a" 4,%/2/3,3)!" ')>:+,*=," )" )%$*$(/," *," 3)'5)"0,3+9$"3,"')>:/*5)"4$+(,-
(,*:5)*=9$"3)'5)"'/'5)(,"$:"0+$3:5$7"8("'$456,+)!"," » Encapsulamento de detalhes da implementação:
3/5,"(,*:5)*/;/2/3,3)"3)":("'/'5)(,",#,2/,","4,%/2/3,3)" %2,+,"')0,+,=9$")*5+)"$"%P3/>$"3$'"5)'5)'")","%,-
3)",25)+,=9$"3$"'$456,+)"0,+,"+)'$2:=9$"3)":(";:>"$:" (,3,"3)"#/'9$7"R"%P3/>$"3)":("5)'5)!"0$+")K)(-
/*%2:'9$"3)":("*$#$"+)A:/'/5$7 02$!"*9$"0+)%/',"')"0+)$%:0,+"*,"4$+(,"A:)"."3/'-
I" :*/9$" 3$'" %$*%)/5$'" 3)" R+/)*5,=9$" ," R;S)5$'" a" 0,+,3,"3)5)+(/*,3,",=9$"*$"'/'5)(,!"%$($!"0$+"
+),2/3,3)" 3," ,:5$(,=9$" 3$'" 5)'5)'" 4$/" /3),2/?,3," 0)2$" )K)(02$!"*9$"*)%)''/5,"/3)*5/Z%,+"$")2)()*5$","
0+$S)5$" B);" H+/#)+" U$+/>)(" 3$" 0+$S)5$" F)2)*/:(V7" R'" ')+"%2/%,3$"*,"5)2,"0,+,"A:)":(,",=9$"')S,"3/'0,-
3)')*#$2#)3$+)'";:'%,#,(":(,"(,*)/+,"3)"+)0+)')*- +,3,7"D,+,"$"%P3/>$"3)"5)'5)!";,'5,"A:)",")K)%:=9$"
5,+" U)" )*%,0':2,+V" ," /*5)+,=9$" )*5+)" :(," ,02/%,=9$" )" *$"'/'5)(,"')S,"3/'0,+,3,7"I;'5+,/*3$"3)'5,"4$+-
:':C+/$",5+,#.'"3)"$;S)5$'"A:)"5+$%,("()*',>)*'")*5+)" (,!" ,5+,#.'" 3$'" D,>)" R;S)%5'!" )*%,0':2,($'" $'"
'/7"H)'5,"/3)/,")()+>/:"$"0,55)+*"D,>)"R;S)%57 3)5,2E)'"3)"/(02)()*5,=9$"3,"%,(,3,"3)"#/'9$!"
0+$#)*3$" ,$" %P3/>$" 3$'" 5)'5)'" (.5$3$'" ,(/>C-
Utilizando Page Objects #)/'")"3)"4C%/2":5/2/?,=9$"UZ>:+,"WV7
^(" D,>)" R;S)%5" ." :(" $;S)5$" A:)" +)0+)')*5," :(," » Métodos representam serviços: )K/'5)":("%,(/*E$"
0C>/*," )'0)%1Z%," 3)" :(," ,02/%,=9$7" R'" 5)'5)'" /*5)+,- O*/%$"3)"%$(:*/%,=9$")*5+)",'"%2,'')'"3)"5)'5)'"
>)(" %$(" ," ,02/%,=9$" )K%2:'/#,()*5)" ,5+,#.'" 3$'" (.- )","%,(,3,"3)"#/'9$"3,",02/%,=9$7"H)'5,"4$+(,!"."
5$3$'"0O;2/%$'"3$"D,>)"R;S)%5",$"/*#.'"3)"/*5)+,>/+"3/- >)+,3$":("O*/%$"0$*5$"3)"(:3,*=,",$"/*#.'"3)"
+)5,()*5)"%$(","%,(,3,"3)"#/'9$"U#/)6V"3,",02/%,=9$7" %P3/>$"3)",%)''$","#/)6")'0,2E,3$"0)2$'"5)'5)'7
R"%2,+$";)*)41%/$"3)'5,",;$+3,>)("."$";,/K$",%$- » !"#$!%&'()*+ ,'+ !-./01'&/2" $" $;S)5$" +)0+)')*5,"
02,()*5$")*5+)","%,(,3,"3)"#/'9$")"$'"5)'5)'"3,",02/%,- ,0)*,'" ," 0,+5)" 3," 0C>/*," *)%)''C+/," ,$'" 5)'5)'!"

Figura 1. Representação do pattern Page Object: as páginas de busca do Google são representadas por objetos PageObject que forne-
cem métodos públicos, encapsulando os detalhes para manipulação da página e disponibilizando o acesso aos diversos testes que a
utilizam.

47 \
3/(/*:/*3$","%$(02)K/3,3)"3$"3)')*#$2#/()*5$7"
» Métodos retornam outros Page Objects: ,$")K)%:- @Test
5,+":("(.5$3$"3)":("D,>)"R;S)%5!"$"(.5$3$"0$3)" public void testaBuscaSeleniumTest() {
+)5$+*,+"$:5+$"D,>)"R;S)%57"D$+")K)(02$-",$"',2- PaginaDeBusca paginaDeBusca =
#,+":("%,3,'5+$"3)":("%2/)*5)!",5+,#.'"3$"(.5$3$" PaginaDeBusca.acessa(driver);
D,>/*,G*%2:',$H)Y2/)*5)7',2#,+Y,3,'5+$UV!" #$%&" PaginaDeResultadoDaBusca
+)%);)!" %$($" +)5$+*$!" :(," /*'5b*%/," 3)" D,>/*,- paginaDeResultadoDaBusca =
Y$*':25,H)Y2/)*5)'7" H)'5," 4$+(,!" ." 0$''1#)2" %$- paginaDeBusca.realizaBusca(
*E)%)+" $" J:K$" 3," ,02/%,=9$" ,5+,#.'" 3," /*5)+,=9$" “selenium test”);
)*5+)"$'"$;S)5$'7 Assert.assertTrue(paginaDeResultadoDaBusca
R:5+$" 0$*5$" /(0$+5,*5)" *," :5/2/?,=9$" 3$" D,>)R;- .encontrouSite(“seleniumhq.org”));
S)%5"."A:)"#$%&"0$3)")'%+)#)+"'):"%P3/>$"3)":(,"4$+(," }
(,/'" 2)>1#)27" 8" A:,/'" '9$" $'" +),/'" ;)*)41%/$'" 3)'5," 0+)-
$%:0,=9$T" ^(" %P3/>$" 2)>1#)2" ." *)%)'',+/,()*5)" :(" @Test
%P3/>$" 3)" (,*:5)*=9$" '/(02)'" U(,*:5)*1#)2V7" ^(" %P- public void testaBuscaPageObjectPattern() {
3/>$" 2)>1#)2" 5$+*,\')!" 0$+" '/" 'P!" :(," 3$%:()*5,=9$" 3$" PaginaDeBusca paginaDeBusca =
'/'5)(,7"8'5)"O25/($"0$*5$!"/*%2:'/#)!"0$3)"')+",25,()*- PaginaDeBusca.acessa(driver);
5)" 0$5)*%/,2/?,3$" %$(" ," :5/2/?,=9$" 3," %$(;/*,=9$" D,- PaginaDeResultadoDaBusca
>)R;S)%5")"HFc"UH$(,/*"F0)%/Z%"c,*>:,>)V"$:",2>:(," paginaDeResultadoDaBusca =
4)++,()*5,"3)"dHH"Ud)E,#/$+"H+/#)*"H)'/>*V"')*3$!")(" paginaDeBusca.realizaBusca
(:/5$"%)*C+/$'!"':;'5/5:5$'"3$'"(.5$3$'"5+,3/%/$*,/'"3)" (“pageobject pattern”); Assert.assertT
3$%:()*5,=9$7 rue(paginaDeResultadoDaBusca
.encontrouSite(“code.google.com/p/sele
Implementando o padrão nium/wiki/PageObjects”));
^("0$*5$"/*5)+)'',*5)","')"$;')+#,+!"*$"D,>)"R;- }
S)%5!"."A:)"')"5+,5,"3)":("0,55)+*!"$:"')S,!"*9$")'5C",5+)- @AfterClass
2,3$","*)*E:(,"/(02)()*5,=9$")'0)%1Z%,7"D,+,"/2:'5+,+" public static void %-'$!3'4/5./5() {
':," :5/2/?,=9$" *)'5)" ,+5/>$!" :5/2/?,+)($'" $" 4+,()6$+ " driver.close();
F)2)*/:("Ue7fW;V"0,+,"g,#,7"[$")*5,*5$!"sua /3)/,"."#C2/- }
3,"0,+,"A:,2A:)+"2/*>:,>)(78++$-"R+/>)("3,"+)4)+&*%/," }
*9$")*%$*5+,3,7
Y$()=,+)($'" *$''$" )K)(02$" /(02)()*5,*3$" :(" R"A:)"')+/,(")'5)'"$;S)5$'"D,>/*,H)d:'%,")"D,>/-
5)'5)" 0,+," ," ;:'%," 3$" _$$>2)7" D)*')($'!" /*/%/,2()*5)!" *,H)N)':25,3$H,d:'%,T"I*5)+/$+()*5)"4$/"#/'5$"A:)"*$"
*$"J:K$"A:)"A:)+)($'"5)'5,+-"$":':C+/$"3/>/5,+C"$"5)+- 0,55)+*"D,>)R;S)%5":(,"0C>/*,"."+)0+)')*5,3,"0$+":("
($"L')2)*/:(M"*:(,"4)++,()*5,"3)";:'%,")"3)#)+C"$;5)+" $;S)5$"D,>)"R;S)%57"H)'5,"4$+(,!"A:,/'"')+/,(",'"0C>/*,'"
%$($" 0+/()/+$" +)5$+*$" $" 2/* " 0,+," $" '/5)" 3$" F)2)*/:(7" U$;S)5$'V")*#$2#/3,'")("*$''$"5)'5)T"I"0C>/*,"3)";:'%,"
8("$:5+$"5)'5)!"')+C"4)/5,",";:'%,"0,+,"$"5)+($"L0,>)"$;- )","0C>/*,"3)"+)':25,3$!"%$++)5$T"Y$++)5$Q"<,(;.("%$-
S)%5M" )" )'0)+,($'" +)5$+*,+" ," 6/ /" %$(" %$*5)O3$" '$;+)" ()*5,($'"A:)"$'"(.5$3$'"3$'"D,>)"R;S)%5'"+)0+)')*-
)'5)",'':*5$7 5,("')+#/=$'7"F)*3$",''/(!"A:,/'"')+/,("$'"')+#/=$'"A:)"
[)'')"%$*5)K5$!"5)+1,($'":(,"%2,'')"3)"5)'5)'"3)'5," :5/2/?,+)($'"*)'',"0C>/*,T"])S,($'","c/'5,>)("e7
4$+(,- Listagem 2. Implementação dos PageObjects refe-
Listagem 1. Classe que implementa o teste a ser execu- rentes à da Página de Busca e Resultado.
tado. public class PaginaDeBusca {
private static %-'$ String URL = “http://www.google.
public class TestaMecanismoBusca { com.br”;
private static WebDriver driver; private static %-'$ long WAIT_TIME = 2000l;
private WebDriver driver;
@BeforeClass
public static void preparaTestes() { private PaginaDeBusca(WebDriver driver) {
!"#$%&"'!()$*")%!"%+",$-,.%!+/)/!.%!($*")%.%! this.driver = driver;
// browsers. Nesse caso }
!0&$1$2/)"'.%!.!-)"3.#4 public static PaginaDeBusca acessa(
driver = new FirefoxDriver(); WebDriver driver) {
} // navega para a URL desta pagina
driver.navigate().to(URL);
// retorna uma nova instancia do objeto que
// representa a pagina da busca

/ 48
/eu uso
789!*+:!"'+ '-.*5+;+<5=5#>?"'!$@&*"
Desenvolvedor de Software, com 7 anos de experiência em projetos de desenvolvimento de sistemas cor-
porativos na plataforma Java Enterprise Edition e Ruby on Rails. Formado em Ciência da Computação
na Universidade de São Paulo/São Carlos, atuando ainda como consultor de arquitetura de sistemas e
instrutor de treinamentos.
^',+"5)'5)'"4:*%/$*,/'"0,+,">,+,*5/+"+)>+)''9$")("'/'5)(,'"%$+0$+,5/#$'"
%$(02)K$'",0$*5,"0,+,":("3)',Z$"3)"$+>,*/?,=9$")"+)O'$"3)"%2,'')'"3)"5)'5)7"
8(",2>:*'"%,'$'!","/(02)()*5,=9$"3)":("O*/%$"%)*C+/$"3)"5)'5)"0$3)"3)(,*-
3,+":(")'4$+=$"(:/5$">+,*3)"3)"3)')*#$2#/()*5$!",''/("%$($"3)(,*3,+/,"(:/5$'"%2/A:)'"*,"5)2,7"^',($'","
,;$+3,>)("3)"D,>)"R;S)%5'"%$("':%)''$")(":("0+$S)5$"3$"'/'5)(,"%$+0$+,5/#$"3)":(";,*%$"3)"%b(;/$!"0)+-
(/5/*3$"A:)"*$#$'"%)*C+/$'"3)"5)'5)"4$'')("/(02)()*5,3$'"+,0/3,()*5)")",:()*5,*3$"'/>*/Z%,5/#,()*5)"
,"%$;)+5:+,"3)"5)'5)'"3$"'/'5)(,7"H/,*5)"3,'"3/#)+','",25)+*,5/#,'"A:)"SC")K0)+/()*5)/"0,+,"$+>,*/?,=9$"3)"
5)'5)'" 4:*%/$*,/'!" )'5," ()" 0,+)%)" ," ,25)+*,5/#," (,/'" /*5:/5/#," 0,+," $" :':C+/$!" 0$''/;/2/5,*3$" A:)" $" *$''$"
D+$3:%5"R6*)+!"0$+")K)(02$!"%$*'/>,"2)+")"%$(0+))*3)+"$"%P3/>$"3$'"*$''$'"5)'5)'7

return new PaginaDeBusca(driver); public boolean encontrouSite(String


} urlSiteProcurado) {
// procura por todos os elementos li de classe
public PaginaDeResultadoDaBusca // css g que estiverem dentro de um div de id res
realizaBusca(String conteudoDaBusca) { List<WebElement> itensEncontrados =
// escreve o valor de conteudoDaBusca em um driver.%-,6$/"/-.5(By
!!!!!!!! !"1"'"5&.!$("5&$-,/(.!+"1.!5.'"!6 .cssSelector(“div#res li.g”));
driver.%-,6$/"/-.(By.name(“q”)).sendKeys( boolean elementoEncontrado = false;
conteudoDaBusca); for (WebElement itemEncontrado :
!($%+/)/!.!,1$,7!"'!0'!"1"'"5&.!$("5&$-,/(.! itensEncontrados) {
// pelo nome btnG // obtem o conteudo de um elemento cite
driver.%-,6$/"/-.(By.name(“btnG”)).click(); // dentro de cada item encontrado
try { String linkDoElementoEncontrado =
// aguarda um tempo ate a pagina do itemEncontrado.%-,6$/"/-.(By.tagName(
// resultado de busca ser carregada “cite”)).getText();
Thread.sleep(WAIT_TIME);
} catch (InterruptedException e) { elementoEncontrado =
throw new RuntimeException(“Can not wait linkDoElementoEncontrado.contains
for page to load.”, e); (urlSiteProcurado);
}
// retorna um novo objeto que representa a if (elementoEncontrado) {
// pagina do resultado da busca break;
return new PaginaDeResultadoDaBusca(driver); }
} }
} return elementoEncontrado;
//--------------- }
public class PaginaDeResultadoDaBusca { }
private WebDriver driver;

public PaginaDeResultadoDaBusca( R"B);H+/#)+"."$"+)'0$*'C#)2"0$+"0+$#)+","*,#)>,=9$"


WebDriver driver) { *$";+$6')+!";)("%$($"+),2/?,+","(,*/0:2,=9$"3$'"3,3$'"
this.driver = driver; 3," 0C>/*," )K/;/3," )(" 5)2,7"],2)" %$()*5,+" A:)" )K/'5)("
} /(02)()*5,=`)'"3)'5)"3+/#)+"+)0+)')*5,*3$"$'"(,/'"3/-
#)+'$'";+$6')+'")K/'5)*5)'7"I>$+,!"0)+%);,"%$($",'"%2,'-

49 \
/eu uso
A0=-*+B90/=+;+90=-*@'90/=>5*%5.@&*"@90
!"#$%"&$'()!(%&)*&+%,-$.&#/0"#-*&#-0#(!*1!2*3*&#/&$#-$#-&#&45*1!3*3#&3#&-%6$7*"#8&9&/#-$"#&#/&:!;)(!*&
da Computação pela Unicamp e bacharel em Ciência da Computação pela UFMG. Na Receita Federal
3%&<"*-!1.&*$5%5&)*&65)=>%&3#&?#"#)$#&3#&$#-$#-&3#&5/*&#45!0#&!)3#0#)3#)$#&3#&@#"!,(*=>%&#&@*1!3*=>%&
(V&V). Participa ativamente do curso de especialização em Engenharia de Software da Unicamp desde
ABBC.&#-0#(!,(*/#)$#&)*-&3!-(!01!)*-&3#&@D@&#&E*)5$#)=>%8&E!)!-$"*&0*1#-$"*-&#&$"#!)*/#)$%-&-%F"#&
temas relacionados a testes e qualidade de software em instituições e eventos, e possui uma série de
publicações nacionais e internacionais relacionadas.
gC":5/2/?,($'"EC",2>:*'",*$'"$"0,3+9$"D,>)R;S)%5"*,"F$Z'57"R"0,3+9$".")K-
5+)(,()*5)"0$3)+$'$!"5$+*,*3$","(,*:5)*/;/2/3,3)"3$'"5)'5)'":(,",5/#/3,3)"
'/(02)'")!"*,"(,/$+/,"3$'"%,'$'!"3/#)+5/3,")"0+,?)+$',7"]$%&"0$+",%,'$"SC"/(,>/*$:"%$++/>/+"(,/'"3)"W7Xff"
%,'$'"3)"5)'5)",:5$(,5/?,3$'")4)5:,*3$","/*%2:'9$"3)"5+&'"2/*E,'")(":(,"%2,'')T"
Y)+5,()*5)",A:/")'5$:"%$()*5,*3$"'$;+)"$'",'0)%5$'"L3/#)+5/3$'")"0+,?)+$'$'M7"I">)'59$"3,'"(:3,*=,'"
*$'"#C+/$'"%$(0$*)*5)'"3,'"5)2,'"%E)>,","')+"5+/#/,2!"3)'3)"A:)"$":':C+/$"5)*E,"%:/3,3$"*$"($()*5$"3)"
)'5+:5:+,+"'):'"%$(0$*)*5)'7"_$'5,+/,"3)"%$(0,+5/2E,+",2>:*'"3,3$'"/*5)+)'',*5)'"%$("$'"2)/5$+)'7"8(":("
3$'"0+$S)5$'"*$"A:,2",02/%,($'")'5)"3)'/>*"0,55)+*!"$'"+)':25,3$'"$4)+)%)+,(",$"%2/)*5)"0)2$"()*$'"hfi"3)"
)%$*$(/,"3)#/3$"a",3$=9$"3$"0,3+9$7"8("$:5+$"0+$S)5$!"$*3)"SC"E,#/,"(,/'"3)"hff"%,'$'"3)"5)'5)'",:5$(,-
5/?,3$'"%$("$"F)2)*/:(!"0+$0$+%/$*,($'"+)3:=9$"(.3/,"3)"jfi"*$")'4$+=$"0,+,"(,*:5)*=9$"3$'"5)'5)'7"
[)'5)"%,'$!"3)#$"%$()*5,+"A:)"$"'$456,+)")("A:)'59$"'$4+/,",25)+,=`)'"A:,')"A:)"3/C+/,'")("':,'"5)2,'")"
%$(0$*)*5)'7"8'5)".":("3$'"0,3+`)'"A:)"+)%$()*3$","A:,2A:)+"0)''$,"A:)"0)*')")(",3/%/$*,+",:5$(,5/-
?,=9$"3)"5)'5)'"4:*%/$*,/'"a"':,"L%,/K,"3)"4)++,()*5,'M7

')'"+)0+)')*5,(!")4)5/#,()*5)!","0C>/*,"A:)"#)($'",$" public PaginaBase(WebDriver driver) {


+),2/?,+"$"()'($"0+$%)''$"(,*:,2()*5)78++$-"R+/>)(" this.driver = driver;
3,"+)4)+&*%/,"*9$")*%$*5+,3,7 }
"D)+%);,","4,%/2/3,3)"3)"2)/5:+,"3$"5)'5)7"N)0,+)"5,(- protected void preencheInputText(String
;.("A:)!")'5+:5:+,*3$",'"0C>/*,'"3)'5,"4$+(,"U:5/2/?,*- cssSelector,
3$" D,>)R;S)%5'V!" %$*')>:/($'" +)0)5/+" $" 5)'5)" 3/#)+','" String conteudo) {
#)?)'!"(,'":5/2/?,*3$"%)*C+/$'"3/4)+)*5)'7"8'5,($'":':- WebElement inputText = driver.%-,6$/"/-.(
4+:/*3$"3$"0$3)+"3,"+):',;/2/3,3)!":("/(0$+5,*5)"%$*- By.cssSelector(cssSelector));
%)/5$"*,"$+/)*5,=9$","$;S)5$7"8++$-"R+/>)("3,"+)4)+&*%/," inputText.clear();
*9$")*%$*5+,3,!"(,'",/*3,"EC"$"A:)"()2E$+,+"*)'')"%)- inputText.sendKeys(conteudo);
*C+/$!"*9$"ECT"D)+%);,"A:)!"0,+,"5$3,"%2,'')"3)"0C>/*," } protected void clica(String cssSelector) {
A:)" %+/,($'!" 5)($'" A:)" 3)Z*/+" :(" B);H+/#)+7" I2.(" driver.%-,6$/"/-.(By.cssSelector(cssSelector)).
3/''$!"*$'"$;S)5$'"3)"0C>/*,'!":':4+:/($'"3$'"+)%:+'$'" click();
3$"B);3+/#)+"A:)!"*)("')(0+)!"'9$"59$"2)>1#)/'"A:,*5$" try { // aguarda um tempo ate a pagina do
3)')S,+1,($'7" resultado
F)+C"A:)")'5)'"%$()*5C+/$'")K02/%,*3$"$"A:)"*$''$" // de busca ser carregada
%P3/>$"4,?"'9$"*)%)''C+/$'T"F)":("%P3/>$".";)(")'%+/5$" Thread.sleep(WAIT_TIME);
%$()*5C+/$'" *9$" '9$" +)0)5/=9$" 3$" %P3/>$" )'%+/5$T" 8" ')" } catch (InterruptedException e) {
,(,*E9"4$+"($3/Z%,3,","(,*)/+,"3)"/*')+/+"$"%$*5)O3$" throw new RuntimeException(
)(":("/*0:5"5)K5!"0$+")K)(02$T"D$3)($'"*$'":5/2/?,+"3$" “Nao foi possivel esperar a pagina ser
0$3)+" 3," E)+,*=," )" 3$" )*%,0':2,()*5$" 0,+," ()2E$+,+" carregada.”, e);
)'',"'/5:,=9$" }
}
Listagem 3. Refactoring dos Page Objects e da classe de protected List<WebElement> buscaPorElementos(
testes. String cssSelector) {
public abstract class PaginaBase { return driver.%-,6$/"/-.5(By.cssSelector(
private static %-'$ long WAIT_TIME = 2000l; cssSelector));
protected WebDriver driver; }

/ 50
public abstract String getURL();
}
//--------------- /para saber mais
public class PaginaDeBusca extends PaginaBase {

private static %-'$ String INPUT_BUSCA = !"#$$%&#'(%)!*#!+#)(#)!,-(.&%(/0%*.)!1!23!45


“input[name=q]”;
!6-%7/*%*#!,($%89)!*#!+#)(#)!"-':/.'%/)!:.&!;#7#'/-&<!
private static %-'$ String BOTAO_DE_BUSCA = 3=#>%8#<!2%8#'!#!?'(#@$%AB.!C.'(D'-%!1!23!4E
“input[name=btnG]”;
!=#>%8/.$FG$/8#'!G#8#7.H&#'(!#&!3%8%!'%!H$I(/:%<!:.&!
3=#>%8#!1!23!44
public PaginaDeBusca(WebDriver driver) {
super(driver); !+#)(#)!*#!J'/*%*#!H%$%!C%&%*%)!*#!,H$#)#'(%AB.!'.!
} 2-'*.!K#%7!1!23!LE

public static PaginaDeBusca acessa(WebDriver driver)


{
PaginaDeBusca paginaDeBusca =
protected void acessaPagina() {
driver.navigate().to(this.getURL()); private void entaoMecanismoDeBuscaEncontraSite(
} String siteEsperado) {
Assert.assertTrue(paginaDeResultadoDaBusca.
encontrouSite(siteEsperado));
new PaginaDeBusca(driver); }
paginaDeBusca.acessaPagina(); @AfterClass
return paginaDeBusca; public static void !"#$%"&'()'(() {
} driver.close();
}
quandoUsuarioProcuraPor(“selenium test”); }
entaoMecanismoDeBuscaEncontraSite(
“seleniumhq.org”); ! "#$! %&$'()*! +(! $,$'-.(! /01'/*! 2(1! 031/3! #'/!
} 0./))$!/4)53/5/!06/'/7/!8/91+/:/)$!"#$!$+0/-)#./!;<-
@Test 31()!0('-(35/'$+5()!$!/5314#5()!0('#+)!/!5(7/)!/)!-<-
public void testaBuscaPageObjectPattern() { 91+/)!"#$!#51.1&/'()!$'!+())(!5$)5$=!>(+)$9#1'()*!+$)-
dadoQueUsuarioAcessaMecanismoDeBusca(); 5$! 0/)(*! /4)53/13! /1+7/! '/1)! +())(!'$0/+1)'(!$!7$1,/3!
quandoUsuarioProcuraPor(“pageobject pattern”); +())(!0?719(!/1+7/!'/1)!.$9@;$.=!A.B'!71))(*!3$$)03$;$-
entaoMecanismoDeBuscaEncontraSite( '()!+())()!5$)5$)!$'!#'/!$)53#5#3/!)1'1./3!C)!$)53#5#-
“code.google.com/p/selenium/wiki/ 3/)!#51.1&/7/)!-(3!23/'$D(3E)!:FF=
PageObjects); !"#$!/0(+5$0$3<!)$*!)$G/!-$.(!'(51;(!"#$!2(3*!51;$3-
} '()!"#$!53(0/3!(!H((9.$!-$.(!:1+9!0('(!'$0/+1)'(!7$!
4#)0/I!J'!"#/1)!-(+5()!)$3<!+$0$))<31(!'$,$3!+/!+())/!
$)53#5#3/!7$!5$)5$)I!J,/5/'$+5$!1))(!"#$!;(0K!-$+)(#L!
/-$+/)!+/)!+())/)!-<91+/)*!+()!+())()!8/9$ 4G$05!
private void
dadoQueUsuarioAcessaMecanismoDeBusca() {
paginaDeBusca = PaginaDeBusca.acessa(driver);
}
/referências
private void quandoUsuarioProcuraPor(String
conteudo) {
paginaDeResultadoDaBusca = !"#$%&'(!)*+,-.!)#&,'.,/!0$1.%2#,3!(4&/,/!*5!.,6.6!7$#!
paginaDeBusca.realizaBusca(conteudo); 0.,8,!9#,,:2'!2'/!;2.!<#5-,
}
<2(,!$*+,-.6!=..7>??-$/,@($$(A,@-$:?7?6,A,'&4:?%&B&?
<2(,)*+,-.6

51 \
Listagem 6. !"#$%&'"!()*%&'#+)!("*(,-+%&. itemEncontrado.getText().replaceAll(“ “, “”);
elementoEncontrado =
public class PaginaDeBusca extends PaginaBase { linkDoElementoEncontrado.contains(
private static !"# String INPUT_BUSCA =
“input#sb_form_q”; urlSiteProcurado);
private static !"# String BOTAO_DE_BUSCA =
“input#sb_form_go”;
!5$)5$!"#$!6/;@/'()!1'-.$'$+5/7(!%0(#!1+5/05(*!
public PaginaDeBusca(WebDriver driver) { $,/5/'$+5$!0('(!2(1!$)0315(!(3191+/.'$+5$=!M(!$+5/+5(*!
super(driver); '#7/'()*!-(3!0('-.$5(*!(!'$0/+1)'(!7$!4#)0/!#51.1&/-
} 7(=!N!0./3(!"#$!#51.1&/'()!#'!$,$'-.(!4/)5/+5$!)1'-.$)!
-/3/!1.#)53/3!(!#)(!$!()!9/+6()!7(!8/9$ 4G$05=!8(7$3@/-
public static PaginaDeBusca acessa(WebDriver driver) '()!#51.1&/3!$))$!5$)5$*!-(3!$,$'-.(*!-/3/!3$/.1&/3!#'/!
{ -$"#$+/!-3(;/!7$!0(+0$15(!(#!#'/!43$;$!/+<.1)$!7$!1'-
PaginaDeBusca paginaDeBusca = -/05(! +/! 53(0/! 7(! '$0/+1)'(! H((9.$! -$.(! '$0/+1)'(!
new PaginaDeBusca(driver); :1+9=
paginaDeBusca.acessaPagina(); 8(3B'*!$,53/-(.$'()!#'!-(#0(!$))$!$,$'-.(*!53/-
return paginaDeBusca; &$+7(O(!-/3/!/!3$/.17/7$!7$!)(25D/3$=!P'/91+$!"#$!;(0K!
} 5$+6/! QR! 0$+<31()! 7$! 5$)5$)! $+01'/! 7$! #'/! 2#+01(+/-
.17/7$! 0('-.$,/! $! 1'/91+$! 5/'4B'! "#$*! $'! #'! -/))(!
0('#'!/!5(7()!$)5$)!0$+<31()*!2(1!+$0$))<31(!/.5$3/3!#'!
3$"#1)15(L! 1+0.#13! #'! 0/'-(! (#! /.5$3/3! #'! 0/'-(=! F$-
public PaginaDeResultadoDaBusca
)$)-$3(IS!MT(S!F$;17(!/(!$+0/-)#./'$+5(!$!4/1,(!/0(-
realizaBusca(String conteudoDaBusca) {
-./'$+5(*!4/)5/31/!;(0K!/7$"#/3!(!8/9$ 4G$05!+(!"#/.!(!
this.preencheInputText(INPUT_BUSCA,
-/))(!2(1!'(71%0/7(=
conteudoDaBusca);
P'/91+$*! 5/'4B'*! "#$! ;(0K! -3$01)/*! $'! #'! 7$5$3-
this.clica(BOTAO_DE_BUSCA);
'1+/7(! 0$+<31(*! 0('(! -3$0(+71UT(! -/3/! )#/! $,$0#UT(*!
return new PaginaDeResultadoDaBusca(driver);
$,$0#5/3! #'! -/))(! "#$! ;(0K! G<! 5$'! 1'-.$'$+5/7(! $'!
}
(#53(! 5$)5$=! V(0K! 0(+)$9#13<*! '#15(! 2/01.'$+5$*! 06/-
'/+7(! (W)X! 8/9$ 4G$05W)X! $+;(.;17()! +/! )#/! -3$0(+71-
@Override
UT(!-/3/!)$3$'!$,$0#5/7()!$*!/))1'*!;(0K!0(+)$9#13!7$-
public String getURL() {
)$+;(.;$3!)$#!0$+<31(!7$!5$)5$)=
return “http://www.bing.com.br”;
}
} *+!($,'-"./'(0 !"$(0
//--------------- Y$)5$)!/#5('/51&/7()!)T(!#'/!$,0$.$+5$!2$33/'$+-
public class PaginaDeResultadoDaBusca extends 5/!-/3/!(!7$)$+;(.;1'$+5(!7$!)(25D/3$=!>('!5$)5$)!/#-
PaginaBase { 5('/51&/7()!9/3/+51'()!"#/.17/7$!1+5$3+/!$!$,5$3+/!7(!
private static !"# String LISTA_DE_RESULTADO = )(25D/3$=!A53/;B)!7$!5$)5$)!/#5('/51&/7()!0(+)$9#1'()!
“div#results li cite”; )$9#3/+U/! $! 0(+2(35(! -/3/! $;(.#13! 0(+)5/+5$'$+5$! #'!
)(25D/3$L!)$G/!+/!0(33$UT(!7$!4#9)*!+/!/.5$3/UT(!7$!3$-
public PaginaDeResultadoDaBusca(WebDriver driver) "#1)15()!(#!+/!3$$)53#5#3/UT(!7$!0?719(=
{ M(!$+5/+5(*!/!$)53#5#3/!7$!5$)5$)!7$)$+;(.;17/!$'!
super(driver); #'!-3(G$5(!-3$01)/!)$3!2$15/!7$!'(7(!"#$!)$G/!-())@;$.!
} '/+5$3!$!#)#23#13!7$!5/.!$)53#5#3/!$!+T(!/-$+/)!0/33$9<-
O./!0('(!#'!2/37(L!ZJ!/9(3/I!83$01)/'()!'$,$3!+()!5$)-
public boolean encontrouSite(String urlSiteProcurado) 5$)=[! (#!ZMT(! ;/'()! 2/&$3! 1))(! -(3"#$! ;/1! "#$43/3! #'!
{ '(+5$!7$!5$)5$)S!F$1,/!/))1'!0('(!$)5<L!+T(!$)5<!4('*!
List<WebElement> itensEncontrados = '/)!3$)(.;$=[!(#!(!-1(3!0$+<31(!ZV/'()!7$1,/3!()!5$)5$)!
"#$43/+7(!-(3!$+"#/+5([=
this.buscaPorElementos(LISTA_DE_ 8/9$ 4G$05!)#39$!0('(!#'!-/55$3+!"#$!;$'!/G#7/3!
RESULTADO); /! 3$)(.;$3! $)5/)! "#$)5\$)! $'! 5$)5$)! 2#+01(+/1)! "#$! )1-
boolean elementoEncontrado = false; '#./'!/!1+5$3/UT(!7$!#)#<31()!0('!(!)1)5$'/=!>(+5#7(!
for (WebElement itemEncontrado : 8/9$ 4G$05!3$-3$)$+5/!/-$+/)!#'/!7/)!1+]'$3/)!2$33/-
itensEncontrados) { // obtem o conteudo '$+5/)*!$)53/5B91/)!$!-/73\$)!-/3/!/#'$+5/3!/!"#/.17/-
de um elemento cite 7$!7(!)$#!7$)$+;(.;1'$+5(=
// dentro de cada itemencontrado
String linkDoElementoEncontrado =

/ 52

Você também pode gostar