Successfully reported this slideshow.
Your SlideShare is downloading. ×

QA Fest 2017. Ярослав Святкин. Тестовый фреймворк GEB для тестирования WEB приложений и Mobile

QA Fest 2017. Ярослав Святкин. Тестовый фреймворк GEB для тестирования WEB приложений и Mobile

Доклад будет полезен тем, кто хочет узнать как бысто писать тесты на языке програмирования Groovy и не думать о фреймворке, PageObject и инициализации WebDriver. Фреймворк это сложно? Нет! Я покажу способ, который позволяет думать о тестировании приложения, а не о стуктуре кода.

Доклад будет полезен тем, кто хочет узнать как бысто писать тесты на языке програмирования Groovy и не думать о фреймворке, PageObject и инициализации WebDriver. Фреймворк это сложно? Нет! Я покажу способ, который позволяет думать о тестировании приложения, а не о стуктуре кода.

More Related Content

More from QAFest

Related Audiobooks

Free with a 30 day trial from Scribd

See all

QA Fest 2017. Ярослав Святкин. Тестовый фреймворк GEB для тестирования WEB приложений и Mobile

  1. 1. Тестовый фреймворк GEB для тестирования WEB приложений и Mobile YaroslavSviatkin email:yariks@i.ua http://sviatkin.com
  2. 2. HtmlElements. Page Object
  3. 3. JDI UI Test Automation Framework @JSite(domain="https://epam.github.io/JDI/") publicclassJDIExampleSiteextendsWebSite{ publicstaticHomePagehomePage; publicstaticLoginFormloginForm; @FindBy(css=".profile-photo") publicstaticLabelprofilePhoto; publicstaticvoidlogin(){ profilePhoto.click(); loginForm.loginAs(newUser()); } }
  4. 4. Automated Acceptance Testing with Style http://www.thucydides.info/#/
  5. 5. Project structure Page Object classes Steps implementation class Stories classes Requirements for the application under test
  6. 6. Organizing requirements First, you create a model of the features and user stories you intend to implement: Stories Features
  7. 7. Confidential 9 Page Objects Next you will need to implement your page objects. These are almost just run-of-the-mill WebDriver page objects, but with a few enhancements:
  8. 8. Steps implementation Now implement the actual test steps using either WebDriver page objects or other test steps. Here you start thinking about implementation: A step library High level steps... ...implemented with Page Objects ...or with other steps
  9. 9. Selenide http://selenide.org
  10. 10. Geb http://www.gebish.org
  11. 11. What is Geb? Geb is a browser automation solution
  12. 12. What can you test with Geb? • Any web and mobile applications • App doesn't need to be written in Groovy
  13. 13. go"http://www.google.com" $("input",name:"q").value("geb") $("button",name:"btnG").click() waitFor{$("#search").displayed} $("h3.r").first().click() waitFor{title=="Geb-VeryGroovyBrowserAutomation"}
  14. 14. Selector syntax $("#by-id") $(".by-class") $("div",name:"by-attribute") $("div",text:"Bytext") $(By.id("some-id")) $(By.className("some-class")) $(By.xpath('//p[@class="xpath"]')) … title{$(By.xpath(".//h4[@class='titleng-binding']")).text()
  15. 15. assert$("p",1..2)*.text()==["b","c"] assert$("p",text:~/p./).size()==2 assert$("p",text:startsWith("p")).size()==2
  16. 16. assert$("p.d").previous()==$("p.c") assert$("p.e").prevAll()==$("p.c").add("p.d") assert$("p.d").next()==$("p.e") assert$("p.c").nextAll()==$("p.d").add("p.e") assert$("p.d").parent()==$("div.b") assert$("p.c").siblings()==$("p.d").add("p.e") assert$("div.a").children()==$("div.b").add("div.f")
  17. 17. project { String index -> $(By.xpath("//div[@class=card-item']//h4[@title='${index}']")).click() } projectPage.project(nameProject)
  18. 18. dynamicallyAdded(wait:true){$("p.dynamic")} dynamicallyAdded(wait:5,required:false){$("p.dynamic")} cachedValue(cache:true){value} helpLink(to:HelpPage){$("a",text:"Help")}
  19. 19. Page Object Model
  20. 20. Page Module
  21. 21. Control modules • FormElement • Checkbox • Select • MultipleSelect • TextInput • Textarea • FileInput • RadioButtons
  22. 22. classExamplePageextendsPage{ staticcontent={ theModule{moduleExampleModule} } } classExampleModuleextendsModule{ staticcontent={ button{$("input",type:"submit")} } }
  23. 23. class NotificationModule extends Module { static content = { notifocation { $(By.xpath(".//li[contains(@ng-repeat,'notifications')]")).moduleList(Notification) } gotItButton { $(By.xpath(".//button[@ng-click='appCtrl.gotItNotifications()']")) } } } class Notification extends Module { static content = { name { $(By.xpath("//h5")).text() } dete { $(By.xpath("//div[contains(@class,'date')]")).text() } notification { $(By.xpath("//p")) text() } } }
  24. 24. searchResult(required: false, wait: 5) { $(By.xpath("//li/a/strong"))*.text() } notification { $(By.xpath("//ul[contains(@ng-if,'notifications')]")).module(NotificationModule) } menuLinksModule(wait: 5) { $(By.xpath("//button[contains(@class,'services')]")).module(MenuLinksModule) }
  25. 25. Verify test at current page classIdeaCreatePageextendsgeb.Page{ staticat={$("div#create-idea").displayed} } staticcontent={ createButton(to:IdeaShowPage){$("input#create")} } IdeaCreatePageideaCreatePage=to(IdeaCreatePage) isAt(IdeaCreatePage)
  26. 26. class LoginPage extends Page { static url = "access/signin" static at = { browser.currentUrl.startsWith("https://wwwwwwwwww.com") } static content = { userName(wait: 5) { $(By.xpath("//input[@type='text']")) } userPassword { $(By.xpath("//input[@type='password']")) } loginError(required: false, wait: 3) { $(By.xpath("//div[@class='error']")).text() } loginSubmit { $("button", text: startsWith("Login")).click() } heading (to:BasePage){ $(By.xpath("//div[@class='info']/h1")).text() } } def login(String login, String password) { userName.firstElement().clear() userPassword.firstElement().clear() userName << login userPassword << password loginSubmit } } LoginPage loginPage = page(LoginPage)
  27. 27. waitFor examples waitFor{ $("div.alert").displayed } waitFor{ $("div.message").text()=="Updatesuccessful" }
  28. 28. Mouse interactions voidmoveRatingSlider(Integerrating){ //Slideris400pixelswideandstartsat1, //soeachnotchabove1is100pixelsapart IntegernumPixelsX=(rating-1)*100 interact{ clickAndHold(ratingSliderHandle) moveByOffset(numPixelsX,0) release() } } WebElementunderlyingElement= $('#myElement').getElement(0) Actionaction=newActions(browser.driver) .clickAndHold(underlyingElement) .moveByOffset(15,15) .release() .build() action.perform() } Use keyboard $(".ui-slider-handle")<<Keys.ARROW_RIGHT
  29. 29. Already opened windows withWindow({title=="Geb-VeryGroovyBrowserAutomation"}){ assert$("#slogan").text().startsWith("verygroovybrowserautomation…") } } withNewWindow({$('a').click()}){ asserttitle=='Geb-VeryGroovyBrowserAutomation' }
  30. 30. @Test void feedBackReferenceTest() { openMenu browser.withNewWindow({ basePage.menuLinksModule.feedback }, { assert browser.currentUrl.startsWith("https://helpdesk.com/") }) } @Test void officeMapReferenceTest() { openMenu browser.withWindow({ basePage.menuLinksModule.officeMap }, { if (browser.currentUrl == signinUrl) { loginPage.login(userName, userPassword) } assert browser.currentUrl == "https://portal.com" }) browser.to(ProjectPage) }
  31. 31. Show hidden element void scrollUp() { js.exec("""window.scrollTo(0,0)""") } $("div#a").jquery.mouseover() Browser.drive{ assertjs.myGlobalVar==1 }
  32. 32. Available browsers
  33. 33. waiting { timeout = 2 } baseUrl = "https://wwwwwwwww.com/" autoClearCookies = false atCheckWaiting = true baseNavigatorWaiting = true name = '' password = '' mail ='' environments { chrome { driver = { def driverInstance = new ChromeDriver() driverInstance.manage().window().maximize() driverInstance } } firefox { driver = { def driverInstance = new FirefoxDriver() driverInstance.manage().window().maximize() driverInstance } } ie { driver = { def driverInstance = new InternetExplorerDriver() driverInstance.manage().window().maximize() driverInstance } }} //Receiving name and password from GebConfig.groovy final String userName = browser.config.rawConfig.name final String userPassword = browser.config.rawConfig.password
  34. 34. task chromeTest(type: Test) { systemProperty "geb.env", "chrome" systemProperty "webdriver.chrome.driver", "driverschromedriver.exe" useTestNG { suites "srctestresourcestestng-suite.xml" useDefaultListeners = true } } // Drivers testCompile "org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion" testCompile "org.seleniumhq.selenium:selenium-firefox-driver:$seleniumVersion" testCompile "org.seleniumhq.selenium:selenium-ie-driver:$seleniumVersion"
  35. 35. static String randomString(int count) { (1..count).inject("") { a, b -> a += ('a'..'z')[new Random().nextFloat() * 26 as int] }.capitalize() } def getWanted() { def result = [] HTTPRequest.request(GET, JSON) { req -> uri.path = '/wanted' headers.'Auth' = "${TOKEN}" response.success = { resp, json -> println new JsonBuilder( json).toPrettyString() (json as ArrayList).each { String name = it.name def projects = [] (it.projects as ArrayList).each { projects << [it.projectid.'$oid', it.title] } result << [name, projects].flatten() } } } result }
  36. 36. List getAllIdProject() { def result = [] GITLAB.get(path: "/gitlab/api/v3/projects/all") { resp, json -> println new JsonBuilder(json).toPrettyString() def request = (json as Map) result = request*.id } result } assert loginPage.heading == "Welcome"
  37. 37. Geb integrates with
  38. 38. Geb-mobile https://github.com/JasonKissinger-MDT/geb-mobile
  39. 39. email : yariks@i.ua http://sviatkin.com

×