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
net/http/httptest.Server ͷΞϓϩʔνΛςετઓུʹ׆༻͢Δখࢁ݈Ұ / GMO PEPABO inc.2023.6.2 Go Conference 2023 Online1
View Slide
ࣗݾհٕज़෦ɹٕज़ج൫νʔϜ2018 த్ೖࣾখࢁ ݈Ұ Ken’ichiro Oyamaগ࣮͠༻తͰখ͞ͳOSSΛॻ͘ͷ͕झຯɻ● GitHub : k1LoW● Twitter : @k1LoW2
GMOϖύϘʹ͍ͭͯ3https://pepabo.com
ΞδΣϯμ• ςεταΠζྨʹ͓͚Δ net/http/httptest.Server ͷϝϦοτ• goroutineϕʔεͷMediumςετΛ͘׆༻͢Δςετઓུ• goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δ• ࣮ફͯ͠ײ͡ΔϝϦοτͱσϝϦοτ• ͓ΘΓʹ4
5ςεταΠζྨʹ͓͚Δnet/http/httptest.Server ͷϝϦοτ
6ςεταΠζྨʹ͓͚Δ net/http/httptest.Server ͷϝϦοτςεταΠζ• ςετͷ࣮ߦͱܾఆੑʹணͨ͠ςετྨ• ॻ੶ʮGoogleͷιϑτΣΞΤϯδχΞϦϯάʯΑΓ• Smallςετʢখςετʣ... ୯ҰϓϩηεʢγϯάϧεϨουʣͰ࣮ߦ͞Εͳ͚ΕͳΒͳ͍ɻsleepېࢭɻI/OېࢭɻϒϩοΫېࢭ• Mediumςετʢதςετʣ... ୯ҰϚγϯͰ࣮ߦ͞Εͳ͚ΕͳΒͳ͍ɻlocalhostҎ֎ͷγεςϜͷωοτϫʔΫݺͼग़͠ېࢭ• Largeςετʢେςετʣ... ෳϚγϯʹ·͕ͨΔςετ
7ςεταΠζྨʹ͓͚Δ net/http/httptest.Server ͷϝϦοτnet/http/httptest.Server• httptest.NewServerͰϩʔΧϧϧʔϓόοΫΞυϨε+γεςϜ͕બΜͩϙʔτͰͪड͚ΔHTTPαʔόΛىಈͰ͖Δ• HTTPαʔόgoroutineͰ࣮ߦ͞Ε͍ͯΔ
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=34goroutineϕʔεͷMediumςετ
11ςεταΠζྨʹ͓͚Δ net/http/httptest.Server ͷϝϦοτgoroutineϕʔεͷMediumςετͷϝϦοτ• net/http/httptest.ServergoroutineϕʔεͷMediumςετΛ࣮ݱͰ͖Δ• ҰൠతͳMediumςετͱൺͯߏཁૉͷཧΛGo Runtime (Scheduler) ʹͤΔ͜ͱ͕Ͱ͖ΔͷͰʢܰྔͰʣ҆ఆͨ͠ӡ༻͕ՄೳʹͳΔ• ʮίεύ͕ྑ͍ʯMediumςετͱݴ͑Δ• ผϓϩηεͰ࣮ݱ͢ΔMediumςετͱൺͯɺಉҰͷGo Runtime্Ͱ࣮ߦͰ͖ΔͨΊͷ૬ޓड͚͠ͳͲͷ࿈ܞ͕༰қʹ࣮ݱͰ͖Δ• ςετμϒϧʢϞοΫɺελϒɺεύΠͳͲʣͷ࣮͕͍͢͠
goroutineϕʔεͷMediumςετΛ͘׆༻͢Δςετઓུ12
• ࣗಈςετΛؚΉςετεΠʔτͷ༻ҙૣ͚Εૣ͍΄ͲಘΒΕΔޮՌ͕େ͖͍• ͔͠͠ɺ։ൃॳظΞϓϦέʔγϣϯͷΞʔΩςΫνϟະঢ়ଶ• ΞϓϦέʔγϣϯͷ֎ଆ͔ΒͷςετΛް͘͢Δ͜ͱͰɺΞϓϦέʔγϣϯ෦ͷΞʔΩςΫνϟมߋʹڧ͘͢Δ → Mediumςετ• ֎෦ͱͷΠϯλʔϑΣʔεͰ͋ΔAPIεΩʔϚɺσʔλϕʔεεΩʔϚɺ֎෦APIΛத৺ʹςετΛΈཱ͍ͯͯ͘• goroutineϕʔεͷMediumςετ༗ޮͳΞϓϩʔν13goroutineϕʔεͷMediumςετΛ͘׆༻͢ΔςετઓུΞϓϦέʔγϣϯͷΞʔΩςΫνϟະঢ়ଶͰ༗ޮͳςετઓུΛߟ͑Δ
14goroutineϕʔεͷMediumςετΛ͘׆༻͢ΔςετઓུςετରͷΞϓϦέʔγϣϯͱςεταΠζͷΠϝʔδ• ઐ༻ͷDBΛ࣋ͪଞͷίϯϙʔωϯτͱ࿈ಈ͠ͳ͕Βಈ͘APIαʔόΛྫʹͱΔ• Smallςετςετର͕APIαʔό෦ɻඞཁʹԠͯ͡ςετμϒϧΛ༻ҙɻ• MediumςετAPIαʔόઐ༻DB·ͰΛςετσʔλϕʔεͱͯ͠༻ҙɻͦͷଞςετμϒϧΛ༻ҙɻ• Largeςετίϯϙʔωϯτશମͷಈ࡞͕ର
15goroutineϕʔεͷMediumςετΛ͘׆༻͢ΔςετઓུΞʔΩςΫνϟະঢ়ଶͷΞϓϦέʔγϣϯ• ։ൃॳظʹ͓͍ͯSmallςετ·ͩݻఆతͰͳ͍
• ࣗಈςετΛؚΉςετεΠʔτͷ༻ҙૣ͚Εૣ͍΄ͲಘΒΕΔޮՌ͕େ͖͍• ͔͠͠ɺ։ൃॳظΞϓϦέʔγϣϯͷΞʔΩςΫνϟະঢ়ଶ• ΞϓϦέʔγϣϯͷ֎ଆ͔ΒͷςετΛް͘͢Δ͜ͱͰɺΞϓϦέʔγϣϯ෦ͷΞʔΩςΫνϟมߋʹڧ͘͢Δ → Mediumςετ• ֎෦ͱͷΠϯλʔϑΣʔεͰ͋ΔAPIεΩʔϚɺσʔλϕʔεεΩʔϚɺ֎෦APIΛத৺ʹςετΛΈཱ͍ͯͯ͘• goroutineϕʔεͷMediumςετ༗ޮͳΞϓϩʔν• ίεύ͕ྑ͍ɻ҆ఆ͍ͯ͠ΔɻςετμϒϧΛ࣮ࢪ͍͢͠16goroutineϕʔεͷMediumςετΛ͘׆༻͢ΔςετઓུΞϓϦέʔγϣϯͷΞʔΩςΫνϟະঢ়ଶͰ༗ޮͳςετઓུΛߟ͑Δ
17goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δ
18goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢ΔgoroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δ• goroutineϕʔεͷMediumςετ༗ޮͳΞϓϩʔν• ΞϓϦέʔγϣϯͷ֎ଆΛΈΔͱϓϩτίϧHTTPʹݶΒͣɺgRPCɺDBʢΫΤϦʣɺSMTPͳͲ͕ߟ͑ΒΕΔ → Mediumςετͷద༻ൣғ͍• net/http/httptestύοέʔδҎ֎ʹύοέʔδΛ༻ҙͯ͠͞ΒʹޮՌΛ্͛Δ
19goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δgithub.com/k1LoW/httpstub• ҙͷϨεϙϯεΛฦ͢HTTPαʔόΛ؆୯ʹΈཱͯͯىಈ͢Δ͜ͱ͕Ͱ͖Δ• ͞·͟·ͳ݅ϨεϙϯεΛઃఆͰ͖ΔͷͰҙͷHTTPαʔόΛߏஙͰ͖Δ• OpenAPI Spec v3ͷDocumentΛಡΈࠐΜͰϦΫΤετͱϨεϙϯεͷόϦσʔγϣϯ͕Ͱ͖Δ• OpenAPI Spec v3ͷDocumentͷ examples: ηΫγϣϯͷΛͬͯϨεϙϯεΛฦ͢͜ͱ͕Ͱ͖Δ
• ҙͷϨεϙϯεΛฦ͢HTTPαʔόΛىಈͯ͠ςετʹ༻͢Δ20goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δgithub.com/k1LoW/httpstub
• OpenAPI Spec v3 Documentͷ examples: ηΫγϣϯͷΛͬͯϨεϙϯεΛฦ͢• GET /api/v1/users examples: ηΫγϣϯͷ 2xx ͳεςʔλεͷΛͬͯϨεϙϯεΛฦ͢21goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δgithub.com/k1LoW/httpstub
22goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δgithub.com/k1LoW/grpcstub• ҙͷϨεϙϯεΛฦ͢gRPCαʔόΛ؆୯ʹΈཱͯͯىಈ͢Δ͜ͱ͕Ͱ͖Δ• ͞·͟·ͳ݅ϨεϙϯεΛઃఆͰ͖ΔͷͰ΄΅ҙͷgRPCαʔόΛߏஙͰ͖Δ• protoϑΝΠϧͷఆٛΛ༻ͯ͠ϦΫΤετͱϨεϙϯεͷόϦσʔγϣϯ͕Ͱ͖Δ• protoϑΝΠϧͷఆٛΛ༻ͯ͠ಈతʹϨεϙϯεΛΈཱͯͯฦ͢͜ͱ͕Ͱ͖Δ
23goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δgithub.com/k1LoW/grpcstub• ҙͷϨεϙϯεΛฦ͢gRPCαʔόΛىಈͯ͠ςετʹ༻͢Δ
• protoϑΝΠϧͷఆٛΛ༻ͯ͠ಈతʹϨεϙϯεΛΈཱͯͯฦ͢• routeguide.RouteGuide/GetFeature ͚ͩಈతʹϨεϙϯεΛΈཱͯͯฦ͢24goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δgithub.com/k1LoW/grpcstub
• ҙͷϑΟʔϧυ໊͚ͩಠࣗʹੜؔΛઃఆͯ͠ಈతʹϨεϙϯεΛΈཱͯͯฦ͢25goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δgithub.com/k1LoW/grpcstub
26goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δgithub.com/k1LoW/smtptest• net/http/httptest.Serverͱಉ͡Α͏ͳ͍উखͰSMTPαʔόΛىಈ͢Δ͜ͱ͕Ͱ͖Δ• ड৴ͨ͠ϝʔϧΛ֬ೝ͢Δ͜ͱ͕Ͱ͖Δ
27goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δgithub.com/k1LoW/smtptest• SMTPαʔόΛىಈͯ͠ςετʹ༻͢Δ
28goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δgithub.com/k1LoW/smtptest• ड৴ͨ͠ϝʔϧΛ֬ೝ͢Δ͜ͱ͕Ͱ͖Δ
29goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δgithub.com/k1LoW/runn• γφϦΦΛYAMLͰॻ͍ͯͦΕΛͱʹૢ࡞ʢΦϖϨʔγϣϯʣΛࣗಈԽͰ͖Δ• HTTPɺgRPCɺDatabaseʢSQLʣɺChrome DevTools ProtocolɺҙίϚϯυͷ࣮ߦʢϩʔΧϧ/SSHʣͳͲʹରԠ
• runn1ͭҎ্ͷγφϦΦΛ࣮ߦͯ͠ɺͦΕͧΕͷޭ/ࣦഊΛΈΔ• 1ͭͷγφϦΦ1ͭҎ্ͷεςοϓ͔Βߏ͞Ε͍ͯΔ• 1γφϦΦ1YAMLϑΝΠϧʹͳ͍ͬͯΔʢϥϯϒοΫͱݺΜͰ͍Δʣ• γφϦΦ͝ͱʹϥϯφʔͱݺΜͰ͍Δεςοϓ࣮ߦίϯϙʔωϯτΛఆٛ͠ɺͦͷϥϯφʔΛ֤ͬͯεςοϓΛ࣮ߦ͍ͯ͘͠• ϥϯφʔʹγφϦΦʹఆ͕ٛඞཁͳ௨ৗͷϥϯφʔͱɺطʹrunnͰ༻ҙ͍ͯ͠ΔϏϧτΠϯϥϯφʔͷ2छྨ͕͋Δ• ϥϯφʔ: HTTPϥϯφʔɺDBϥϯφʔɺgRPCϥϯφʔɺCDPϥϯφʔɺSSHϥϯφʔ• ϏϧτΠϯϥϯφʔ: ExecϥϯφʔɺTestϥϯφʔɺDumpϥϯφʔɺIncludeϥϯφʔɺBindϥϯφʔ30goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢ΔrunnͷΞʔΩςΫνϟ
31goroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δϥϯφʔͷઃఆมͷઃఆɹɹɹɹ֤εςοϓ0123
32More about runn• runnʹ͍ͭͯɺൃදεϥΠυZennϒοΫ͕͋ΔͷͰੋඇ͝ཡ͍ͩ͘͞• https://speakerdeck.com/k1low/stac2022• https://zenn.dev/k1low/books/runn-cookbookgoroutineϕʔεͷMediumςετͷ࡞Λαϙʔτ͢Δ
33࣮ફͯ͠ײ͡ΔϝϦοτͱσϝϦοτ
• ҰൠతͳMediumςετͱൺΔͱɺಉ͡Goͷίʔυϕʔεʹด͓ͯ͡Γೝෛՙ͕খ͘͞ײ͡Δ• σʔλϕʔεʹ͍ͭͯผϓϩηεͳͷͰैདྷ௨Γ• ʮClientΛϞοΫ͢ΔςετʯΑΓɺຊདྷͷڍಈʹ͍ۙʮServer-ClientͰ࣮ࡍʹ௨৴͢Δςετʯͷ΄͏͕ײత͔ͯ͠ͳ͍• 1γφϦΦ͋ͨΓͷΧόϨοδ͕େ͖͘ɺ݁ՌϦϑΝΫλϦϯάͷੑ͕େ͖͘ͳ͍ͬͯΔ• γφϦΦͷ֦ॆYAMLΛॻ͚ͩ͘Ͱྑ͍ɻҰΈࠐΜͰ͠·͑ɺ͋ͱYAMLΛॻ͚ͩ͘ʹͳΔ• γφϦΦ͕OpenAPI SpecϥΠΫͰ͋Δ͜ͱ͔ΒΤϯδχΞʹͱͬͯಡΈ͘͢ɺͦͷ··ΦϯϘʔσΟϯάʹʹཱͬͨʢAPIར༻ଆͷઆ໌ͳͲʣɻॻ͖͍͢=ಡΈ͍͢34࣮ફͯ͠ײ͡ΔϝϦοτͱσϝϦοτϝϦοτ
• MediumςετSmallςετͱൺΔͱ࣮ߦ͕͍࣌ؒɻMediumςετ͕༰қʹ֦ॆͰ͖ΔΑ͏ʹͳͬͨ݁Ռɺશମͷςετ࣮ߦ͕࣌ؒେ͖͘ͳΓ͕ͪ• ςετσʔλϕʔεΛฒྻԽ͢ΔͳͲͯ͠ର߅͍ͯ͠Δ• ΞϓϦέʔγϣϯ֎෦ʹؾܰʹελϒαʔόΛཱͯͯςετ͕Ͱ͖ΔΑ͏ʹͳΔ͜ͱͰɺΞϓϦέʔγϣϯࣗମͷςετ༰қੑ͕Լ͕Γ͕ͪ• UnitςετΛૄ͔ʹ͍͚ͯ͠ͳ͍ͷ໌Β͔ͳͷͰɺΞʔΩςΫνϟະঢ়ଶͱ͍͑ςετ༰қੑ୲อ͍ͯ͘͠35࣮ફͯ͠ײ͡ΔϝϦοτͱσϝϦοτσϝϦοτ
͓ΘΓʹ36
• ϓϩμΫτͷ৽ن։ൃ࣌ͷΞʔΩςΫνϟͷະঢ়ଶʹର߅͢Δखஈͱͯ͠ɺgoroutineϕʔεͷMediumςετΛ͘׆༻͢ΔํΛऔͬͨ• ࠓޙɺʮن͕େ͖͘ͳΔʯʮΞʔΩςΫνϟ͕҆ఆ͢ΔʯͳͲͷཁҼʹΑΓςετߏ͕มΘΔ͜ͱେ͍ʹ͋Γ͏Δ͕ɺগͳ͘ͱݱ࣌ʹ͓͍ͯѱ͘ͳ͍அͩͬͨ37͓ΘΓʹ͓ΘΓʹ
Thank You!Thank You!38