Go2 Advent Calendar 2017 12日目の記事です。
昨日たまたま空きを見つけたので代筆させていただきます。
はじめに
先日Go4 Advent Calendar 2017 2日目でGoで標準出力をテストする方法という記事を書きました。
要約すると、理想的には fmt.Fprint()
などで io.Writer
を渡す形でテスタブルに実装した方がよいが、都合上できない場合は os.Stdout
を差し替えてそれを読むようにすればよい、という内容です。
ただこれを毎回実装するのも面倒なので、パッケージとして公開しました。
使い方
パッケージの使い方はREADMEやgodocのとおりですが、以下に例を示します。
先日の記事では、次のようなコードに対してテストを実装しました。
main.go
:
package main
import (
"flag"
"fmt"
"os"
)
const (
ExitCodeOK = iota
ExitCodeError
)
func main() {
os.Exit(run(os.Args[1:]))
}
func sum(x, y int) int {
return x + y
}
func run(args []string) int {
var x, y int
flags := flag.NewFlagSet("sum", flag.ContinueOnError)
flags.IntVar(&x, "x", 0, "Value for x")
flags.IntVar(&y, "y", 0, "Value for y")
flags.Parse(args)
fmt.Printf("%d + %d = %d\n", x, y, sum(x, y))
return ExitCodeOK
}
この標準出力をともなう main()
に対するテストは、go-capturerを用いると次のように書けます。
main_test.go
:
package main
import (
"testing"
"github.com/kami-zh/go-capturer"
)
func TestRun(t *testing.T) {
var code int
out := capturer.CaptureStdout(func() {
code = run([]string{"-x", "2", "-y", "3"})
})
if code != ExitCodeOK {
t.Errorf("Unexpected exit code: %d", code)
}
if out != "2 + 3 = 5\n" {
t.Errorf("Unexpected output: %s", out)
}
}
標準出力だけでなく標準エラー出力も取得でき、また上のように関数の返り値も得ることができます。
思ったこと
今回はじめてGoのパッケージをつくったのですが、
- GitHubにリポジトリを追加してREADMEを書くだけでgodocができており、さらにExampleなどもあってすごい
- go reportという外部サービスでgofmtやgolintによるチェックとを行ってくれるので便利
という感想を持ちました。