Golangでテスト書くよ
testingというTest用のパッケージがあらかじめ用意されているので、それを使ってみます。使い方はこんな感じ。
テスト対象のコード
sample.go
package main func main(){ } func sum(v1 int, v2 int) int { return v1+v2 }
テストコード
sample_test.go
package main import "testing" func Test_sum(t *testing.T) { if sum(1,2) != 3 { t.Error("fail sum") } }
- Test***で始まるメソッドがテストの実行対象になります。詳しくは testing - The Go Programming Language
- testingにはassertのようなものは無く、ごり押しでif文書く感じ。他にもTest用のパッケージはあるみたいですが、とりあえず本家で用意されているものを使います。
Testを動かしてみる
- テストは以下のコマンドで実行され、実行するとつらつらとテスト結果が表示されます。-vオプションはテストの詳細を表示するオプションです。
$ go test -v === RUN Test_sum --- PASS: Test_sum (0.00 seconds) PASS ok _/Users/rei_m/Documents/go/travisSample 0.010s
Travisと連携する
language: go script: - go test -v
では、意図的にTestを失敗させてみます。上のsumのTestメソッドが合わないように修正してローカルでテストを動かしてみます。
func Test_sum(t *testing.T) { if sum(1,2) != 4 { t.Error("fail sum") } }
$ go test -v === RUN Test_sum --- FAIL: Test_sum (0.00 seconds) sample_test.go:7: fail sum FAIL exit status 1 FAIL _/Users/rei_m/Documents/go/travisSample 0.008s
テストがこけてtestingのErrorメソッドにセットした文字列が表示されています。この状態でGithubにpushしてみます。
「add fail case」が今回のcommitです。Travis上でテストがこけてmergeすんなよと教えてくれているのがわかります。
では、先ほどのコードをテストが動く状態に戻してpushしてみます。
今度はテストが通ってmergeしても大丈夫ということがわかりました。pushを契機にTravis上でテストが正しく実行されています。
httpServerのテスト
golangはhttpパッケージが用意されていて、簡単にhttpサーバーが立てられます。その場合のテストも試してみました。先ほどのコードにhttpサーバーを立てるコードを追加します。
sample.go
package main import ( "fmt" "net/http" ) func main(){ handler := createHandler("{\"sample\":\"sampleValue\"}") http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) } func sum(v1 int, v2 int) int { return v1+v2 } func createHandler(res string) (func(w http.ResponseWriter, r *http.Request)) { return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Content-Type", "application/json") fmt.Fprintf(w, res) return } }
createHandlerでhandlerを作成してmainメソッドでlistenしています。処理は渡したJSONをそのまま表示するだけのシンプルなものです。では起動してみます。
$ go run sample.go
portは8080でlistenしているのでブラウザでlocalhost:8080を表示します。
設定したJSONが表示されていますね。では、このhandler用のテストコードを追加します。
sample.go
package main import ( "io/ioutil" "net/http" "net/http/httptest" "testing" ) func Test_sum(t *testing.T) { if sum(1, 2) != 3 { t.Error("fail sum") } } func Test_createHandler(t *testing.T) { response := "{\"test\":\"testValue\"}" handler := createHandler(response) server := httptest.NewServer(http.HandlerFunc(handler)) defer server.Close() if res, err := http.Get(server.URL); err != nil { t.Error(err) } else { if res.StatusCode != 200 { t.Error("fail Test_createHandler 1") } else { if body, err := ioutil.ReadAll(res.Body); err != nil { t.Error(err) } else { if response != string(body) { t.Error("fail Test_createHandler 2") } } } res.Body.Close() } return }
Test_createHandlerというテスト用のメソッドを追加しました。この中で注目するのはhttptestというパッケージです。httptest.NewServerメソッドにテスト対象のhandlerを渡す事でテスト用のserverを返してくれるので、そこからResponseを取得してチェックできます。sampleでは渡したJSON文字列とResponseを比較して合っているかどうか見ています。
$ go test -v === RUN Test_sum --- PASS: Test_sum (0.00 seconds) === RUN Test_createHandler --- PASS: Test_createHandler (0.00 seconds) PASS ok _/Users/rei_m/Documents/go/travisSample 0.016s
作成したTest_createHandlerもテストが通りました。もちろんpushしてTravis上でテストしても同じ結果が返ります。
今回作ったコードはこちら
rei-m/go-Travis · GitHub