LoginSignup
3
0

More than 3 years have passed since last update.

Goで簡単な関数を実装しながらgo testを理解する

Last updated at Posted at 2019-12-02

この記事はtomowarkar ひとりAdvent Calendar 2019の3日目の記事です。

今日はgo testを理解していきます。

今回実装する関数

整数配列から最小値を求める関数をそれぞれ実装していきます。
pythonでいうmin関数ですね。


$ python
>>> min([1,2,3])
1

testingパッケージについて

  • Goでのテストはtestingパッケージを使う。
  • テストは{filename}_test.goというファイルで作成。
  • テストのメソッドは命名則があるので注意(以下引用)。

func TestXxx(* testing.T)
ここで、Xxxは小文字で始まっていません。関数名は、テストルーチンを識別するのに役立ちます。
Package testing

テストファイルを同時に作成する

テストを書く場合は同時に作成してしまうと楽そうです。

$ touch math{,_test}.go
$ ls
math.go math_test.go

テストを書く

それでは上記で作成したmathファイルにコードを書いていきます。TDD的にまずはテストから。

  • テーブルを使ってテストを実装
  • min関数はminIntとして実装
  • サブテスト を使ってテストケース毎にテストを分類
math_test.go
package math

import (
    "testing"
)

func TestMinInt(t *testing.T) {
    tests := []struct {
        name string
        in   []int
        want int
    }{
        {"natural_number_slice", []int{1, 2, 3}, 1},
        {"nega_posi", []int{-1, 0}, -1},
        {"nega_nega", []int{-10, -11}, -11},
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got := minInt(tt.in)
            if got != tt.want {
                t.Fatalf("want %v but %v", tt.want, got)
            }
        })
    }
}
math.go
package math

func minInt(slice []int) int {
    var min int
    return min
}

失敗することを確認

まだminIntを実装しておらずただ0を返すだけの関数なので、テストは当然落ちます。

$ go test
--- FAIL: TestMinInt (0.00s)
    --- FAIL: TestMinInt/natural_number_slice (0.00s)
        math_test.go:21: want 1 but 0
    --- FAIL: TestMinInt/nega_posi (0.00s)
        math_test.go:21: want -1 but 0
    --- FAIL: TestMinInt/nega_nega (0.00s)
        math_test.go:21: want -11 but 0
FAIL
exit status 1
FAIL    math       0.006s

一つ目のテスト結果をみてみます


    --- FAIL: TestMinInt/natural_number_slice (0.00s)
        math_test.go:21: want 1 but 0

データオブジェクトは{"natural_number_slice", []int{1, 2, 3}, 1}で、テストログのwant 1 but 0より1が期待されたけれども、得られたのは0ですよといことがわかる。

関数を実装する

テストが落ちることが確認できたので関数を実装します。簡単ですね。

math.go
package math

func minInt(slice []int) int {
    var min int = slice[0]
    for _, value := range slice {
        if min > value {
            min = value
        }
    }
    return min
}

成功することを確認する

関数を実装したので期待通りに動作することを確認します。

$ go test
PASS
ok      math       0.005s

テストの途中経過を確認する

PASSと出ているだけではどのテストを確認したのかわからないため、テストの途中経過を確認したくなりました。
そのような場合は-vオプションを追加します。

TestMinIntの3つのサブテストを確認した結果PASSになっているのが分かります。

$ go test -v
=== RUN   TestMinInt
=== RUN   TestMinInt/natural_number_slice
=== RUN   TestMinInt/nega_posi
=== RUN   TestMinInt/nega_nega
--- PASS: TestMinInt (0.00s)
    --- PASS: TestMinInt/natural_number_slice (0.00s)
    --- PASS: TestMinInt/nega_posi (0.00s)
    --- PASS: TestMinInt/nega_nega (0.00s)
PASS
ok      math       0.006s

各関数, サブテスト毎にテスト結果を確認する

今回はTestMinIntしかテスト対象がないため必要としませんが、-run {your_test_method}オプションで各メソッド毎にテスト結果を確認することができます。

$ go test -run TestMinInt

また同様にして-run {your_test_method/sub_test}オプションを使ってサブテスト毎にテスト結果を確認することもできます。

$ go test -v -run TestMinInt/natural_number_slic
=== RUN   TestMinInt
=== RUN   TestMinInt/natural_number_slice
--- PASS: TestMinInt (0.00s)
    --- PASS: TestMinInt/natural_number_slice (0.00s)
PASS
ok      math       0.005s

テストカバレッジを確認する

最後に-coverオプションを使ってテストカバレッジを確認します。


$ go test -cover
PASS
coverage: 100.0% of statements
ok      math       0.005s

参考記事

まとめ

  • go testの書き方がわかった
  • go testの各オプションの理解ができた
  • テストカバレッジ上げていこう

以上明日も頑張ります!!
tomowarkar ひとりAdvent Calendar Advent Calendar 2019

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0