Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

testdata ディレクトリを活用しよう!

Avatar for uji uji
December 01, 2025
190

testdata ディレクトリを活用しよう!

Avatar for uji

uji

December 01, 2025
Tweet

More Decks by uji

Transcript

  1. © NOT A HOTEL, Inc. 自己紹介 uji @uji_rb 神戸市在住 NOT

    A HOTEL 所属 Gopher 7年生 KOBE.go, Kyoto.go 運営 Kyoto.go KOBE.go
  2. © NOT A HOTEL, Inc. © NOT A HOTEL, Inc.

    testdata 活用 Tips を3つ紹介 4
  3. © NOT A HOTEL, Inc. testdata とは? • テストに利用する補助データを 置いておくことができるディレクトリ

    • Go ツールはビルドなどからは testdata と命名された ディレクトリは無視されるので安全(doc) ◦ 中に .go ファイルがあってもビルド対象にならない
  4. © NOT A HOTEL, Inc. 何が嬉しい? • 入出力データや状態が複雑になるテストの 可読性や保守性を上げられる •

    Table Driven Test でも可読性や保守性を 高くしきれない場面で有効。 テストケースと検証ロジックの分離度がさらに上がる
  5. © NOT A HOTEL, Inc. 基本的な使い方 • 任意の場所に testdata ディレクトリを作成

    • テストで利用するファイルを用意 • 標準 pkg でテストコードからファイルを読み取り ◦ os.Open(“testdata/xxx.png”) や embed など • src/image/testdata など golang/go でも実例がたくさん
  6. © NOT A HOTEL, Inc. © NOT A HOTEL, Inc.

    Tips 1 Golden Test に利用する 8
  7. © NOT A HOTEL, Inc. Golden Test とは? • テスト対象の出力結果を事前に保存された

    “Golden” ファイル と比較するテスト手法 • コードの変更した際、意図しない変更や 回帰がないかを検証するために特に有用 • “Golden” は、 「黄金の価値がある」「非常に信頼性の高い」という意味合いが由来
  8. © NOT A HOTEL, Inc. Golden Test の書き方 • Golden

    ファイルを testdata に格納し読み書き • flag パッケージを活用することで、 Golden ファイルの生成機構も簡単に用意できる
  9. © NOT A HOTEL, Inc. golang/go/src/go/doc/doc_test.go の例 var update =

    flag.Bool("update", false, "update golden (.out) files") ... func test(t *testing.T, mode Mode) { ... for _, pkg := range pkgs { t.Run(pkg.Name, func(t *testing.T) { ... // Golden ファイルのupdate golden := filepath.Join(dataDir, fmt.Sprintf("%s.%d.golden", pkg.Name, mode)) if *update { err := os.WriteFile(golden, got, 0644) if err != nil { t.Fatal(err) } } // Golden ファイルの取得 want, err := os.ReadFile(golden) if err != nil { t.Fatal(err) } // 検証 ...
  10. © NOT A HOTEL, Inc. golang/go/src/go/doc/doc_test.go の例 var update =

    flag.Bool("update", false, "update golden (.out) files") ... func test(t *testing.T, mode Mode) { ... for _, pkg := range pkgs { t.Run(pkg.Name, func(t *testing.T) { ... // Golden ファイルのupdate golden := filepath.Join(dataDir, fmt.Sprintf("%s.%d.golden", pkg.Name, mode)) if *update { err := os.WriteFile(golden, got, 0644) if err != nil { t.Fatal(err) } } // Golden ファイルの取得 want, err := os.ReadFile(golden) if err != nil { t.Fatal(err) } // 検証 ... flag パッケージで変数を宣言
  11. © NOT A HOTEL, Inc. golang/go/src/go/doc/doc_test.go の例 var update =

    flag.Bool("update", false, "update golden (.out) files") ... func test(t *testing.T, mode Mode) { ... for _, pkg := range pkgs { t.Run(pkg.Name, func(t *testing.T) { ... // Golden ファイルのupdate golden := filepath.Join(dataDir, fmt.Sprintf("%s.%d.golden", pkg.Name, mode)) if *update { err := os.WriteFile(golden, got, 0644) if err != nil { t.Fatal(err) } } // Golden ファイルの取得 want, err := os.ReadFile(golden) if err != nil { t.Fatal(err) } // 検証 ... flag 変数で条件分岐
  12. © NOT A HOTEL, Inc. • go test で生成されるテストバイナリは、 内部で

    flag.Parse() を呼び出している (code) • フラグ変数をグローバル変数として定義すれば、 go test -update などでテストに値を渡すことができる
  13. © NOT A HOTEL, Inc. © NOT A HOTEL, Inc.

    Tips 2 txtar 形式を活用する 15
  14. © NOT A HOTEL, Inc. • Go 言語のエコシステム内で利用される、 アーカイブ形式の一つ •

    複数のファイルの内容を単一のテキストファイルに まとめて表現するための形式 txtar とは?
  15. © NOT A HOTEL, Inc. • golang.org/x/tools/txtar でライブラリが サポートされている ◦

    例えば txtar.Parse() で簡単に複数ファイルを取得可能 • 活用例 ◦ テストの入力・出力をセットで扱う ◦ ファイルシステムの状態を表現 txtar の活用方法
  16. © NOT A HOTEL, Inc. © NOT A HOTEL, Inc.

    Tips 3 script-based test で利用する 20
  17. © NOT A HOTEL, Inc. • テストケースをスクリプト (手順と期待結果を記述した文書)で記述するテスト • Go公式の

    cmd/go のテストでもヘビーに利用 ◦ Russ Cox 氏により、 internal package で独自の スクリプト言語が実装されている(README) • testdata でテストスクリプトを管理している script-based test とは?
  18. © NOT A HOTEL, Inc. src/cmd/go/testdata/script/test_status.txt の例 env GO111MODULE=off !

    go test x y stdout ^FAIL\s+x stdout ^ok\s+y stdout (?-m)FAIL\n$ -- x/x_test.go -- package x import "testing" func TestNothingJustFail(t *testing.T) { t.Fail() } -- y/y_test.go -- package y このファイルを scripttest.Run() に渡すと テストが動作 src/cmd/go/script_test.go#L40
  19. © NOT A HOTEL, Inc. • Go で使われているスクリプト言語を利用するためのライ ブラリは github.com/rsc/script

    にて Russ Cox 氏が公開 • 別の記述スタイルが欲しければ自作するのもアリ…? ◦ 多様なパターンをテストしたい場合はコストに見合う価値はあるかも 同じように script-based test を書くには
  20. © NOT A HOTEL, Inc. 他にも testdata 活用 Tips があれば是非

    #go_findy で教えてください! 参考文献 • research!rsc: Go Testing By Example https://research.swtch.com/testing • Bitfield Consulting: Flipping the script: a smarter way to test Go binaries https://bitfieldconsulting.com/posts/test-scripts