Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
横浜タネマキでGebと握手! #yokohamagroovy
Search
PoohSunny
July 30, 2016
Technology
0
400
横浜タネマキでGebと握手! #yokohamagroovy
Yokohama.groovy #42でのGebのハンズオンの資料です。
PoohSunny
July 30, 2016
Tweet
Share
More Decks by PoohSunny
See All by PoohSunny
ドレイファスモデルの紹介 / introduce Dreyfus model
poohsunny
1
1.3k
Make Work Visible in Agile2018 #LINE_DM
poohsunny
1
430
タウンワークをドライブさせるためになんちゃってアジャイルをやめた話 #devsumi #devsumiB / devsumi2018
poohsunny
30
46k
1 test 1 assert ?
poohsunny
0
440
XUTPから学ぶ記述性の高いユニットテスト 〜俺たちを助けるユニットテストへ〜 / xUTP in #xpjug
poohsunny
4
5.3k
XCUITestする時のTIPs 〜あなたを助けるXCUITestへ〜
poohsunny
0
3.1k
コードに思いが伝わる
poohsunny
0
300
The "yummy" licenses.
poohsunny
0
180
ブラウザテストをサクサク自動化するためのGeb実践入門 #jjug_ccc
poohsunny
21
7.1k
Other Decks in Technology
See All in Technology
専門分化が進む分業下でもユーザーが本当に欲しかったものを追求するプロダクトマネジメント/Focus on real user needs despite deep specialization and division of labor
moriyuya
2
1.4k
o11yツールを乗り換えた話
tak0x00
2
1.6k
Google Cloud で学ぶデータエンジニアリング入門 2025年版 #GoogleCloudNext / 20250805
kazaneya
PRO
24
5.9k
AIは変更差分からユニットテスト_結合テスト_システムテストでテストすべきことが出せるのか?
mineo_matsuya
3
960
マルチプロダクト×マルチテナントを支えるモジュラモノリスを中心としたアソビューのアーキテクチャ
disc99
1
630
AIと描く、未来のBacklog 〜プロジェクト管理の次の10年を想像し、創造するセッション〜
hrm_o25
0
110
メルカリIBIS:AIが拓く次世代インシデント対応
0gm
2
400
【OptimizationNight】数理最適化のラストワンマイルとしてのUIUX
brainpadpr
2
520
リモートワークで心掛けていること 〜AI活用編〜
naoki85
0
180
AIエージェントを現場で使う / 2025.08.07 著者陣に聞く!現場で活用するためのAIエージェント実践入門(Findyランチセッション)
smiyawaki0820
7
1.2k
アカデミーキャンプ 2025 SuuuuuuMMeR「燃えろ!!ロボコン」 / Academy Camp 2025 SuuuuuuMMeR "Burn the Spirit, Robocon!!" DAY 1
ks91
PRO
0
150
Findy Freelance 利用シーン別AI活用例
ness
0
670
Featured
See All Featured
4 Signs Your Business is Dying
shpigford
184
22k
The Straight Up "How To Draw Better" Workshop
denniskardys
236
140k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.6k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.8k
Rebuilding a faster, lazier Slack
samanthasiow
83
9.1k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Practical Orchestrator
shlominoach
190
11k
A better future with KSS
kneath
239
17k
Designing for humans not robots
tammielis
253
25k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Transcript
ԣλωϚΩͰ GebͱѲखʂ @PoohSunny Yokohama.groovy #42 #yokohamagroovy
@PoohSunny { work: "σΟϕϩούʔ" geb: "very minor contributor" community: [
"TDDBC", "Agile Samurai Base Camp", "ຊSeleniumϢʔβʔίϛϡχςΟ" "Yokohama.groovy" <- NEW! ] }
None
ࠓͷςʔϚ
͐͡Ϳ
ϒϥβΦʔτϝʔγϣϯ πʔϧ LicenseApache License, Version 2.0 ͦΖͦΖ1.0.0ͳͣʂʂ ݱࡏͷ࠷৽όʔδϣϯ0.13.1
GebΛͬͯΈΑ͏ʂ
ͪΐͬͱ͚ͩલஔ͖ GebͷϦ
؆ܿͳهड़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/
Seleniumͩͱ...
Gebͩͱ!2 2 http://www.slideshare.net/youtaroutakahashi/what-makes-geb-groovy
࣮ࡍͬͯΈ·͠ΐ ͏ɻ
࠷ॳʹ͏ϓϩδΣΫτ GebͷϗʔϜϖʔδʹΞΫηε͢Δͷ ͪ͜ΒΛΫϩʔϯ͍ͯͩ͘͠͞ https://github.com/PoohSunny/geb-hands-on-project
͍ͬͯΔπʔϧ Gradle: λεΫϥϯφʔͱͯ͠ Spock: ςετϥϯφʔͱͯ͠ ࣮ࡍͷςετSpockͷςετͱͯ͠هड़ GebSpecɺ͋Δ͍GebReportingSpecΛܧঝ class GebishOrgSpec extends
GebReportingSpec { Reportingͱ͍͍ͭͯΔΫϥε → ҙͷλΠϛϯάɾऴྃ࣌ʹΩϟϓνϟ͕औΕ·͢ɻ
ϓϩδΣΫτͷσΟϨΫτϦ ߏ root |-- src | `-- test | |--
groovy | | `- xxxSpecs.groovy | `-- resources | `-- GebConfig.groovy `-- build.gradle
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
ͱΓ͋͑ͣಈ͔ͯ͠ΈΑ͏ ԼهͷίϚϯυΛ࣮ߦͯ͠ɺϒϥβ ্ཱ͕͕ͪΔʁ ./gradlew test
ಈ͍ͨʂ Ͱίέͨʂ
গ͠ղઆ ͍ͬͯΔAPI // ҾͰࢦఆ͞Ε͍ͯΔURLʹભҠ go "XXX" // ϖʔδͷλΠτϧΛνΣοΫ title ==
"Very Groovy Browser Automation!"
APIʹ͍ͭͯ པΔͳΒެࣜυΩϡϝϯτ http://www.gebish.org/manual/current/ αϯϓϧ͕ଟ͍͔ΒӳޠͰ͖ͬͱେৎʂ
࿅श མͪͨςετΛͯ͠ΈΑ͏ ࣍ͷϖʔδʹղ͕͋Γ·͢ɻ
ղ // λΠτϧͷظ͕ؒҧͬͯͨʂ title == "Very Groovy Browser Automation"
࿅शͦͷ2 ԼهͷॲཧΛՃͯ͠Έ·͠ΐ͏ɻ • ϗʔϜϖʔδ͔ΒɺϚχϡΞϧͷϦϯΫΛΫ ϦοΫ • ϚχϡΞϧϖʔδʢThe book of Gebʣ͕දࣔ
͞ΕΔ͔ΛνΣοΫ • step-2ͬͯϒϥϯνʹɺҰ෦ຒ·ͬͯΔςετ ͕͋ΔͷͰɺͦΕΛຒΊͯΒ͏ͱ͍͍͔ͱɻ • ώϯτ͕ཉ͍͠ਓ࣍ͷϖʔδ
͔͜͜Βώϯτ
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
͜Μͳॻ͖ํՄ $("#user-name") // user-name ͱ͍͏id͕ࢦఆ͞Ε͍ͯΔཁૉ $(".btn") // btn ͱ͍͏class͕ࢦఆ͞Ε͍ͯΔཁૉ ཁૉΛ୳͢ͷChrome
Developer tool + jQueryͰͬͯɺͦΕΛGebʹίϐ ϖ͢Δͱ͔Α͘Γ·͢ νʔϜͰهड़͕όϥόϥͩͱ͘͜͠ͳΔͷͰɺܾΊ͓ͯ͘ͱྑ͍Ͱ͢
click manualsMenu.links[0].click() ϖʔδΦϒδΣΫτͷఆٛͷํ͍Ζ͍Ζ content { // to: ͜ͷΤϨϝϯτ͕ΫϦοΫ͞Εͨͱ͖ʹConfirmPageΛ͢ // toWait:
࣍ͷϖʔδͷatνΣοΫ͕trueʹͳΔ·Ͱͭ button(to: ConfirmPage, toWait: true) { $('button#save') } }
interact()5 ෳࡶͳૢ࡞Λ͢Δͱ͖ʹ ྫ͑υϥοά & υϩοϓ interact { clickAndHold($('#draggable')) moveByOffset(150, 200)
release() } 5 http://www.gebish.org/manual/current/#interact-closures
ώϯτ͜͜·Ͱ ͪͳΈʹ͑ step-2- answer ϒϥϯνʹ͋Γ·͢ɻ
Ͱ͖ͨ͠ͷͷ ͋Μ·Γ͖Ε͍Ͱͳ͍
Կ͕͍͚ͳ͍ʁ interact { // ఆ͕͍ٛ moveToElement($("#header-content ul li", 0).children("span")) }
// ఆٛͷॏෳ $("#header-content ul li", 0).$('.link-list li a')[0].click()
Ͳ͏վળ͢Δʁ
هड़γϯϓϧΛ৺͕͚Δ ਂ͗͢ΔΤϨϝϯτऔಘ $("#id").find(".class-a").find("td").find(".class-b")
هड़γϯϓϧΛ৺͕͚Δ ఆٛ͘ // ్தʹࢦఆͰ͖ͦ͏ͳattributeΛ୳͢ $("#user-td").find(".class-b") // ΤϨϝϯτΛׂ͢Δ userTd { $("#id").find(".class-a").find("td")
} column { userTd.find(".class-b") }
ϖʔδΦϒδΣΫτύλʔϯ ͷར༻ ར༻͢ΔίϯςϯπͷϝϯςφϯεੑΛ্͛ɺ࠶ ར༻͘͢͢͠ΔͨΊͷσβΠϯύλʔϯ6 6 http://www.seleniumhq.org/docs/06testdesign_considerations.jsp#page-object-design-pattern
GebͷϖʔδΦϒδΣΫτʹ ͍ͭͯৄ͘͠
GebͷϖʔδΦϒδΣΫτ PageΫϥεΛܧঝ class GebishOrgHomePage extends Page { static at =
{ title == "Sample page" } static content = { header { $("#header") } manualsMenu { module MenuModule, $("#header", 0) } } }
࠶ར༻ՄೳͳύʔπModuleʹ import geb.Module class MenuModule extends Module { static content
= { toggle { children("span") } links { $('.link-list li a') } } }
Page url at content
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
at9 at()ϝιουར༻࣌ʹ͜ͷϖʔδͷΞαʔτ͕ߦΘΕΔ to()ϝιουͰϖʔδભҠͨ͠ͱ͖atνΣοΫ͕Δ class PageWithAtChecker extends Page { static at
= { $("h1").text() == "Example" } } 9 http://www.gebish.org/manual/current/#at-checker
content ϖʔδͷཁૉΛهड़ class PageWithDiv extends Page { static content =
{ theDiv { $('div', id: 'a') } } }
Page, Moduleઐ༻ͷσΟϨΫτϦ ʹஔ͠·͠ΐ͏ root |-- src | `-- test |
|-- groovy | | |-- pages | | |-- modules | | `- xxxSpecs.groovy | `-- resources | `-- GebConfig.groovy `-- build.gradle
࿅श ϖʔδΦϒδΣΫτΛͬͯ վળͯ͠ΈΑ͏ʂ
࿅श ࠓͷςετɺ؆ܿͰͳ͍هड़ॏෳΛ͓࣋ͬͯ Γɺ·ͨมߋʹऑ͍ߏʹͳ͍ͬͯ·͢ɻ͜ΕΒ ͷΛղܾ͢Δ͘ςετίʔυΛϦϑΝΫλ Ϧϯά͍ͯͩ͘͠͞ɻ ΩʔϫʔυɿϖʔδΦϒδΣΫτύλʔϯɺ؆ܿ ͳهड़ɺϞδϡʔϧԽ step-3ͱ͍͏ϒϥϯνʹϖʔδΦϒδΣΫτͷ ܗΛ࡞ͬͨͷ͕͋Γ·͢ɻ
͔͜͜Β՝Λ Δ্Ͱͷώϯτ
ϖʔδΦϒδΣΫτͷఆٛͷํ͍Ζ͍Ζ content { // to: ͜ͷΤϨϝϯτ͕ΫϦοΫ͞Εͨͱ͖ʹConfirmPageΛ͢ // toWait: ࣍ͷϖʔδͷatνΣοΫ͕trueʹͳΔ·Ͱͭ button(to:
ConfirmPage, toWait: true) { $('button#save') } }
Θ͔Γ͍͢هड़Λ ͜ͷϘλϯͲ͜ͷϘλϯʁ to LoginPage login("user", "password") clickListButton()
Θ͔Γ͍͢هड़Λ 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
ॻ͖ํόϥόϥ // 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)
ॻ͖ํͷ౷Ұ ·ͣϖʔδΦϒδΣΫτԽ ·ͱ·ͬͨॲཧϝιουͱͯ͠ఆٛ͢Δ
ϝιουͷཻόϥόϥ // A͞Μ to HomePage menuLinks[0].click() // B͞Μ to HomePage
manualLink.click() // C͞Μ to HomePage showManual()
ͳͥɺͳʹΛ ςετ͍ͨ͠ͷ͔ʹґଘ10 తΛࢥ͍ग़͢ νʔϜͰٞ͢Δ 10 http://benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories.html
՝ʹ٧·ͬͨΒ ్தܦա͕Լهϒϥϯνʹ͋ Γ·͢ɻ https://github.com/yokohamagroovy/ geb-hands-on-project/tree/step3-hints
࠷ऴܗ ຊՈͷαϯϓϧϓϩδΣΫτ ʹ͍ۙͷʹͳΔͣɻ https://github.com/geb/geb-example- gradle ɾϖʔδɺϞδϡʔϧͷύοέʔδϯά ɾϖʔδΦϒδΣΫτͷϝιουͷΓग़͠ํɺ໋໊ҙਤతʹมߋͯ͠·͢
͓͠·͍ GebͰָ͍͠ϒϥβΦʔτϝʔγϣϯΛʂ