Share
Embed
net/http/httptest.Server のアプローチをテスト戦略に活用する / Go Conference 2023
https://gocon.jp/2023/sessions/A13-S/
https://github.com/k1LoW/httpstub
https://github.com/k1LoW/grpcstub
https://github.com/k1LoW/smtptest
https://github.com/k1LoW/runn
Ken’ichiro Oyama
June 02, 2023
Transcript
38 slides
-
net/http/httptest.Server ͷΞϓϩʔνΛ ςετઓུʹ׆༻͢Δ খࢁ݈Ұ / GMO PEPABO inc. 2023.6.2 Go
Conference 2023 Online 1 -
ࣗݾհ ٕज़෦ɹٕज़ج൫νʔϜ 2018 த్ೖࣾ খࢁ ݈Ұ Ken’ichiro Oyama গ࣮͠༻తͰখ͞ͳOSSΛॻ͘ͷ͕झຯɻ •
GitHub : k1LoW • Twitter : @k1LoW 2 -
6 ςεταΠζྨʹ͓͚Δ net/http/httptest.Server ͷϝϦοτ ςεταΠζ • ςετͷ࣮ߦͱܾఆੑʹணͨ͠ςετྨ • ॻ੶ʮGoogleͷιϑτΣΞΤϯδχΞϦϯάʯΑΓ •
Smallςετʢখςετʣ... ୯ҰϓϩηεʢγϯάϧεϨουʣͰ࣮ߦ͞Εͳ͚ΕͳΒͳ ͍ɻsleepېࢭɻI/OېࢭɻϒϩοΫېࢭ • Mediumςετʢதςετʣ... ୯ҰϚγϯͰ࣮ߦ͞Εͳ͚ΕͳΒͳ͍ɻlocalhostҎ֎ͷγε ςϜͷωοτϫʔΫݺͼग़͠ېࢭ • Largeςετʢେςετʣ... ෳϚγϯʹ·͕ͨΔςετ -
8 ςεταΠζྨʹ͓͚Δ net/http/httptest.Server ͷϝϦοτ HTTPΫϥΠΞϯτ-αʔόؒͷςετΛྫʹͨ͠ൺֱ ʢDockerͳͲʣผϓϩηεͰHTTPαʔόΛىಈͯ͠ςετ͢Δ߹ͱnet/http/httptest.ServerΛ༻ ͯ͠ςετ͢Δ߹Λൺֱ͢Δ • Mediumςετ •
ߏཁૉͷཧGo Runtime • ཧΛGo RuntimeʹͤΔ͜ͱ͕Ͱ͖Δ • Mediumςετ • ߏཁૉͷཧϝΠϯϓϩηε • ಠࣗʹཧΛ͢Δඞཁ͕͋Δ -
9 ςεταΠζྨʹ͓͚Δ net/http/httptest.Server ͷϝϦοτ Takuto Wada. “αόϯφศΓʙࣗಈςετʹؔ͢Δ࿈ࡌͰಘΒΕͨݟͷ·ͱΊʢ20235݄൛ʣʙ / Automated Test
Knowledge from Savanna 202305 edition” https://speakerdeck.com/twada/automated-test-knowledge-from-savanna-202305-edition?slide=34 -
10 ςεταΠζྨʹ͓͚Δ net/http/httptest.Server ͷϝϦοτ Takuto Wada. “αόϯφศΓʙࣗಈςετʹؔ͢Δ࿈ࡌͰಘΒΕͨݟͷ·ͱΊʢ20235݄൛ʣʙ / Automated Test
Knowledge from Savanna 202305 edition” https://speakerdeck.com/twada/automated-test-knowledge-from-savanna-202305-edition?slide=34 goroutineϕʔεͷMediumςετ -
11 ςεταΠζྨʹ͓͚Δ net/http/httptest.Server ͷϝϦοτ goroutineϕʔεͷMediumςετͷϝϦοτ • net/http/httptest.ServergoroutineϕʔεͷMediumςετΛ࣮ݱͰ͖Δ • ҰൠతͳMediumςετͱൺͯߏཁૉͷཧΛGo Runtime
(Scheduler) ʹͤΔ͜ͱ͕Ͱ ͖ΔͷͰʢܰྔͰʣ҆ఆͨ͠ӡ༻͕ՄೳʹͳΔ • ʮίεύ͕ྑ͍ʯMediumςετͱݴ͑Δ • ผϓϩηεͰ࣮ݱ͢ΔMediumςετͱൺͯɺಉҰͷGo Runtime্Ͱ࣮ߦͰ͖ΔͨΊͷ૬ ޓड͚͠ͳͲͷ࿈ܞ͕༰қʹ࣮ݱͰ͖Δ • ςετμϒϧʢϞοΫɺελϒɺεύΠͳͲʣͷ࣮͕͍͢͠ -
• ࣗಈςετΛؚΉςετεΠʔτͷ༻ҙૣ͚Εૣ͍΄ͲಘΒΕΔޮՌ͕େ͖͍ • ͔͠͠ɺ։ൃॳظΞϓϦέʔγϣϯͷΞʔΩςΫνϟະঢ়ଶ • ΞϓϦέʔγϣϯͷ֎ଆ͔ΒͷςετΛް͘͢Δ͜ͱͰɺΞϓϦέʔγϣϯ෦ͷ ΞʔΩςΫνϟมߋʹڧ͘͢Δ → Mediumςετ •
֎෦ͱͷΠϯλʔϑΣʔεͰ͋ΔAPIεΩʔϚɺσʔλϕʔεεΩʔϚɺ֎෦ APIΛத৺ʹςετΛΈཱ͍ͯͯ͘ • goroutineϕʔεͷMediumςετ༗ޮͳΞϓϩʔν 13 goroutineϕʔεͷMediumςετΛ͘׆༻͢Δςετઓུ ΞϓϦέʔγϣϯͷΞʔΩςΫνϟະঢ়ଶͰ༗ޮͳςετઓུΛߟ͑Δ -
14 goroutineϕʔεͷMediumςετΛ͘׆༻͢Δςετઓུ ςετରͷΞϓϦέʔγϣϯͱςεταΠζͷΠϝʔδ • ઐ༻ͷDBΛ࣋ͪଞͷίϯϙʔωϯτͱ࿈ ಈ͠ͳ͕Βಈ͘APIαʔόΛྫʹͱΔ • Smallςετςετର͕APIαʔό ෦ɻඞཁʹԠͯ͡ςετμϒϧΛ༻ҙɻ •
MediumςετAPIαʔόઐ༻DB·Ͱ Λςετσʔλϕʔεͱͯ͠༻ҙɻͦͷ ଞςετμϒϧΛ༻ҙɻ • Largeςετίϯϙʔωϯτશମͷಈ ࡞͕ର -
• ࣗಈςετΛؚΉςετεΠʔτͷ༻ҙૣ͚Εૣ͍΄ͲಘΒΕΔޮՌ͕େ͖͍ • ͔͠͠ɺ։ൃॳظΞϓϦέʔγϣϯͷΞʔΩςΫνϟະঢ়ଶ • ΞϓϦέʔγϣϯͷ֎ଆ͔ΒͷςετΛް͘͢Δ͜ͱͰɺΞϓϦέʔγϣϯ෦ͷ ΞʔΩςΫνϟมߋʹڧ͘͢Δ → Mediumςετ •
֎෦ͱͷΠϯλʔϑΣʔεͰ͋ΔAPIεΩʔϚɺσʔλϕʔεεΩʔϚɺ֎෦ APIΛத৺ʹςετΛΈཱ͍ͯͯ͘ • goroutineϕʔεͷMediumςετ༗ޮͳΞϓϩʔν • ίεύ͕ྑ͍ɻ҆ఆ͍ͯ͠ΔɻςετμϒϧΛ࣮ࢪ͍͢͠ 16 goroutineϕʔεͷMediumςετΛ͘׆༻͢Δςετઓུ ΞϓϦέʔγϣϯͷΞʔΩςΫνϟະঢ়ଶͰ༗ޮͳςετઓུΛߟ͑Δ -
18 goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δ goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δ • goroutineϕʔεͷMediumςετ༗ޮͳΞϓϩʔν • ΞϓϦέʔγϣϯͷ֎ଆΛΈΔͱϓϩτίϧHTTPʹݶΒͣɺgRPCɺDBʢΫΤϦʣɺSMTP ͳͲ͕ߟ͑ΒΕΔ → Mediumςετͷద༻ൣғ͍
• net/http/httptestύοέʔδҎ֎ʹύοέʔδΛ༻ҙͯ͠͞ΒʹޮՌΛ্͛Δ -
19 goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δ github.com/k1LoW/httpstub • ҙͷϨεϙϯεΛฦ͢HTTPαʔόΛ؆୯ʹΈཱͯͯىಈ͢Δ͜ͱ͕Ͱ͖Δ • ͞·͟·ͳ݅ϨεϙϯεΛઃఆͰ͖ΔͷͰҙͷHTTPαʔόΛߏஙͰ͖Δ • OpenAPI Spec
v3ͷDocumentΛಡΈࠐΜͰϦΫΤετͱϨεϙϯεͷόϦσʔγϣϯ͕Ͱ͖Δ • OpenAPI Spec v3ͷDocumentͷ examples: ηΫγϣϯͷΛͬͯϨεϙϯεΛฦ͢͜ͱ͕Ͱ ͖Δ -
• OpenAPI Spec v3 Documentͷ examples: ηΫγϣϯͷΛͬͯϨεϙϯεΛฦ͢ • GET /api/v1/users
examples: ηΫγϣϯͷ 2xx ͳεςʔλεͷΛͬͯϨεϙϯεΛฦ͢ 21 goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δ github.com/k1LoW/httpstub -
• runn1ͭҎ্ͷγφϦΦΛ࣮ߦͯ͠ɺͦΕͧΕͷޭ/ࣦഊΛΈΔ • 1ͭͷγφϦΦ1ͭҎ্ͷεςοϓ͔Βߏ͞Ε͍ͯΔ • 1γφϦΦ1YAMLϑΝΠϧʹͳ͍ͬͯΔʢϥϯϒοΫͱݺΜͰ͍Δʣ • γφϦΦ͝ͱʹϥϯφʔͱݺΜͰ͍Δεςοϓ࣮ߦίϯϙʔωϯτΛఆٛ͠ɺͦͷϥϯφʔΛ֤ͬͯε ςοϓΛ࣮ߦ͍ͯ͘͠ •
ϥϯφʔʹγφϦΦʹఆ͕ٛඞཁͳ௨ৗͷϥϯφʔͱɺطʹrunnͰ༻ҙ͍ͯ͠ΔϏϧτΠϯϥϯφʔͷ2 छྨ͕͋Δ • ϥϯφʔ: HTTPϥϯφʔɺDBϥϯφʔɺgRPCϥϯφʔɺCDPϥϯφʔɺSSHϥϯφʔ • ϏϧτΠϯϥϯφʔ: ExecϥϯφʔɺTestϥϯφʔɺDumpϥϯφʔɺIncludeϥϯφʔɺBindϥϯφʔ 30 goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δ runnͷΞʔΩςΫνϟ -
• ҰൠతͳMediumςετͱൺΔͱɺಉ͡Goͷίʔυϕʔεʹด͓ͯ͡Γೝෛՙ͕খ͘͞ײ͡Δ • σʔλϕʔεʹ͍ͭͯผϓϩηεͳͷͰैདྷ௨Γ • ʮClientΛϞοΫ͢ΔςετʯΑΓɺຊདྷͷڍಈʹ͍ۙʮServer-ClientͰ࣮ࡍʹ௨৴͢Δςετʯ ͷ΄͏͕ײత͔ͯ͠ͳ͍ • 1γφϦΦ͋ͨΓͷΧόϨοδ͕େ͖͘ɺ݁ՌϦϑΝΫλϦϯάͷੑ͕େ͖͘ͳ͍ͬͯΔ •
γφϦΦͷ֦ॆYAMLΛॻ͚ͩ͘Ͱྑ͍ɻҰΈࠐΜͰ͠·͑ɺ͋ͱYAMLΛॻ͚ͩ͘ʹͳ Δ • γφϦΦ͕OpenAPI SpecϥΠΫͰ͋Δ͜ͱ͔ΒΤϯδχΞʹͱͬͯಡΈ͘͢ɺͦͷ··ΦϯϘʔ σΟϯάʹʹཱͬͨʢAPIར༻ଆͷઆ໌ͳͲʣɻॻ͖͍͢=ಡΈ͍͢ 34 ࣮ફͯ͠ײ͡ΔϝϦοτͱσϝϦοτ ϝϦοτ