2013年12月21日(Sat) 公園で子どもたちと鬼ごっこ [同日]
● [golang] Goのテストツール
GoとC++で作るB木シリーズ。やっとこgo testでB木のテストが動いたので今日はgo testの動作を掘り下げてみた。 go testでは*_test.goのテストケースが実行される。 テストされるコードは、 *.goから読まれたうちの、packageの記述が合っているもののようだ。 そして、テストケース内の名前空間は、 テストされるコードの名前空間と同じみたい
$ go help
してみると「Go is a tool for managing Go source code.」 サブコマンドとしては、build、clean、…、testなどがあるとのこと。
$ go help test usage: go test [-c] [-i] [build flags] [packages] [flags for test binary] <中略> 'Go test' recompiles each package along with any files with names matching the file pattern "*_test.go". <中略> By default, go test needs no arguments. It compiles and tests the package with source in the current directory, including tests, and runs the tests. The package is built in a temporary directory so it does not interfere with the non-test installation.
あー。だからバイナリとかカレントディレクトリには見えなかったのか。
実行される側のソースコードはどういう風になってるんだろう。 普通のGoプログラムは実行を始める場所に package mainを記述してfunc main()を 定義しないといけないようだけれど、btree_test.goにはどちらも無い。 代わりに、package btreeという記述がある。 これは、btree.goというファイル名に対応してるのかな? それともbtree.go内のpackage btreeという記述に対応してるのかな? 試してみる。
$ touch zunuda_test.go $ go test can't load package: package .: zunda_test.go:1:1: expected 'package', found 'EOF' $ echo package zunda >| zunda_test.go $ go test testing: warning: no tests to run PASS ok _/home/zunda/tmp/omanuke 0.011s
最低限packageの行があれば実行はできるようだ。 もう少し何かを実行してもらうには…zunuda_test.goに内容を下記のようにすると
package zunda
import (
"fmt"
"testing"
)
func TestHello(t *testing.T) {
fmt.Printf("Hello World\n")
}
下記のように実行された。 カレントディレクトリには他のファイルは置いていない。
$ go test Hello World PASS ok _/home/zunda/tmp/omanuke 0.011s
package zundaの行はどのように活用されるのかな。 Pythonみたいにパッケージ名とファイル名を一致させる必要があるのかな。 とりあえずzunda.goにpackage zundaを書いてみる:
package zunda
import (
"fmt"
)
func Greet() {
fmt.Printf("Hello World\n")
}
packageが一致してると呼び出し元からは指定する必要はないようだ。 zunda_test.goを下記のようにして
package zunda
import (
"testing"
)
func TestHello(t *testing.T) {
Greet()
}
go testすると「Hello World」が表示されるが、 Greet()をzunda.Greet()とすると
$ go test # _/home/zunda/tmp/omanuke ./zunda_test.go:8: undefined: zunda FAIL _/home/zunda/tmp/omanuke [build failed]
となる。ではファイル名を変えてみると…
$ mv zunda.go zundan.go $ go test Hello World PASS ok _/home/zunda/tmp/omanuke 0.011s $ mv zundan.go zunda.ngo $ go test # _/home/zunda/tmp/omanuke ./zunda_test.go:8: undefined: Greet FAIL _/home/zunda/tmp/omanuke [build failed]
ファイル名は関係なく、 *.goからpackage zundaを頼りにコードを読んでるようだ。
$ sed s/zunda/zundan/ zunda.ngo > zunda.go $ go test can't load package: package .: found packages zundan (zunda.go) and zunda (zunda_test.go) in /home/zunda/tmp/omanuke
蛇足。importの時はファイル名とpackageとどちらを気にするのかな。 greet.goを用意して:
package main
import "zunda"
func main() {
zunda.Greet()
}
あれ、8gもgccgoもないよ?gccgoをapt-get installしました。
$ gccgo greet.go greet.go:3:13: error: import file ‘zunda’ not found greet.go:6:2: error: reference to undefined name ‘zunda’ $ gccgo greet.go zunda.go greet.go:3:13: error: import file ‘zunda’ not found zunda.go:1:1: error: expected package ‘main’ greet.go:6:2: error: reference to undefined name ‘zunda’
おや。zundaをimportできるようにするにはどうするんだ? というかpackage mainがカレントディレクトリにあると go testもうまくいかなくなるのだね。
$ go test can't load package: package .: found packages main (greet.go) and zunda (zunda.go) in /home/zunda/tmp/omanuke
Goのパッケージ?のつくりかたについて勉強する必要がありそうですね。
- https://www.google.co.jp/ ×15
- http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&s... ×1
- http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&s... ×1
- https://www.google.es/ ×1
- http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&s... ×1
- http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&s... ×1
- zundago ×1
最近のツッコまれどころ