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
サービス間をテストするフレームワーク集
Search
Shin'ya Ueoka
December 15, 2021
Technology
0
270
サービス間をテストするフレームワーク集
2021-12-15 開催 JJUGナイトセミナー「おうちで!ビール片手にLT大会!」でお話した資料です
https://jjug.doorkeeper.jp/events/129543
Shin'ya Ueoka
December 15, 2021
Tweet
Share
More Decks by Shin'ya Ueoka
See All by Shin'ya Ueoka
英語ができなかった自分達が、グローバルチーム立ち上げに挑戦!?
ueokande
1
740
技術書典12協賛企業サイボウズゲストトーク
ueokande
0
230
kintone.comを支える技術
ueokande
0
180
SLO策定とアラート設定までの長い道のり
ueokande
6
4.4k
オンラインイベントを 半年運営して気づいたこと
ueokande
0
100
インフラ開発チームがプロダクトチームに体験入部したはなし
ueokande
1
650
kintone.comのAWS移行と その舞台裏
ueokande
4
4.7k
OSSでキレイな本を 作りたい話
ueokande
0
230
サイボウズとOSSの付き合い方
ueokande
0
750
Other Decks in Technology
See All in Technology
マルチプロダクトな開発組織で 「開発生産性」に向き合うために試みたこと / Improving Multi-Product Dev Productivity
sugamasao
1
310
Shopifyアプリ開発における Shopifyの機能活用
sonatard
4
250
ドメインの本質を掴む / Get the essence of the domain
sinsoku
2
160
いざ、BSC討伐の旅
nikinusu
2
780
AGIについてChatGPTに聞いてみた
blueb
0
130
障害対応指揮の意思決定と情報共有における価値観 / Waroom Meetup #2
arthur1
5
480
データプロダクトの定義からはじめる、データコントラクト駆動なデータ基盤
chanyou0311
2
330
なぜ今 AI Agent なのか _近藤憲児
kenjikondobai
4
1.4k
CDCL による厳密解法を採用した MILP ソルバー
imai448
3
140
10XにおけるData Contractの導入について: Data Contract事例共有会
10xinc
6
660
BLADE: An Attempt to Automate Penetration Testing Using Autonomous AI Agents
bbrbbq
0
320
OTelCol_TailSampling_and_SpanMetrics
gumamon
1
200
Featured
See All Featured
Building Flexible Design Systems
yeseniaperezcruz
327
38k
Why You Should Never Use an ORM
jnunemaker
PRO
54
9.1k
Scaling GitHub
holman
458
140k
Done Done
chrislema
181
16k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
1.9k
Making the Leap to Tech Lead
cromwellryan
133
8.9k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
229
52k
Rails Girls Zürich Keynote
gr2m
94
13k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
Facilitating Awesome Meetings
lara
50
6.1k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
Adopting Sorbet at Scale
ufuk
73
9.1k
Transcript
αʔϏεؒΛςετ͢Δ ϑϨʔϜϫʔΫू αΠϘζגࣜձࣾ ্Ԭ ਅ (@ueokande) 2021-12-15. JJUGφΠτηϛφʔʮ͓͏ͪͰʂϏʔϧยखʹLTେձʂʯ
Me • αΠϘζגࣜձࣾ • άϩʔόϧ͚B2BαʔϏεͷ όοΫΤϯυΛ࡞͍ͬͯ·͢ • ݱͰKotlin +
Spring Boot͕ϝΠϯ 2
ຊͷ͓ • ෳαʔϏε͕ϓϩμΫτΛߏ͢Δ࣌ʢMicroservice, SOA, …ʣ • αʔϏεؒͷΓऔΓΛͲ͏ͬͯςετ͢Δ͔ʁ • REST API௨৴ͷݕূʹཱͭϑϨʔϜϫʔΫΛհ
3 αʔϏε" αʔϏε# )551ϦΫΤετ +40/
հϑϨʔϜϫʔΫ • Mockito … ΫϥΠΞϯτͷ࣮ͱϏδωεϩδοΫΛ • WireMock … ϞοΫαʔόʔΛཱͯͯΫϥΠΞϯτ࣮Λςετ •
Pact … αʔϏεؒ௨৴ͷAPIͷมߋΛݕ 4
Mockito • JavaͷΠϯλʔϑΣΠεɺΫϥεΛϞοΫ • ΫϥΠΞϯτ࣮ΛϞοΫͯ͠ϏδωεϩδοΫ୯ମΛςετ 5 αʔϏε" αʔϏε# )551ϦΫΤετ +40/
͜͜ΒΜͷςετ
Mockito͔͍͔ͭͨ • MockitoΛͬͯΫϥΠΞϯτ࣮ͷϞοΫΛهड़ • ϩδοΫ୯ମΛςε͠ɺΫϥΠΞϯτར༻͞Ε͔ͨݕূ 6 val client = mock<BClient>()
whenever(client.getItems()) .thenReturn(Arrays.asList(item1, …)) val logic = ItemLogic(bClient) val actual = sut.calc() assertEquals("...", actual) verify(bClient, times(1)).getItems() ϞοΫΫϥΠΞϯτͷ࡞ ϞοΫΫϥΠΞϯτΛͯ͠ ରΫϥεʢϏδωεϩδοΫʣͷݕূ MockΫϥΠΞϯτ͕ར༻͞Ε͔ͨݕূ ※ Kotlinͷίʔυྫ
WireMock • ϞοΫͷϨεϙϯεΛฦ͢HTTPαʔόʔΛཱͯΔ • HTTPαʔόʔϦΫΤετΛهͯ͠ظ͢ΔϦΫΤετ͔ݕূ 7 αʔϏε" αʔϏε# )551ϦΫΤετ +40/
͜͜ΒΜͷςετ
WireMock͔͍͔ͭͨ • ϦΫΤετʹର͢ΔϨεϙϯεΛఆٛͯ͠ϞοΫαʔόʔΛىಈ • ΫϥΠΞϯτ࣮ͱɺൃߦ͞ΕͨϦΫΤετ͕ਖ਼͍͔͠ݕূ 8 val server = WireMockServer(12345)
server.stubFor( WireMock.post(“/v1/item/1“) .willReturn(aResponse().withBody("{ ... }”))) server.start() val client = BClientImpl("127.0.0.1", 12345) List<Items> item = bClient.getItem(1L) assertEquals(10, actual.size) server.verify( postRequestedFor(urlPathEqualTo("/v1/items")) .withRequestBody(equalToJson("{ ... }")) ) ϞοΫαʔόʔͷ࡞ͱىಈ ϦΫΤετͷൃߦͱΓͷݕূ ࣮ߦ͞ΕͨϦΫΤετͷݕূ
Pact/Pact JVM • αʔϏεؒͷAPIͷৼΔ͍Λ୲อ͢ΔϑϨʔϜϫʔΫ 1. ίϯγϡʔϚʔɺར༻APIͷظ͢ΔϦΫΤετɾϨεϙϯεʢܖʣΛఆٛ 2. ίϯγϡʔϚʔɺΫϥΠΞϯτ࣮͕ܖͷ௨ΓʹৼΔ͏͔ݕূ 3. ϓϩόΠμʔɺܖͷϦΫΤετʹର͠ظͷϨεϙϯεΛฦ͔͢ݕূ
9 αʔϏε" $POTVNFS αʔϏε# 1SPWJFS ܖ ϞοΫ ϞοΫ ϦΫΤετ Ϩεϙϯε ϦΫΤετ Ϩεϙϯε ࡞ ݕূ ᶃ ᶄ ᶅ json
Pact JVM͍ํʛܖͷఆٛ • ίϯγϡʔϚʔଆ͕ར༻͢ΔAPIͷಈ࡞ΛDLSͰఆٛ 10 @Pact(provider = “service-b", consumer =
“service-a") fun getItemPact(builder: PactDslWithProvider): V4Pact { builder .given("item1 and item2 exist") .uponReceiving("get all items") .method(“GET”).matchPath(“/v1/item/1“) .willRespondWith().status(200).body( LambdaDsl.newJsonBody { it -> it.`object` { it.stringType(“name", “pen") it.numberType(“cost", 100) } } ) } ϦΫΤετʹର͢Δظ͢ΔϨεϙϯεΛఆٛ
Pact JVM͍ํʛίϯγϡʔϚʔͷݕূ • هड़ͨ͠ܖʹରͯ͠ΫϥΠΞϯτ࣮͕ਖ਼͘͠ৼΔ͏͔ݕূ • ϞοΫαʔόʔ͕ىಈͯ͠HTTPϦΫΤετΛهɾݕূ 11 @Test @PactTestFor(providerName =
“service-b", pactMethod = "getItemPact") fun getItem(mockServer: MockServer) { val client = BClientImpl(mockServer.getUrl()) val item = client.getItems(1L) assertEquals("pen", item.name) assertEquals(100, item.cost) }
Pact JVM͍ํʛϓϩόΠμʔͷݕূ • ϓϩόΠμʔ͕ܖ௨ΓͷϨεϙϯεΛฦ͔͢ݕূ • ܖΛͱʹPactϑϨʔϜϫʔΫ͕ࣗಈͰςετ 12 @ExtendWith(SpringExtension::class) @Provider(“service-b") @SpringBootTest(webEnvironment
= SpringBootTest.WebEnvironment.RANDOM_PORT) class ContractTest { @TestTemplate @ExtendWith(PactVerificationInvocationContextProvider::class) fun testTemplate( pact: Pact, interaction: Interaction, context: PactVerificationContext ) { context.verifyInteraction() } }
·ͱΊ • ਖ਼͍͠ϨΠϠʔͰϞοΫͯ͠ਖ਼͘͠ςετ • Mockito … αʔϏεͷΠϯλʔϑΣΠεͱ࣮ΫϥεΛ • WireMock …
ϦΫΤετɾϨεϙϯεΛϞοΫ • Pact … ৗʹมԽ͠ଓ͚ΔαʔϏεؒͷAPIͰഁյతมߋ͕ͳ͍͔νΣοΫ • ͍͠ϨΠϠʔςετɾࣗಈԽͯ҆͠৺ײΛಘΑ͏ 13