Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 17293] ファイルの概要

このコミットは、Go言語の標準ライブラリであるtestingパッケージにTBインターフェースが追加されたことをGo 1.2のリリースノートに記載するものです。TBインターフェースは、テスト(*testing.T)とベンチマーク(*testing.B)の両方で共通して利用できるメソッド群を定義し、テストヘルパー関数などの記述をより汎用的にすることを目的としています。

コミット

commit 8814b4a4c6bb3906ba82bb4372eb01c8be5d2bfa
Author: Rob Pike <r@golang.org>
Date:   Fri Aug 16 15:38:18 2013 +1000

    doc/go1.2.txt: testing: add TB interface

    R=golang-dev, adg
    CC=golang-dev
    https://golang.org/cl/12890044

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/8814b4a4c6bb3906ba82bb4372eb01c8be5d2bfa

元コミット内容

doc/go1.2.txt: testing: add TB interface

R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/12890044

変更の背景

Go言語のテストフレームワークでは、テスト関数には*testing.T型、ベンチマーク関数には*testing.B型が引数として渡されます。これらの型は、テストの失敗を報告したり、ログを出力したり、サブテストを実行したりするための共通のメソッドを多数持っています。しかし、これら二つの型は異なる型であるため、テストとベンチマークの両方で共通の処理を行うヘルパー関数を作成する際に、引数の型をinterface{}にするか、あるいは*testing.T*testing.Bの両方を受け入れるようにオーバーロードする(Goでは直接的なオーバーロードはできないため、別の方法で実現する)必要がありました。

このコミットは、Go 1.2のリリースノートに、testingパッケージにTBインターフェースが追加されたことを記載するものです。TBインターフェースは、*testing.T*testing.Bの両方が実装する共通のメソッド群を抽象化することで、この問題を解決します。これにより、テストとベンチマークの両方で利用できる汎用的なヘルパー関数を、よりクリーンなコードで記述できるようになります。

前提知識の解説

Go言語のtestingパッケージ

Go言語には、標準ライブラリとしてtestingパッケージが提供されており、ユニットテストやベンチマークテストを記述するための機能が組み込まれています。

  • テスト関数: func TestXxx(t *testing.T)というシグネチャを持つ関数で、go testコマンドによって実行されます。*testing.T型は、テストの失敗を報告するErrorFail、ログを出力するLogなどのメソッドを提供します。
  • ベンチマーク関数: func BenchmarkXxx(b *testing.B)というシグネチャを持つ関数で、go test -bench=.コマンドによって実行されます。*testing.B型は、ベンチマークの実行回数を制御するNフィールドや、タイマーを操作するStartTimerStopTimerなどのメソッドを提供します。
  • インターフェース: Go言語におけるインターフェースは、メソッドのシグネチャの集まりを定義する型です。ある型がインターフェースで定義されたすべてのメソッドを実装していれば、その型はそのインターフェースを満たしているとみなされます。これにより、異なる具体的な型を抽象化して扱うことが可能になります。

*testing.T*testing.Bの共通メソッド

*testing.T*testing.Bは、それぞれテストとベンチマークに特化した機能を提供しますが、エラー報告やログ出力など、共通の機能も持っています。例えば、ErrorErrorfFatalFatalfLogLogfNameSkipSkipfSkippedなどのメソッドは両方の型に存在します。

技術的詳細

このコミット自体はコードの変更ではなく、Go 1.2のリリースノート(doc/go1.2.txt)に、testingパッケージにTBインターフェースが追加されたという新機能の情報を追記するものです。

TBインターフェースは、testingパッケージ内で以下のように定義されています(Go 1.2のソースコードから抜粋、概念的な説明のため実際の定義とは異なる場合がありますが、共通メソッドの集合体であるという点は同じです)。

// TB is the interface common to T and B.
type TB interface {
	Error(args ...interface{})
	Errorf(format string, args ...interface{})
	Fail()
	FailNow()
	Failed() bool
	Fatal(args ...interface{})
	Fatalf(format string, args ...interface{})
	Log(args ...interface{})
	Logf(format string, args ...interface{})
	Name() string
	Skip(args ...interface{})
	Skipf(format string, args ...interface{})
	Skipped() bool
	Helper()
	Cleanup(func())
	Setenv(key, value string)
	TempDir() string
}

このインターフェースが導入されたことで、テストとベンチマークの両方で共通して利用したいヘルパー関数は、引数として*testing.T*testing.Bの代わりにtesting.TBを受け取ることができるようになります。これにより、コードの再利用性が向上し、より簡潔で汎用的なテストヘルパーを記述することが可能になります。

例:

TBインターフェース導入前は、テストとベンチマークの両方で共通のセットアップ処理を行う場合、以下のように冗長なコードになる可能性がありました。

func setupTest(t *testing.T) {
    // テスト固有のセットアップ
    t.Log("Setting up for test...")
}

func setupBenchmark(b *testing.B) {
    // ベンチマーク固有のセットアップ
    b.Log("Setting up for benchmark...")
}

TBインターフェース導入後は、以下のように共通のヘルパー関数を作成できます。

func commonSetup(tb testing.TB) {
    tb.Log("Performing common setup...")
    // tb.Helper() // Go 1.9以降で利用可能
}

func TestMyFunction(t *testing.T) {
    commonSetup(t)
    // ... テストロジック ...
}

func BenchmarkMyFunction(b *testing.B) {
    commonSetup(b)
    // ... ベンチマークロジック ...
}

これにより、テストコードの可読性と保守性が向上します。

コアとなるコードの変更箇所

このコミットによるコードの変更は、doc/go1.2.txtファイルへの1行の追加のみです。

--- a/doc/go1.2.txt
+++ b/doc/go1.2.txt
@@ -65,6 +65,7 @@ strings: add IndexByte, for consistency with bytes package (CL 12214044).
 sync/atomic: add Swap functions (CL 12670045).
 syscall: implemented Sendfile for Darwin, added Syscall9 for Darwin/amd64 (CL 10980043).
 testing: AllocsPerRun is now quantized to an integer (the type is still float64) (CL 9837049).
+testing: add TB interface (intersection of T and B's methods) (CL 12962043).
 time: Allow Parse and Format to handle time zone offsets with seconds (CL 8132044)
 time: patterns require non-lowercase letter to follow Mon, Jan etc (CL 12448044).
 unicode: add In, a nicer-to-use but equivalent version of IsOneOf (CL 11672044).

具体的には、doc/go1.2.txtの66行目に以下の行が追加されています。

testing: add TB interface (intersection of T and B's methods) (CL 12962043).

コアとなるコードの解説

doc/go1.2.txtは、Go 1.2のリリースにおける変更点や新機能、非互換性などをまとめた公式ドキュメントの一部です。このファイルにtesting: add TB interface (intersection of T and B's methods) (CL 12962043).という行が追加されたことは、TBインターフェースの導入がGo 1.2の重要な新機能の一つとして公式に認識され、ユーザーにその存在が知らされることを意味します。

この記述は、TBインターフェースが*testing.T*testing.Bの共通メソッドの集合体であることを簡潔に説明しており、ユーザーがこの新しいインターフェースの目的を理解するのに役立ちます。また、括弧内のCL 12962043は、この機能が導入された元の変更リスト(Change List)のIDを示しており、詳細な実装内容や議論を追跡するための参照情報となります。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • Go言語のソースコード (特にsrc/testing/testing.goTBインターフェース定義)
  • Go言語の変更リスト (Gerrit)
  • Go 1.2 Release Notes (最終版)