Go言語のテスト方法初歩の初歩

## Goテストの基本
- testingパッケージを使う。
- ファイル名は必ず_test.goがつくようにする。
- testingパッケージをimportする
- 関数名はfunc TestXxx (t *testing.T)の形式にする

## テスト実行
以下のコードをサンプルとして動かしてみる。

```go
package gotest

import (
  "testing"
)

func Test_Division_1(t *testing.T) {
  if i, e := Division(6, 2); i != 3 || e != nil { //try a unit test on function
      t.Error("除算関数のテストが通りません") // もし予定されたものでなければエラーを発生させます。
  } else {
      t.Log("はじめのテストがパスしました") //記録したい情報を記録します
  }
}

func Test_Division_2(t *testing.T) {
  t.Error("パスしません")
}
```
[Goでテストをどのように書くか](https://astaxie.gitbooks.io/build-web-application-with-golang/ja/11.3.html)

### テストを全て実行

```go
go test
```
<img width="554" alt="スクリーンショット 2017-11-06 17.11.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/208513/26d8fdf9-ac47-7238-8e94-ae30ca2d53f6.png">

ただ、これではテスト結果がわかりにくい。go testを実行するとテストがパスする情報は表示されない。

表示させるには-vをつける必要がある。

```go
go test -v
```
<img width="544" alt="スクリーンショット 2017-11-06 17.11.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/208513/04e5e9f1-7e79-61a1-863d-64acc81f7114.png">


### １つのテストメソッドを実行

```go
go test -run メソッド名
```
<img width="535" alt="スクリーンショット 2017-11-06 17.11.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/208513/103df212-a376-8d8a-4f4b-a4b5cdd71831.png">

## Hello Worldのテストを書いてみる

```go
go_test
├── hello.go
└── hello_test.go
```
go_testというディレクトリにhelloworldを出力するhello.goとテストするためのhello_test.goを置く。

```go:hello.go
package main

import "fmt"

func getHello() string {
  return "Hello World"
}

func main() {
    fmt.Println(getHello())
}
```
hello.goは実行すればHelloWordの出力。これをテストします。

<img width="509" alt="スクリーンショット 2017-11-06 17.14.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/208513/d974da4a-d0c7-9a4d-341a-36a2d969c6a3.png">


```go:hello_test.go
package main

import (
    "testing"
)

func TestHello(t *testing.T) {
  if "Hello World" != getHello() {
    t.Fatal("failed test")
  }
}
```
testingをimport。ファイル名は必ず〇〇_test.goにしなければいけないようなので、hello_test.go。メソッド名も規則に則りTestHello()です。

これを実行すると、テストは通りますね。

```go
go test -v
```
<img width="349" alt="スクリーンショット 2017-11-06 17.15.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/208513/7fa2bb85-5f05-90d2-f5a9-d9c3df350ca1.png">

## assertやexpect的なものがない？
go言語にはphpのassertやrubyのexpectのようなものがないみたいです。

公式のgithubのサンプルを少しみてみましょう。

```go
func runExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ran, ok bool) {
	ok = true

	var eg InternalExample

	for _, eg = range examples {
		matched, err := matchString(*match, eg.Name)
		if err != nil {
			fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\n", err)
			os.Exit(1)
		}
		if !matched {
			continue
		}
		ran = true
		if !runExample(eg) {
			ok = false
		}
	}

	return ran, ok
}
```
https://github.com/golang/go/blob/master/src/testing/example.go
if文で行っていますね。
ちょっと不思議な感じですが、これがgoなのでしょう。

ドキュメントに理由が書いてあります。
[アサーション機能はないのですか？](http://go.shibu.jp/faq.html#21)

>### アサーション機能は無いのですか？¶
Goはアサーション機能を提供しません。アサーションが便利なのは否定できませんが、我々の経験上プログラマは、それを適切なエラー処理とエラー出力を避けるために使っています。適切なエラー処理とは、サーバがクラッシュする代わりに致命的ではないエラーを発生するにとどめ、処理を続けられるということを意味しています。適切なエラー出力は、エラーが直接的や部分的だったとき、クラッシュ時の膨大なトレースを翻訳する作業からプログラマを開放することを意味します。正確なエラー出力は、エラーを見つけたプログラマーがそのコードに精通していない時ほど重要です。

## いや、それでもAssert使いたい
Goの考えはわかった。でも、私はassertを使いたい。そんな時にはassertのパッケージがあるので、それを使いましょう。

https://github.com/stretchr/testify
これです。

こんな使い方ができるようです。

```go

func TestSomething(t *testing.T) {

  // assert equality
  assert.Equal(t, 123, 123, "they should be equal")

  // assert inequality
  assert.NotEqual(t, 123, 456, "they should not be equal")

  // assert for nil (good for errors)
  assert.Nil(t, object)

  // assert for not nil (good when you expect something)
  if assert.NotNil(t, object) {

    // now we know that object isn't nil, we are safe to make
    // further assertions without causing any errors
    assert.Equal(t, "Something", object.Value)

  }
```
https://github.com/stretchr/testify
テストっぽい感じがしますね。
さっきのHello Wordのテストをこっちに書き換えます。

```go
go get github.com/stretchr/testify/assert
//インストール
```

```go:hello_test.go
package main

import (
    "testing"
    "github.com/stretchr/testify/assert"
)

func TestHello(t *testing.T) {
    assert.Equal(t, getHello(), "Hello World")
}
```

さっきと同じようにテストを実行すると、通ります。
<img width="510" alt="スクリーンショット 2017-11-06 17.11.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/208513/fe48c976-d73b-7a2e-c1c6-6c751d4b1051.png">