Go TestScript

Go TestScript #

概要 #

テストコードの書き方 #

定義済コマンドをテストで使用 #

testdata/script/TestFoo/hello-world.txt

exec echo 'hello world!'
stdout 'hello world!\n'

sample_test.go

package sample_test

import (
	"path/filepath"
	"testing"

	"github.com/rogpeppe/go-internal/testscript"
)

var scriptDir = filepath.Join("testdata", "script")

func TestFoo(t *testing.T) {
	t.Parallel()
	testscript.Run(t, testscript.Params{
		Dir:         filepath.Join(scriptDir, t.Name()),
		WorkdirRoot: t.TempDir(),
	})
}

独自のコマンドを作成してテストで使用 #

testdata/script/TestFoo/hello-world.txt

mycat hello.txt world.txt
stdout 'hello\n'
stdout 'world!\n'

-- hello.txt --
hello
-- world.txt --
world!

sample_test.go

package sample_test

import (
	"os"
	"path/filepath"
	"testing"

	"github.com/rogpeppe/go-internal/testscript"
)

var scriptDir = filepath.Join("testdata", "script")

func TestMain(m *testing.M) {
	os.Exit(testscript.RunMain(m, map[string]func() int{
		"mycat": mycat,
	}))
}

func TestFoo(t *testing.T) {
	t.Parallel()
	testscript.Run(t, testscript.Params{
		Dir:         filepath.Join(scriptDir, t.Name()),
		WorkdirRoot: t.TempDir(),
	})
}

// mycat behaves like cat command.
// Do NOT use *testing.T as an argument because we use mycat in testscript.RunMain().
func mycat() int {
	if len(os.Args) == 1 {
		_, err := io.Copy(os.Stdout, os.Stdin)
		if err != nil {
			return 1
		}
		return 0
	}

	for _, fname := range os.Args[1:] {
		f, err := os.Open(fname)
		if err != nil {
			return 1
		}

		_, err = io.Copy(os.Stdout, f)
		if err != nil {
			return 1
		}
	}
	return 0
}

References #