Você está na página 1de 38

UI Testing with Selenium and Robot Framework

Ed Manlove irc: t55e devP PlTw!veri"on#net

Follow along at

github#com$emanlove$%se&'(&

github.com/emanlove/pse2012 Unit Testing Integration Testing Functional Testing )cce%tance Testing

github.com/emanlove/pse2012 Unit Testing Integration Testing Functional Testing )cce%tance Testing


Testing the User Inter*ace +UI,

github.com/emanlove/pse2012

.anguage
P thon 3avascri%t 6M. 8TM. /SS ###

/ode .ines
&051025 (&(1445 52107' (&1425 2195& ###

Source: :hloh#net

.anguage
P thon 3avascri%t 6M. 8TM. /SS
###

/ode .ines
&051025 (&(1445 52107' (&1425 2195&
###

&2 ;

Source: :hloh#net

.anguage
P thon 3avascri%t 6M. 8TM. /SS
###

/ode .ines
&051025 (&(1445 52107' (&1425 2195&
###

($&

Source: :hloh#net

Source: :hloh#net

.anguage
P thon 3avascri%t 6M. 8TM. /SS ###
-

/ode .ines
&051025 (&(1445 52107' (&1425 2195& ###
Source: :hloh#net

.anguage
P thon 3avascri%t 6M. 8TM. /SS ###
P8P +-<-,

/ode .ines
&051025 (&(1445 52107' (&1425 2195& ###
(&4
Source: :hloh#net

=Unit -

Selenium &#' $ >eb?river

Selenium &#' $ >eb?river

import unittest2 as unittest import transaction from plone.app.testing.selenium_layers import SELENIUM_PLONE_FUNC ION!L_ ES IN" class estPortlets#unittest. estCase$% layer & SELENIUM_PLONE_FUNC ION!L_ ES IN" 'ef setUp#self$% self.'ri(er & self.layer)*selenium*+ self.portal & self.layer)*portal*+ self.'ri(er.implicitly_,ait#-$ self.portal.acl_users._'o!''User#*mem.er/*0 *secret*0 )*Mem.er*+0 )+$ 'ef test_login_faile'#self$% 1 ensure ,e 2a(e a clean starting point transaction.commit#$ self.'ri(er.get#self.portal.a.solute_url#$ 3 *4login_form*$ self.'ri(er.fin'_element_.y_name#*__ac_name*$.sen'_5eys#*mem.er/*$ self.'ri(er.fin'_element_.y_name#*__ac_pass,or'*$.sen'_5eys#*.a'pass,or'*$ self.'ri(er.fin'_element_.y_name#*su.mit*$.clic5#$ self.assert rue#6Login faile'6 in self.'ri(er.page_source$

'ef test_login_o(erlay_successful#self$% 1 ensure ,e 2a(e a clean starting point transaction.commit#$ self.'ri(er.get#self.portal.a.solute_url#$$ self.'ri(er.fin'_element_.y_i'#*personaltools7login*$.clic5#$ self.assert rue#self.'ri(er.fin'_element_.y_i'#*'i(.o(erlay7a8a9 form1login_form*$.is_'isplaye'#$$ self.'ri(er.fin'_element_.y_name#*__ac_name*$.sen'_5eys#*mem.er/*$ self.'ri(er.fin'_element_.y_name#*__ac_pass,or'*$.sen'_5eys#*secret*$ self.'ri(er.fin'_element_.y_name#*su.mit*$.clic5#$ self.assert rue#6:ou are no, logge' in6 in self.'ri(er.page_source$

from plone.testing import Layer class SeleniumLayer#Layer$% 'efault;ases & #<2.=SE>?E>_FI@ U>E0 $ 'ef testSetUp#self$% 1 Start up Selenium 'ri(er & os.en(iron.get#*SELENIUM_A>I?E>*0 **$.lo,er#$ or *firefo9* ,e.'ri(er & __import__# *selenium.,e.'ri(er.Bs.,e.'ri(er* B 'ri(er0 fromlist&)*Ce.Ari(er*+$ args & )arg.strip#$ for arg in os.en(iron.get#*SELENIUM_!>"S*0 **$.split#$ if arg.strip#$+ self)*selenium*+ & ,e.'ri(er.Ce.Ari(er#Dargs$ 'ef test earAo,n#self$% self)*selenium*+.Euit#$ 'el self)*selenium*+ SELENIUM_FI@ U>E & SeleniumLayer#$ SELENIUM_FUNC ION!L_ ES IN" & Functional esting# .ases&#SELENIUM_FI@ U>E0 $0 name&6Selenium esting%Functional6$ SELENIUM_PLONE_FUNC ION!L_ ES IN" & Functional esting# .ases&#SELENIUM_FI@ U>E0 PLONE_FI@ U>E$0 name&6Selenium esting%Functional6$

'ef test_login_o(erlay_successful#self$% 1 ensure ,e 2a(e a clean starting point transaction.commit#$ self.'ri(er.get#self.portal.a.solute_url#$$ self.'ri(er.fin'_element_.y_i'#*personaltools7login*$.clic5#$ self.assert rue#self.'ri(er.fin'_element_.y_i'#*'i(.o(erlay7a8a9 form1login_form*$.is_'isplaye'#$$ self.'ri(er.fin'_element_.y_name#*__ac_name*$.sen'_5eys#*mem.er/*$ self.'ri(er.fin'_element_.y_name#*__ac_pass,or'*$.sen'_5eys#*secret*$ self.'ri(er.fin'_element_.y_name#*su.mit*$.clic5#$ self.assert rue#6:ou are no, logge' in6 in self.'ri(er.page_source$

'ef test_login_o(erlay_successful#self$% 1 ensure ,e 2a(e a clean starting point transaction.commit#$ self.'ri(er.get#self.portal.a.solute_url#$$ self.'ri(er.fin'_element_.y_i'#*personaltools7login*$.clic5#$ self.assert rue#self.'ri(er.fin'_element_.y_i'#*'i(.o(erlay7a8a9 form1login_form*$.is_'isplaye'#$$ self.'ri(er.fin'_element_.y_name#*__ac_name*$.sen'_5eys#*mem.er/*$ self.'ri(er.fin'_element_.y_name#*__ac_pass,or'*$.sen'_5eys#*secret*$ self.'ri(er.fin'_element_.y_name#*su.mit*$.clic5#$ self.assert rue#6:ou are no, logge' in6 in self.'ri(er.page_source$

'ef test_login_o(erlay_successful#self$% 1 ensure ,e 2a(e a clean starting point transaction.commit#$ self.'ri(er.get#self.portal.a.solute_url#$$ self.'ri(er.fin'_element_.y_i'#*personaltools7login*$.clic5#$ self.assert rue#self.'ri(er.fin'_element_.y_i'#*'i(.o(erlay7a8a9 form1login_form*$.is_'isplaye'#$$ self.'ri(er.fin'_element_.y_name#*__ac_name*$.sen'_5eys#*mem.er/*$ self.'ri(er.fin'_element_.y_name#*__ac_pass,or'*$.sen'_5eys#*secret*$ self.'ri(er.fin'_element_.y_name#*su.mit*$.clic5#$ self.assert rue#6:ou are no, logge' in6 in self.'ri(er.page_source$

Solution: Page :b@ects

.:/)T:RS
from from from from

E.EMEATS

P)BE

.asepage import ;asePage pageelements import ;ase e9tElement selenium.,e.'ri(er.common..y import ;y selenium,rapper import SeleniumCrapper as ,rapper

locators & F 6username6% );y.N!ME0 6__ac_name6+0 6pass,or'6% );y.N!ME0 6__ac_pass,or'6+0 6su.mit6% );y.N!ME0 6su.mit6+0 6status_message6% );y.CSS_SELEC O>0 6'l.portalMessage%last7of7type ''6+ G ...

.:/)T:RS
...

E.EMEATS

P)BE

class UsernameElement#;ase e9tElement$% 'ef __init__#self0 selenium$% self.se & selenium self.locator & locators)6username6+ class Pass,or'Element#;ase e9tElement$% 'ef __init__#self0 selenium$% self.se & selenium self.locator & locators)6pass,or'6+ class StatusMessage e9tElement#;ase e9tElement$% 'ef __init__#self0 selenium$% self.se & selenium self.locator & locators)6status_message6+ ...

.:/)T:RS
... class LoginPage#;asePage$%

E.EMEATS

P)BE

'ef __init__#self0 selenium$% self.se & selenium self.username & UsernameElement#self.se$ self.pass,or' & Pass,or'Element#self.se$ self.status_message & StatusMessage e9tElement#self.se$ 'ef su.mit#self$% self.se.fin'_element#Dlocators)6su.mit6+$.clic5#$

from plone.seleniumtesting.loginpage import LoginPage 'ef test_login_successful#self$% lpo & LoginPage#$ lpo.open#$ lpo.username & *mem.er/* lpo.pass,or' & *secret* lpo.su.mit#$ self.assertEEual#6:ou are no, logge' in60 lpo.status_message$

'ef test_login_successful#self$% 1 ensure ,e 2a(e a clean starting point transaction.commit#$ self.'ri(er.get#self.portal.a.solute_url#$ 3 *4login_form*$ self.'ri(er.fin'_element_.y_name#*__ac_name*$.sen'_5eys#*mem.er/*$ self.'ri(er.fin'_element_.y_name#*__ac_pass,or'*$.sen'_5eys#*secret*$ self.'ri(er.fin'_element_.y_name#*su.mit*$.clic5#$ self.assert rue#6:ou are no, logge' in6 in self.'ri(er.page_source$

from plone.seleniumtesting.loginpage import LoginPage 'ef test_login_successful#self$% lpo & LoginPage#$ lpo.open#$ lpo.username & *mem.er/* lpo.pass,or' & *secret* lpo.su.mit#$ self.assertEEual#6:ou are no, logge' in60 lpo.status_message$

Selenium

Robot Framework

Robot Framework

TeCtDbased *ile *ormat Ee wordDdriven a%%roach to testing ECtensible through custom libraries Modular architecture

est Login Successful Open login o(erlay Login ,it2 cre'entials O(erlay s2oul' .e gone

a'min

a'min

Robot Framework

DDD

est cases DDD

est Login Successful Open login o(erlay Login ,it2 cre'entials O(erlay s2oul' .e gone DDD Hey,or's DDD

a'min

a'min

Open login o(erlay Clic5 Element IFpersonaltools_login_selectorG Page S2oul' Contain Element IFo(erlay_login_selectorG Page s2oul' contain element __ac_name Login ,it2 cre'entials )!rguments+ IFusernameG IFpass,or'G Input te9t __ac_name IFusernameG Input te9t __ac_pass,or' IFpass,or'G Clic5 ;utton Log in Cait Until Page Contains Element IFpersonaltools_logout_selectorG O(erlay s2oul' .e gone Page S2oul' Not Contain Element IFo(erlay_login_selectorG

DDD Settings DDD Li.rary Selenium2Li.rary Suite setup est setup

timeout&J secon's

implicit_,ait&- secon's

Log out an' go 2ome

DDD ?aria.les DDD IFo(erlay_login_selectorG & IFpersonaltools_login_selectorG & IFpersonaltools_logout_selectorG &


DDD est cases DDD

css&'i(.o(erlay7a8a9 form1login_form css&1personaltools7login css&1personaltools7logout

est Login Successful Open login o(erlay Login ,it2 cre'entials O(erlay s2oul' .e gone DDD Hey,or's DDD

a'min

a'min

Open login o(erlay Clic5 Element IFpersonaltools_login_selectorG Page S2oul' Contain Element IFo(erlay_login_selectorG Page s2oul' contain element __ac_name

...

github.com/emanlove/pse2012

Install Plone

( &

Install robot*ramework1

robot*ramworkDselenium&librar % thon %ackages +and de%endencies,


/reate test director and sam%le test case Run the test +c:F % bot helloGworld#tCt,

(
).uil'out+ parts & ... ro.ot auto7c2ec5out 3& ro.otframe,or57selenium2li.rary )ro.ot+ recipe & <c.recipe.egg eggs & ro.otframe,or5 ro.otframe,or57selenium2li.rary entry7points & py.ot&ro.ot%run_cli re.ot&ro.ot.re.ot%re.ot_cli

buildout#c*g +or eHuivalent,


)sources+ ... ro.otframe,or57selenium2li.rary & git git%44git2u..com4emanlo(e4ro.otframe,or57selenium2li.rary.git

source#c*g +or eHuivalent,

&

K4ploneL2I .4.in4.uil'out

0
. . . import ro.ot if __name__ && *__main__*% ro.ot.run_cli#sys.arg()/%+$

#$bin$% bot

5
DDD Settings DDD ).uil'out+ parts & Li.rary Selenium2Li.rary ... DDD ro.ot est cases DDD timeout&J secon's implicit_,ait&- secon's

Mello Corl' auto7c2ec5out 3& ro.otframe,or57selenium2li.rary "o to 2ttp%44plone.org Clic5 lin5 "et In(ol(e' )ro.ot+ recipe Page & s2oul' <c.recipe.egg contain Melp ma5e Plone e(en .etter eggsPage & ro.otframe,or5 s2oul' contain Create .ug fi9es0 'e(elop ne, features ro.otframe,or57selenium2li.rary entry7points & py.ot&ro.ot%run_cli re.ot&ro.ot.re.ot%re.ot_cli

#$acce%tanceDtests$helloGword#tCt
K4ploneL2I .4.in4py.ot acceptance7tests4

Issues with

Robot Framework

github.com/emanlove/pse2012

Iisual Editors +Tin M/E1 /EEditor, Aew User Inter*ace J /MSUI ?eco $ Tiles $ Klocks

github.com/emanlove/pse2012
Thank Lou

Ed Manlove irc: t55e devP PlTw!veri"on#net

Você também pode gostar