🧪

【Go】Goのテストに入門してみた! ~Table Driven Test編~

に公開

はじめに

前回は、Goにおけるテストの基本を学びました。
今回は、Goでよく使われる 「テーブル駆動テスト(Table Driven Test)」 に入門します。
前回の記事はこちら↓
https://zenn.dev/tmyhrn/articles/7fc1bc9c9e634d

この記事でわかること

  • Table Driven Testの概要
  • 実装方法
  • 実装時に押さえておきたいポイント

実装してみた

前回に引き続き、マルチバイトでの文字列カウントについてのテストケースを見ていきます。

main_test.go
package main

import (
    "testing"
    "unicode/utf8"
)

func Length(s string) int {
    return utf8.RuneCountInString(s)
}

func TestLength(t *testing.T) {
    tests := []struct {
        name  string
        input string
        want  int
    }{
        {"ascii", "Hello", 5},
        {"full-width-japanese", "こんにちは", 5},
        {"half-width-japanese", "コンニチハ", 5},
        {"emoji", "😃😃😃", 3},
        {"empty", "", 0},
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            if got := Length(tt.input); got != tt.want {
                t.Errorf("Length = %d, want %d", got, tt.want)
            }
        })
    }
}

実行してみると、以下のような結果が得られます。

ターミナル
# go test -v
# -vフラグをつけることで詳細なテスト結果を得ることができる
=== RUN   TestLength
=== RUN   TestLength/ascii
=== RUN   TestLength/full-width-japanese
=== RUN   TestLength/half-width-japanese
=== RUN   TestLength/emoji
=== RUN   TestLength/empty
--- PASS: TestLength (0.00s)
    --- PASS: TestLength/ascii (0.00s)
    --- PASS: TestLength/full-width-japanese (0.00s)
    --- PASS: TestLength/half-width-japanese (0.00s)
    --- PASS: TestLength/emoji (0.00s)
    --- PASS: TestLength/empty (0.00s)
PASS
ok      go-test-practice        0.192s

押さえておきたいポイント

1. 構造体を作成する

テーブル駆動テストでは、「入力値」と「期待される出力値」の一覧表(テーブル) を作成します。
Goではこのテーブルを構造体のスライスで表現し、ループで1件ずつテストを実行するのが一般的です。
テストケースを一か所に集約することで、可読性と保守性が高まります。

2. テスト名をつける

各テストケースにテスト名があることで、どのテストで失敗したのかがわかりやすくなります。
特にテストケースが多い時に効力を発揮します。

3. t.Run()でテストを実行

testingパッケージのRunメソッドを使うことで、各テストケースを個別のサブテストとして実行できます。

  • 第1引数:サブテスト名(上で定義したname
  • 第2引数:サブテストの処理を記述した無名関数(func(t *testing.T)

こうすることで、個別に失敗を追跡できるだけでなく、特定のテストだけを選んで実行することも可能になります。

4. 期待値と実際の値

変数名として、期待値にはwantを、実際の値にはgotを使うことが一般的です。
テスト結果のログが読みやすくなり、テストの意図も明確になります。

まとめ

今回は、Goでのテーブル駆動テストの基本を学びました。

  • テストケースを構造体のスライスで定義し
  • t.Run()で各ケースをサブテストとして実行することで
  • 簡潔かつ拡張性の高いテストコードを書くことができることが分かりました。
    次回は、特定のサブテストのみを実行する方法についてみていきます。

参考

https://go.dev/wiki/TableDrivenTests
https://future-architect.github.io/articles/20250509a/
https://qiita.com/ryo_manba/items/242f629e0b3593879c6d

Discussion