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.2k
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
ゆるやかにgolangci-lintのルールを強くする / Kyoto.go #56
utgwkk
2
390
君たちはどうコードをレビューする (される) か / 大吉祥寺.pm
utgwkk
21
13k
Dive into gomock / Go Conference 2024
utgwkk
14
5.4k
Goでリフレクションする、その前に / Kansai.go #1
utgwkk
5
2k
Go製Webアプリケーションのエラーとの向き合い方大全、あるいはやっぱりスタックトレース欲しいやん / Kyoto.go #50
utgwkk
7
3.4k
ありがとう、create-react-app
utgwkk
4
10k
SPAでもデータをURLでシェアしたい / Kyoto.js 19
utgwkk
2
1.8k
prototype大全 / YAPC::Kyoto 2023
utgwkk
1
4.4k
なんでもPull Requestにする / Kichijoji.pm 31
utgwkk
3
6.3k
Other Decks in Programming
See All in Programming
Kaigi on Railsに初参加したら、その日にLT登壇が決定した件について
tama50505
0
100
Fibonacci Function Gallery - Part 1
philipschwarz
PRO
0
220
Effective Signals in Angular 19+: Rules and Helpers
manfredsteyer
PRO
0
100
Stackless и stackful? Корутины и асинхронность в Go
lamodatech
0
760
Haze - Real time background blurring
chrisbanes
1
510
アクターシステムに頼らずEvent Sourcingする方法について
j5ik2o
4
270
Security_for_introducing_eBPF
kentatada
0
110
Mermaid x AST x 生成AI = コードとドキュメントの完全同期への道
shibuyamizuho
0
160
KMP와 kotlinx.rpc로 서버와 클라이언트 동기화
kwakeuijin
0
140
Асинхронность неизбежна: как мы проектировали сервис уведомлений
lamodatech
0
770
たのしいparse.y
ydah
3
120
Symfony Mapper Component
soyuka
2
730
Featured
See All Featured
A Tale of Four Properties
chriscoyier
157
23k
A designer walks into a library…
pauljervisheath
204
24k
How STYLIGHT went responsive
nonsquared
95
5.2k
How To Stay Up To Date on Web Technology
chriscoyier
789
250k
Designing on Purpose - Digital PM Summit 2013
jponch
116
7k
Speed Design
sergeychernyshev
25
670
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
KATA
mclloyd
29
14k
GitHub's CSS Performance
jonrohan
1030
460k
Optimising Largest Contentful Paint
csswizardry
33
3k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
Six Lessons from altMBA
skipperchong
27
3.5k
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を組み合わせることができると爆速でモックを生成でき るのでは??