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
380
横浜タネマキで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
960
Make Work Visible in Agile2018 #LINE_DM
poohsunny
1
380
タウンワークをドライブさせるためになんちゃってアジャイルをやめた話 #devsumi #devsumiB / devsumi2018
poohsunny
30
45k
1 test 1 assert ?
poohsunny
0
350
XUTPから学ぶ記述性の高いユニットテスト 〜俺たちを助けるユニットテストへ〜 / xUTP in #xpjug
poohsunny
4
5.1k
XCUITestする時のTIPs 〜あなたを助けるXCUITestへ〜
poohsunny
0
3k
コードに思いが伝わる
poohsunny
0
230
The "yummy" licenses.
poohsunny
0
150
ブラウザテストをサクサク自動化するためのGeb実践入門 #jjug_ccc
poohsunny
21
6.9k
Other Decks in Technology
See All in Technology
最速最小からはじめるデータプロダクト / Data Product MVP
amaotone
5
730
visionOSでの空間表現実装とImmersive Video表示について / ai-immersive-visionos
cyberagentdevelopers
PRO
1
110
Java x Spring Boot Warm up
kazu_kichi_67
2
490
グローバル展開を見据えたサービスにおける機械翻訳プラクティス / dp-ai-translating
cyberagentdevelopers
PRO
1
150
ガバメントクラウド単独利用方式におけるIaC活用
techniczna
3
270
初心者に Vue.js を 教えるには
tsukuha
5
390
AWS CDKでデータリストアの運用、どのように設計する?~Aurora・EFSの実践事例を紹介~/aws-cdk-data-restore-aurora-efs
mhrtech
4
640
新卒1年目が向き合う生成AI事業の開発を加速させる技術選定 / ai-web-launcher
cyberagentdevelopers
PRO
7
1.5k
なんで、私がAWS Heroに!? 〜社外の広い世界に一歩踏み出そう〜
minorun365
PRO
6
1.1k
신뢰할 수 있는 AI 검색 엔진을 만들기 위한 Liner의 여정
huffon
0
310
CyberAgent 生成AI Deep Dive with Amazon Web Services / genai-aws
cyberagentdevelopers
PRO
1
480
Jr. Championsになって、強く連携しながらAWSをもっと使いたい!~AWSに対する期待と行動~
amixedcolor
0
190
Featured
See All Featured
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
32
1.8k
Ruby is Unlike a Banana
tanoku
96
11k
Code Review Best Practice
trishagee
64
17k
Typedesign – Prime Four
hannesfritz
39
2.4k
Happy Clients
brianwarren
97
6.7k
Agile that works and the tools we love
rasmusluckow
327
21k
GraphQLの誤解/rethinking-graphql
sonatard
66
9.9k
The Art of Programming - Codeland 2020
erikaheidi
51
13k
Making the Leap to Tech Lead
cromwellryan
132
8.9k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
How to Think Like a Performance Engineer
csswizardry
19
1.1k
Reflections from 52 weeks, 52 projects
jeffersonlam
346
20k
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Ͱָ͍͠ϒϥβΦʔτϝʔγϣϯΛʂ