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
mockgenによるモック生成を高速化するツール bulkmockgenのご紹介 / Kyot...
Search
utagawa kiki
July 14, 2023
Programming
2
2.4k
mockgenによるモック生成を高速化するツール bulkmockgenのご紹介 / Kyoto.go #43
Kyoto.go #43
https://kyotogo.connpass.com/event/287778/
utagawa kiki
July 14, 2023
Tweet
Share
More Decks by utagawa kiki
See All by utagawa kiki
go test -json そして testing.T.Attr / Kyoto.go #63
utgwkk
1
150
自動で //nolint を挿入する取り組み / Gopher's Gathering
utgwkk
1
1k
ゆるやかにgolangci-lintのルールを強くする / Kyoto.go #56
utgwkk
2
2.3k
君たちはどうコードをレビューする (される) か / 大吉祥寺.pm
utgwkk
21
15k
Dive into gomock / Go Conference 2024
utgwkk
14
7.6k
Goでリフレクションする、その前に / Kansai.go #1
utgwkk
4
3.6k
Go製Webアプリケーションのエラーとの向き合い方大全、あるいはやっぱりスタックトレース欲しいやん / Kyoto.go #50
utgwkk
7
4.2k
ありがとう、create-react-app
utgwkk
4
11k
SPAでもデータをURLでシェアしたい / Kyoto.js 19
utgwkk
2
1.9k
Other Decks in Programming
See All in Programming
Langfuseと歩む生成AI活用推進
licux
3
320
STUNMESH-go: Wireguard NAT穿隧工具的源起與介紹
tjjh89017
0
390
為你自己學 Python - 冷知識篇
eddie
1
290
サイトを作ったらNFCタグキーホルダーを爆速で作れ!
yuukis
0
700
20250808_AIAgent勉強会_ClaudeCodeデータ分析の実運用〜競馬を題材に回収率100%の先を目指すメソッドとは〜
kkakeru
0
210
一人でAIプロダクトを作るための工夫 〜技術選定・開発プロセス編〜 / I want AI to work harder
rkaga
13
2.9k
DockerからECSへ 〜 AWSの海に出る前に知っておきたいこと 〜
ota1022
5
1.8k
AI OCR API on Lambdaを Datadogで可視化してみた
nealle
0
210
コーディングは技術者(エンジニア)の嗜みでして / Learning the System Development Mindset from Rock Lady
mackey0225
2
600
Claude Codeで挑むOSSコントリビュート
eycjur
0
180
A Gopher's Guide to Vibe Coding
danicat
0
180
詳解!defer panic recover のしくみ / Understanding defer, panic, and recover
convto
0
190
Featured
See All Featured
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Practical Orchestrator
shlominoach
190
11k
Side Projects
sachag
455
43k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.4k
Speed Design
sergeychernyshev
32
1.1k
[RailsConf 2023] Rails as a piece of cake
palkan
56
5.8k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4k
Agile that works and the tools we love
rasmusluckow
330
21k
Documentation Writing (for coders)
carmenintech
73
5k
The Power of CSS Pseudo Elements
geoffreycrofte
77
5.9k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.9k
Transcript
mockgenによるモック生成を 高速化するツール bulkmockgenのご紹介 Kyoto.go #43 @utgwkk (うたがわきき)
自己紹介 @utgwkk (うたがわきき) 株式会社はてな Webアプリケーションエンジニア in 京都 最近はGoを書いて暮らしています
みなさん モックしていますか?
gomock (mockgen) https://github.com/uber/mock (最近 https://github.com/golang/mock がarchiveされた) mockgenでモックを生成してテストで使う
mockgenを使ったモック世界観 (1) // interfaceを定義して type UserStore interface { FindById(ctx context.Context,
id string) (*model.User, error) } // モックを生成する //go:generate mockgen -package mock_store -destination mock_store/user_store.go . UserStore
mockgenを使ったモック世界観 (2) // モックを注入する ctrl := gomock.NewController(t) m := mock_repo.NewMockUserStore(ctrl)
s := NewUserService(s) // モックが呼び出される方法を表明する m.EXPECT().FindById(gomock.Any(), "user"). Return(&model.User{Id: "user"}, nil) // モックを使うメソッドを呼び出してテストする ctx := context.Background() u, err := s.FindUserById(ctx, "user")
mockgen便利 モック生成を一手に引き受けてくれる 便利なmatcherがある (gomock.Any(), gomock.InAnyOrder(), …) 呼び出し方が不正だったらテストを落としてくれる
mockgenの課題 go generateが直列に実行されるので遅い reflect modeだと都度コンパイルされるので遅い
モック生成コマンドが多くなると遅い //go:generate mockgen -package mock_store -destination mock_store/a.go . StoreA //go:generate
mockgen -package mock_store -destination mock_store/b.go . StoreB //go:generate mockgen -package mock_store -destination mock_store/c.go . StoreC go generateによるコード生成は直列に実行される Proposal: cmd/go: parallel execution of //go:generate · Issue #20520 · golang/go
mockgenのreflect modeの仕組み上遅い モックするinterfaceの情報を得るためにGoのプログラムをコンパイルしている mockgenを実行したらコンパイルが走る!!
どんどん遅くなるgo generate 77.70s user 39.76s system 143% cpu 1:21.75 total
https://xkcd.com/303/
go:generate をまとめることはできるが //go:generate mockgen -package mock_store -destination mock_store/store.go . StoreA,StoreB,StoreC
人間がこの1行を編集しまくる必要がある? うまくコンフリクトを解消できる??
bulkmockgen https://github.com/utgwkk/bulkmockgen mockgenのコード生成を1回にまとめて高速化するツールbulkmockgenを作った - 私が 歌川です モック対象のinterfaceをスライスに列挙して一度にコード生成する 移行ツールもある (mockgen-to-bulkmockgen)
仕組み モック対象のinterfaceをスライスに列挙する 静的解析 (go/parser, go/ast) でinterfaceのリストを取得する スライスに渡したinterface名を結合してmockgenに渡す
デモ 大量のinterface定義に対するモック生成を一括で行う https://github.com/utgwkk/bulkmockgen/tree/main/benchmark/interfaces (カンペ: VSCodeを開いてください)
コード生成を速くして効率を上げることに成功 77.70s user 39.76s system 143% cpu 1:21.75 total (before)
52.18s user 19.93s system 209% cpu 34.397 total (after) 関わっているプロジェクトで47秒ほど高速化できた
課題 mockgenが生成するコード中のコメントがコンフリクトする!! // Code generated by MockGen. DO NOT EDIT.
// Source: example.com/test/repo (interfaces: IFoo,IBar,IBaz…)
workaround go generateしたあとにコメントを消す for go_file in `git grep --name-only '^//
Code generated by MockGen. DO NOT EDIT.' -- '*.go'`; do perl -i -nlpe '$_="" if m{// Source: example.com/test/repo}' $go_file gofmt -w $go_file done
まとめ mockgenによるコード生成をまとめるツールbulkmockgenをご紹介 複数のinterfaceのモックを一度に生成することでコード生成を高速化できた interface一覧を1行にまとめる必要がないので人間に優しい
参考 • mockgenのコード生成を1回にまとめて高速化するツールbulkmockgenを作った - 私が歌川です • gomockを完全に理解する • go generateに関するproposal
◦ Proposal: cmd/go: parallel execution of //go:generate · Issue #20520 · golang/go ◦ proposal: cmd/go: generate allow arguments to span multiple lines · Issue #46050 · golang/go
先行研究: gomockhandler Goで大量のモックをより統一的に管理し、もっと高速に生成したい!そうだ!! gomockhandlerを使おう!! | メルカリエンジニアリング mockgenコマンドを並列実行する go generateではなく独自CLIによるモック管理
なぜbulkmockgenを作ったのか go generateの仕組みに乗ったまま高速化できないか考えた 既存の仕組みからジャンプが少ないと導入しやすい モックしたいinterfaceをGoのコードとして列挙するのでrenameにも強い
構想 gomockhandlerとbulkmockgenを組み合わせることができると爆速でモックを生成でき るのでは??