Upgrade to Pro — share decks privately, control downloads, hide ads and more …

横浜タネマキでGebと握手! #yokohamagroovy

横浜タネマキでGebと握手! #yokohamagroovy

Yokohama.groovy #42でのGebのハンズオンの資料です。

B765faf519f19520e1495bd870f4d7f0?s=128

PoohSunny

July 30, 2016
Tweet

Transcript

  1. ԣ඿λωϚΩͰ GebͱѲखʂ @PoohSunny Yokohama.groovy #42 #yokohamagroovy

  2. @PoohSunny { work: "σΟϕϩούʔ" geb: "very minor contributor" community: [

    "TDDBC", "Agile Samurai Base Camp", "೔ຊSeleniumϢʔβʔίϛϡχςΟ" "Yokohama.groovy" <- NEW! ] }
  3. None
  4. ࠓ೔ͷςʔϚ

  5. ͐͡Ϳ

  6. ϒϥ΢βΦʔτϝʔγϣϯ πʔϧ License͸Apache License, Version 2.0 ͦΖͦΖ1.0.0ͳ͸ͣʂʂ ݱࡏͷ࠷৽όʔδϣϯ͸0.13.1

  7. GebΛ࢖ͬͯΈΑ͏ʂ

  8. ͪΐͬͱ͚ͩલஔ͖ Gebͷ΢Ϧ

  9. ؆ܿͳهड़1 import geb.Browser Browser.drive { go "http://myapp.com/login" assert $("h1").text() ==

    "Please Login" $("form.login").with { username = "admin" password = "password" login().click() } assert $("h1").text() == "Admin Section" } 1 http://www.gebish.org/
  10. Seleniumͩͱ...

  11. Gebͩͱ!2 2 http://www.slideshare.net/youtaroutakahashi/what-makes-geb-groovy

  12. ࣮ࡍ΍ͬͯΈ·͠ΐ ͏ɻ

  13. ࠷ॳʹ࢖͏ϓϩδΣΫτ GebͷϗʔϜϖʔδʹΞΫηε͢Δ΋ͷ ͪ͜ΒΛΫϩʔϯ͍ͯͩ͘͠͞ https://github.com/PoohSunny/geb-hands-on-project

  14. ࢖͍ͬͯΔπʔϧ Gradle: λεΫϥϯφʔͱͯ͠ Spock: ςετϥϯφʔͱͯ͠ ࣮ࡍͷςετ͸Spockͷςετͱͯ͠هड़ GebSpecɺ͋Δ͍͸GebReportingSpecΛܧঝ class GebishOrgSpec extends

    GebReportingSpec { Reportingͱ͍͍ͭͯΔΫϥε → ೚ҙͷλΠϛϯάɾऴྃ࣌ʹΩϟϓνϟ͕औΕ·͢ɻ
  15. ϓϩδΣΫτͷσΟϨΫτϦ ߏ੒ root |-- src | `-- test | |--

    groovy | | `- xxxSpecs.groovy | `-- resources | `-- GebConfig.groovy `-- build.gradle
  16. build.gradle ґଘؔ܎ͷఆٛ3 dependencies { // ུ // ඞཁͳυϥΠόΛͦΕͧΕґଘؔ܎ʹ௥Ճ testCompile "org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion"

    testCompile("com.codeborne:phantomjsdriver:1.2.1") { // phantomjs driver pulls in a different selenium version transitive = false } } 3 ͳͥɺWebDriverΛͦΕͧΕґଘؔ܎ʹ௥Ճ͢Δͷ͔ʹ͍ͭͯ͸ɺhttps://groups.google.com/d/ msg/geb-user/Og40o5mXK-4/tga5H2zuRRYJ
  17. ͱΓ͋͑ͣಈ͔ͯ͠ΈΑ͏ ԼهͷίϚϯυΛ࣮ߦͯ͠ɺϒϥ΢β ্ཱ͕͕ͪΔʁ ./gradlew test

  18. ಈ͍ͨʂ Ͱ΋ίέͨʂ

  19. গ͠ղઆ ࢖͍ͬͯΔAPI // Ҿ਺Ͱࢦఆ͞Ε͍ͯΔURLʹભҠ go "XXX" // ϖʔδͷλΠτϧΛνΣοΫ title ==

    "Very Groovy Browser Automation!"
  20. APIʹ͍ͭͯ པΔͳΒެࣜυΩϡϝϯτ http://www.gebish.org/manual/current/ αϯϓϧ͕ଟ͍͔ΒӳޠͰ΋͖ͬͱେৎ෉ʂ

  21. ࿅श མͪͨςετΛ௚ͯ͠ΈΑ͏ ࣍ͷϖʔδʹղ౴͕͋Γ·͢ɻ

  22. ղ౴ // λΠτϧͷظ଴஋͕ؒҧͬͯͨʂ title == "Very Groovy Browser Automation"

  23. ࿅शͦͷ2 ԼهͷॲཧΛ௥Ճͯ͠Έ·͠ΐ͏ɻ • ϗʔϜϖʔδ͔ΒɺϚχϡΞϧ΁ͷϦϯΫΛΫ ϦοΫ • ϚχϡΞϧϖʔδʢThe book of Gebʣ͕දࣔ

    ͞ΕΔ͔ΛνΣοΫ • step-2ͬͯϒϥϯνʹɺҰ෦ຒ·ͬͯΔςετ ͕͋ΔͷͰɺͦΕΛຒΊͯ΋Β͏ͱ͍͍͔ͱɻ • ώϯτ͕ཉ͍͠ਓ͸࣍ͷϖʔδ΁
  24. ͔͜͜Βώϯτ

  25. jQueryͬΆ͍API4 $("div") // ࠷ॳʹݟ͔ͭͬͨ div ཁૉ $("div", name: "main") //

    <div name="main"></div> $("div", 1, name: "main") // ೋ൪໨ͷ<div name="main"></div> 4 http://www.gebish.org/manual/current/#the-jquery-ish-navigator-api
  26. ͜Μͳॻ͖ํ΋Մ $("#user-name") // user-name ͱ͍͏id͕ࢦఆ͞Ε͍ͯΔཁૉ $(".btn") // btn ͱ͍͏class͕ࢦఆ͞Ε͍ͯΔཁૉ ཁૉΛ୳͢ͷ͸Chrome

    Developer tool + jQueryͰ΍ͬͯɺͦΕΛGebʹίϐ ϖ͢Δͱ͔Α͘΍Γ·͢ νʔϜͰهड़͕όϥόϥͩͱ΍΍͘͜͠ͳΔͷͰɺܾΊ͓ͯ͘ͱྑ͍Ͱ͢
  27. click manualsMenu.links[0].click() ϖʔδΦϒδΣΫτͷఆٛͷ࢓ํ͍Ζ͍Ζ content { // to: ͜ͷΤϨϝϯτ͕ΫϦοΫ͞Εͨͱ͖ʹConfirmPageΛ౉͢ // toWait:

    ࣍ͷϖʔδͷatνΣοΫ͕trueʹͳΔ·Ͱ଴ͭ button(to: ConfirmPage, toWait: true) { $('button#save') } }
  28. interact()5 ෳࡶͳૢ࡞Λ͢Δͱ͖ʹ ྫ͑͹υϥοά & υϩοϓ interact { clickAndHold($('#draggable')) moveByOffset(150, 200)

    release() } 5 http://www.gebish.org/manual/current/#interact-closures
  29. ώϯτ͸͜͜·Ͱ ͪͳΈʹ౴͑͸ step-2- answer ϒϥϯνʹ͋Γ·͢ɻ

  30. Ͱ͖͸ͨ͠΋ͷͷ ͋Μ·Γ͖Ε͍Ͱ͸ͳ͍

  31. Կ͕͍͚ͳ͍ʁ interact { // ఆ͕ٛ௕͍ moveToElement($("#header-content ul li", 0).children("span")) }

    // ఆٛͷॏෳ $("#header-content ul li", 0).$('.link-list li a')[0].click()
  32. Ͳ͏վળ͢Δʁ

  33. هड़͸γϯϓϧΛ৺͕͚Δ ਂ͗͢ΔΤϨϝϯτऔಘ $("#id").find(".class-a").find("td").find(".class-b")

  34. هड़͸γϯϓϧΛ৺͕͚Δ ఆٛ͸୹͘ // ్தʹࢦఆͰ͖ͦ͏ͳattributeΛ୳͢ $("#user-td").find(".class-b") // ΤϨϝϯτΛ෼ׂ͢Δ userTd { $("#id").find(".class-a").find("td")

    } column { userTd.find(".class-b") }
  35. ϖʔδΦϒδΣΫτύλʔϯ ͷར༻ ར༻͢ΔίϯςϯπͷϝϯςφϯεੑΛ্͛ɺ࠶ ར༻͠΍͘͢͢ΔͨΊͷσβΠϯύλʔϯ6 6 http://www.seleniumhq.org/docs/06testdesign_considerations.jsp#page-object-design-pattern

  36. GebͷϖʔδΦϒδΣΫτʹ ͍ͭͯৄ͘͠

  37. GebͷϖʔδΦϒδΣΫτ PageΫϥεΛܧঝ class GebishOrgHomePage extends Page { static at =

    { title == "Sample page" } static content = { header { $("#header") } manualsMenu { module MenuModule, $("#header", 0) } } }
  38. ࠶ར༻Մೳͳύʔπ͸Moduleʹ import geb.Module class MenuModule extends Module { static content

    = { toggle { children("span") } links { $('.link-list li a') } } }
  39. Page url at content

  40. url7 to()ϝιουͰݺΜͩ࣌ʹભҠ͢ΔઌΛઃఆ class PageWithUrl extends Page { static url =

    "example" } ૬ରύεͰهड़͢Δͱ͖͸ɺbaseUrlͷઃఆ͕ඞཁ8 8 http://www.gebish.org/manual/current/#base-url 7 http://www.gebish.org/manual/current/#page-urls
  41. at9 at()ϝιουར༻࣌ʹ͜ͷϖʔδͷΞαʔτ͕ߦΘΕΔ to()ϝιουͰϖʔδભҠͨ͠ͱ͖΋atνΣοΫ͕૸Δ class PageWithAtChecker extends Page { static at

    = { $("h1").text() == "Example" } } 9 http://www.gebish.org/manual/current/#at-checker
  42. content ϖʔδ಺ͷཁૉΛهड़ class PageWithDiv extends Page { static content =

    { theDiv { $('div', id: 'a') } } }
  43. Page, Module͸ઐ༻ͷσΟϨΫτϦ ʹ഑ஔ͠·͠ΐ͏ root |-- src | `-- test |

    |-- groovy | | |-- pages | | |-- modules | | `- xxxSpecs.groovy | `-- resources | `-- GebConfig.groovy `-- build.gradle
  44. ࿅श ϖʔδΦϒδΣΫτΛ࢖ͬͯ վળͯ͠ΈΑ͏ʂ

  45. ࿅श ࠓͷςετ͸ɺ؆ܿͰͳ͍هड़΍ॏෳΛ͓࣋ͬͯ Γɺ·ͨมߋʹऑ͍ߏ੒ʹͳ͍ͬͯ·͢ɻ͜ΕΒ ͷ໰୊Λղܾ͢Δ΂͘ςετίʔυΛϦϑΝΫλ Ϧϯά͍ͯͩ͘͠͞ɻ ΩʔϫʔυɿϖʔδΦϒδΣΫτύλʔϯɺ؆ܿ ͳهड़ɺϞδϡʔϧԽ step-3ͱ͍͏ϒϥϯνʹϖʔδΦϒδΣΫτͷ਽ ܗΛ࡞ͬͨ΋ͷ͕͋Γ·͢ɻ

  46. ͔͜͜Β՝୊Λ΍ Δ্Ͱͷώϯτ

  47. ϖʔδΦϒδΣΫτͷఆٛͷ࢓ํ͍Ζ͍Ζ content { // to: ͜ͷΤϨϝϯτ͕ΫϦοΫ͞Εͨͱ͖ʹConfirmPageΛ౉͢ // toWait: ࣍ͷϖʔδͷatνΣοΫ͕trueʹͳΔ·Ͱ଴ͭ button(to:

    ConfirmPage, toWait: true) { $('button#save') } }
  48. Θ͔Γ΍͍͢هड़Λ ͜ͷϘλϯ͸Ͳ͜ͷϘλϯʁ to LoginPage login("user", "password") clickListButton()

  49. Θ͔Γ΍͍͢هड़Λ SpockͷػೳΛ׆༻ given: "user is at Top page" to LoginPage

    login("user", "password") at TopPage when: "user clicks list button" listButton.click() then: "user moves to List page" at ListPage
  50. ॻ͖ํόϥόϥ໰୊ // A͞Μ go "http://myapp.com/login" $("form.login").with { username = "admin"

    password = "password" login().click() } // B͞Μ to LoginPage username = "admin" password = "password" loginButton.click() // C͞Μ to LoginPage login("admin", password)
  51. ॻ͖ํͷ౷Ұ ·ͣ͸ϖʔδΦϒδΣΫτԽ ·ͱ·ͬͨॲཧ͸ϝιουͱͯ͠ఆٛ͢Δ

  52. ϝιουͷཻ౓όϥόϥ໰୊ // A͞Μ to HomePage menuLinks[0].click() // B͞Μ to HomePage

    manualLink.click() // C͞Μ to HomePage showManual()
  53. ͳͥɺͳʹΛ ςετ͍ͨ͠ͷ͔ʹґଘ10 ໨తΛࢥ͍ग़͢ νʔϜͰٞ࿦͢Δ 10 http://benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories.html

  54. ՝୊ʹ٧·ͬͨΒ ్தܦա͕Լهϒϥϯνʹ͋ Γ·͢ɻ https://github.com/yokohamagroovy/ geb-hands-on-project/tree/step3-hints

  55. ࠷ऴܗ ຊՈͷαϯϓϧϓϩδΣΫτ ʹ͍ۙ΋ͷʹͳΔ͸ͣɻ https://github.com/geb/geb-example- gradle ɾϖʔδɺϞδϡʔϧͷύοέʔδϯά ɾϖʔδΦϒδΣΫτ಺ͷϝιουͷ੾Γग़͠ํɺ໋໊͸ҙਤతʹมߋͯ͠·͢

  56. ͓͠·͍ GebͰָ͍͠ϒϥ΢βΦʔτϝʔγϣϯΛʂ