調査内容

  • 単体テスト基本
    • testing フレームワークの 主要関数, Error, Errorf, Fatal, Fatalf
    • ベンチマーク, *testing.B型
    • Google/go-cmp アサーション時の比較演算子
    • サブテストとテーブル駆動テスト
    • テストヘルパー テスト用のヘルパー関数
  • Go Mock, インターフェースによるてスタビリティの向上、抽象化
    • インターフェースをしようし、外部につながる部分はモックに差し替え可能にする
    • 環境変数を使う, os.Getenvで取得
    • GitHub.com/jinzhu/configor を使う
    • テストデータを用意する, どの環境でもしようできるテストデータ (testdataというディレクトリに入れる) 参考
    • 非公開な機能を使ったテスト

テーブル駆動テスト

TableDrivenTests

Writing good tests is not trivial, but in many situations a lot of ground can be covered with table-driven tests: Each table entry is a complete test case with inputs and expected results, and sometimes with additional information such as a test name to make the test output easily readable. If you ever find yourself using copy and paste when writing a test, think about whether refactoring into a table-driven test or pulling the copied code out into a helper function might be a better option.

Given a table of test cases, the actual test simply iterates through all table entries and for each entry performs the necessary tests. The test code is written once and amortized over all table entries, so it makes sense to write a careful test with good error messages.

以下訳

良いテストコードを書くことは困難であるが、テーブル駆動テストによってその多くをカバーすることができる。 テーブル駆動テスト: 各々のテーブルエントリーにより入出力を適切に行えるテスト手法であり、テスト結果を読み易いようにするadditional information も提供してくれる。

与えられたテストケースのテーブルに置いて、全てのテーブルに対して必要なテストを行う。テストコードを一度書くだけで全てのテーブルエントリーに対してテストを実行できるので、エラーメッセージを含め良いテストコードを書く上での良い手助けとなるだろう。

上記文章を読んでもピンとこなかった。こちらのQiitaの記事を参照させていただいた。

ホワイトボックステスト / ブラックボックステスト

ホワイトボックステスト

  • 命令網羅(ステートメントカバレッジ)
  • 分岐網羅(ブランチカバレッジ)
  • 条件網羅 / 複合条件網羅(コンディションカバレッジ)

ブラックボックステストとは?

  • 同値分割
  • 境界値分析

ホワイトボックス手法では、主にコードに着目して試験を行います。実際のプログラムに応じて効率的なテストが可能な反面、プログラマ自身の誤解や、あるべき分岐が無いなど、ソースコード上でのミスを発見できません。

 そのため、ブラックボックステストを主軸として、補助的な観点(テストカバレッジの向上)で実施すべきテストです。通常は、「複合条件網羅」を利用します。

https://www.deep-rain.com/programming/program/615より

Package quick

Testing/quick パッケージはブラックボックステストを可能とする。

Package quick implements utility functions to help with black box testing.

The testing/quick package is frozen and is not accepting new features.

quickパッケージはブラックボックステストのためのutilityな関数を提供します。 このパッケージの開発は凍結されており、新機能の追加は受け付けていません。

サブテスト

子テストを実行する仕組み。 Table-driven tests using subtests

通常、テーブル駆動テストを実行時においては、一つのテストケースでテストが落ちた際は以後のテストケースは実行されずにテストが終了されてしまう。ただし Runメソッドを使用する(ここのケースをサブテストとする) ことで、残り全てのテストについても実行することができるようだ。 以下はリンク内の実例。 "Europe/Zurich" -> "Europe/Zuri" , "07:31 -> "7:31"と故意に書き、落ちるテストケースとした場合について。

The first thing to note is the difference in output from the two implementations. The original implementation prints:

--- FAIL: TestTime (0.00s)
    time_test.go:62: could not load location "Europe/Zuri"

Even though there are two errors, execution of the test halts on the call to Fatalf and the second test never runs.

The implementation using Run prints both:

--- FAIL: TestTime (0.00s)
    --- FAIL: TestTime/12:31_in_Europe/Zuri (0.00s)
        time_test.go:84: could not load location
    --- FAIL: TestTime/12:31_in_America/New_York (0.00s)
        time_test.go:88: got 07:31; want 7:31

func (*T) Run

func (t *T) Run(name string, f func(t *T)) bool

Run runs f as a subtest of t called name. It runs f in a separate goroutine and blocks until f returns or calls t.Parallel to become a parallel test. Run reports whether f succeeded (or at least did not fail before calling t.Parallel).

Runメソッドは、第二引数に与えられた f を第一引数 t を名前としたサブテストを実行する。…(中略)… Runは f についての成功の可否をレポートする。

カバレッジの可視化

Viewing the results

$ go tool cover -html=coverage.out

When this command is run, a browser window pops up, showing the covered (green), uncovered (red), and uninstrumented (grey) source.

こちらの可視化機能が便利である。テスト元となるファイルのコードについて、ブラウザ上でテスの消化/未消化のコードを色分けで表示してくれる。

<!—

【TRY】単体テストを行おう

  • 偶数判定関数のテスト
    • 偶数が与えられた場合にtrueを返す関数を考える
    • テーブル駆動テストを行う
    • テストケースとしてふさわしいものを考えテストを書こう
    • 各テストケースをサブテストとして実行しよう
    • coverprofileをみてみよう

—>