Upgrade to Pro — share decks privately, control downloads, hide ads and more …

synctest時代のhttptest Go 1.27で変わるHTTPサーバテストの裏側 /...

synctest時代のhttptest Go 1.27で変わるHTTPサーバテストの裏側 / go conference2026 synctest and httptest

Go Conference 2026の登壇資料です。
https://gocon.jp/2026/
https://gocon.jp/2026/timetable/1264549/

Avatar for Yoichiro Shimizu

Yoichiro Shimizu

September 11, 2026

More Decks by Yoichiro Shimizu

Other Decks in Technology

Transcript

  1. 今日の話の流れ と synctest のおさらい httptest.Server がなぜ synctest と併用できなかったのか Go 1.27の

    httptest は何が出来るようになったのか httptest.NewTestServer は何をどうやって実現しているのか httptest © LayerX Inc. 6
  2. synctestのおさらい synctest pacakge func Test(t *testing.T, f func(*testing.T)) それぞれのテストを独立した「バブル」と呼ぶ隔離環境で実行できる バブルの中で生成されたgoroutineの実行状況が管理される

    バブルの中では独自の時間(fake clock)が流れる 10分後にタイムアウトしたらPASS、のようなテストでも一瞬で完了する func Wait() バブルの中のgoroutineがすべてdurably blockedになるのを待機する func Sleep(d time.Duration) © LayerX Inc. Go1.27で追加。 time.Sleep + synctest.Wait 8
  3. synctestのおさらい 独立した時間が流れる「バブル」 synctest bubble fake clock G1 00:10:00 G3 G2

    synctest bubble fake clock G4 00:25:00 G6 バブル内で生まれた goroutine を管理する 独自のfake timeを管理する それぞれのバブルは synctest.Test ごとに独立 G5 © LayerX Inc. 9
  4. synctestのおさらい durably blocked ゴルーチンが永続的にブロックされている状態 バブル内で作成されたチャネルに対する送信または受信操作がブロックされている すべてのケースがバブル内で作成されたチャネルを対象とした select 文のブロック sync.Cond.Wait sync.WaitGroup.Wait

    メソッドは、 sync.WaitGroup.Add メソッドがバブル内で呼び出された場合 time.Sleep バブル内のすべてのgoroutineがdurably blockedになると、 バブル内の時刻が進む(n秒のSleepなどが即時に解消される) synctest.Wait を使っていた場合は Wait が解除される © LayerX Inc. 10
  5. httptest.Server がなぜ synctest と併用できなかったのか non-durably blocked な処理は synctest と併用できない バブル内のすべてのgoroutineがdurably

    blockedにならない bubble内の時刻が進まない synctest.Wait を使っていた場合はWaitが解除されない httptest.Server はサーバなのでネットワークI/Oからリクエストを待ち続ける そのためバブルの中でfake clockが進まない synctest.Wait も解除されない © LayerX Inc. 13
  6. Go1.27のhttptest Go 1.27からのsynctestとhttptest リリースノートを読むと httptest.NewTestServer で synctest に対応したらしい! 正確に言うと @mazrean

    さんのGo Proposal Weekly Digestで見かけて目をつけていた net/http/httptest The new NewTestServer function creates a Server configured to use an in-memory fake network suitable for use with the testing/synctest package. © LayerX Inc. ref: Go 1.27 Release Notes 17
  7. Go 1.27のhttptestは何が出来るようになったのか どうやって実現しているのか Go1.26以前からあった httptest.NewServer で作成した(ほぼ通常の)HTTPサーバの処理の流れ 側 側 client server

    http.Client http.Server http.RoundTripper Serve(net.Listener) *http.Transport TCPListener.Accept DialContext TCPConn © LayerX Inc. OS socket (loopback) TCPConn 21
  8. Go 1.27のhttptestは何が出来るようになったのか httptest.NewServer と httptest.NewTestServer はどう違うの? 実はそこまで変わっていない internal/nettest パッケージの nettest.Listener

    と nettest.Conn を使っている 側 側 client server http.Client http.Server http.RoundTripper Serve(net.Listener) *http.Transport DialContext client nettest.Conn © LayerX Inc. nettest.Listener.Accept connection pair in-memory server nettest.Conn 22
  9. internal/nettest deep dive internal/nettest durably blockedと判定される処理だけを使って net.Listener と net.Conn の実装を提供している

    バブル内で作成されたチャネルに対する送信または受信操作がブロックされている すべてのケースがバブル内で作成されたチャネルを対象とした select 文のブロック sync.Cond.Wait sync.WaitGroup.Wait メソッドは、 sync.WaitGroup.Add メソッドがバブル内で呼び出された場合 time.Sleep そのため internal/nettest を使っていても synctest のバブルが期待通りの挙動をしてくれる © LayerX Inc. 24
  10. internal/nettest deep dive internal/nettest.NewListener *nettest.Listener は net.Listener インターフェースを満たす実装 状態管理しながらチャネルを使った Gate

    というロック機能 作成したインメモリな Conn をプールする インメモリな net.Conn を作成する NewConn メソッドを持つ © LayerX Inc. 27
  11. internal/nettest deep dive httptestはどう利用しているか クライアントが nettest.Listener のキューに nettest.Con をpushする サーバは

    nettest.Listener のキューから nettest.Con をpopする 側 側 client server http.Client http.Server http.RoundTripper Serve(net.Listener) *http.Transport DialContext client nettest.Conn © LayerX Inc. nettest.Listener.Accept connection pair in-memory server nettest.Conn 28
  12. まとめ synctest は決定的に非同期処理・時間依存のテストを書ける バブルとdurably blockedで成り立っている Go1.26までの httptest.Server はno-durably blockedなネットワーク通信をするので synctest

    と併用できなかった Go1.27の httptest.NewTestServer を使えば synctest と併用できるようになった 実現している internal/nettest は思ったよりシンプル GoはGoで実装されているので読みやすい! © LayerX Inc. 31
  13. 参考資料 (1/3) Go 1.27 is released!(2026-08-19リリース) Go 1.27 Release Notes

    net/http/httptest package documentation net/http/httptest: synctest support #76608 proposal: testing/nettest: in-memory implementations of net package interfaces #77362 © LayerX Inc. 32
  14. 参考資料 (2/3) CL 740100: testing/nettestのドラフト実装 net/http: use fake network for

    HTTP/3 tests #80480 CL 801940: http3: rework registration to allow using a fake network CL 803380: net/http: rework HTTP/3 registration to allow using a fake network net/http のHTTP/3テストにおける PacketNet の利用 © LayerX Inc. 33
  15. 参考資料 (3/3) source internal/nettest.Listener source internal/nettest.Conn source internal/gate source Go

    Blog: Testing concurrent code with testing/synctest net/http/httptest.Server © LayerX Inc. 34