何かやってみるブログ

興味をもったことに関して書いています。技術系の記事が多いです。

Goの文法まとめ(Testing)

最近、個人的な趣味でGoを勉強しているのでメモ代わりに残します。

今回はGoの標準テストを試してみます。

fizzbuzzを実装して、fizzbuzzが無事に動いているかを確かめるテストを書いていきます。

ディレクトリ構成は以下のようにします。

.
├── main.go
└── toy
    ├── fizz_buzz.go
    └── fizz_buzz_test.go

fizzbuzzを実装する

package toy

import "strconv"

func Fizzbuzz(i int) string {
    if i%15 == 0 {
        return "fizzbuzz"
    } else if i%5 == 0 {
        return "buzz"
    } else if i%3 == 0 {
        return "fizz"
    } else {
        return strconv.Itoa(i)
    }
}

3の倍数だったら fizz 5の倍数だったら buzz 15の倍数だったら fizzbuzz それ以外の数値だったら数値の文字列を返します。

main.goを実装して実行してみる

package main

import (
    "fmt"
    "go_sample/toy"
)

func main() {
    s := []int{1, 2, 3, 5, 6, 7, 15}
    for _, i := range s {
        fmt.Println(toy.Fizzbuzz(i))
    }
}

スライスでいくつかサンプルを作成してfor文で繰り返して fizzbuzzを実行していきます。

実行してみると以下のように出力されます。

% go run main.go
1
2
fizz
buzz
fizz
7
fizzbuzz

テストを書く

以下の流れでテストを実装していきます。

  1. main.goと同じサンプルを用意して、results という空のスライスにfizzbuzzの結果を追加していく。
  2. 期待するスライスである expected を定義してあげる。
  3. expectedresultが一致してればテストが成功、間違っていた場合はテスト失敗です。
package toy

import (
    "reflect"
    "testing"
)

func TestFizzbuzz(t *testing.T) {
    s := []int{1, 2, 3, 5, 6, 7, 15}
    var results []string
    for _, i := range s {
        result := Fizzbuzz(i)
        results = append(results, result)
    }
    expected := []string{"1", "2", "fizz", "buzz", "fizz", "7", "fizzbuzz"}
    if !(reflect.DeepEqual(results, expected)) {
        t.Error("Not correct!!. got a slice", results)
    }
}

reflectのDeepEqualを使うとスライスを比較できるそうです。

qiita.com

テストを実行してみます。

 % go test ./toy
ok      go_sample/toy   0.399s

テストが成功しました。

次にサンプルを適当にいじって、わざと失敗してみます。

% go test ./toy
--- FAIL: TestFizzbuzz (0.00s)
    fizz_buzz_test.go:17: Not correct!!. got a slice [1 2 fizz buzz fizz 7 11]
FAIL
FAIL    go_sample/toy   0.334s
FAIL

失敗することが確認できました。