というわけで最近 Tour of go をやり直してます。
golangのデバッグとテストコードはそういえばどうやるんだろう思ってやってみました。
対象は以下のFizzBuzzコードです。
package main
import (
"fmt"
)
func main() {
for i := 1; i < 100; i++ {
if i%3 == 0 && i%5 == 0 {
fmt.Println(i, "FizzBuzz")
} else if i%3 == 0 {
fmt.Println(i, "Fizz")
} else if i%5 == 0 {
fmt.Println(i, "Buzz")
} else {
fmt.Println(i)
}
}
}
デバッグ
GDBでもできるようですが、Windows環境だったため delve というのを使いました。
go get コマンドでインストールしました。
> go get -u github.com/derekparker/delve/cmd/dlv
インストールしたらソースがあるフォルダに移動して、delve debug コマンドで実行します。
b (break) main.main で main関数のスタートにbreakpointを張って、c (continue)で
続行します。
n (next) で1行進む、s (step) でステップイン、p (print) で変数の値を見ることができました。
このへんはgdbやpythonのpdbと同じですね。
c:\work\gomi\fizzbuzz>dlv debug fizubuzz.go
Type 'help' for list of commands.
(dlv) b main.main
Breakpoint 1 set at 0x4a87b2 for main.main() c:/work/gomi/fizzbuzz/fizubuzz.go:7
(dlv) c
> main.main() c:/work/gomi/fizzbuzz/fizubuzz.go:7 (hits goroutine(1):1 total:1) (PC: 0x4a87b2)
2:
3: import (
4: "fmt"
5: )
6:
=> 7: func main() {
8:
9: for i := 1; i < 100; i++ {
10: if i%3 == 0 && i%5 == 0 {
11: fmt.Println(i, "FizzBuzz")
12: } else if i%3 == 0 {
(dlv) n
> main.main() c:/work/gomi/fizzbuzz/fizubuzz.go:9 (PC: 0x4a87c9)
4: "fmt"
5: )
6:
7: func main() {
8:
=> 9: for i := 1; i < 100; i++ {
10: if i%3 == 0 && i%5 == 0 {
11: fmt.Println(i, "FizzBuzz")
12: } else if i%3 == 0 {
13: fmt.Println(i, "Fizz")
14: } else if i%5 == 0 {
(dlv) s
> main.main() c:/work/gomi/fizzbuzz/fizubuzz.go:10 (PC: 0x4a87e4)
5: )
6:
7: func main() {
8:
9: for i := 1; i < 100; i++ {
=> 10: if i%3 == 0 && i%5 == 0 {
11: fmt.Println(i, "FizzBuzz")
12: } else if i%3 == 0 {
13: fmt.Println(i, "Fizz")
14: } else if i%5 == 0 {
15: fmt.Println(i, "Buzz")
(dlv) p i
1
(dlv)
より詳しい使い方はこちらにまとまっています。(ありがとうございます)
https://qiita.com/minamijoyo/items/4da68467c1c5d94c8cd7
テストコード
delveでポチポチ動作を確認していくのはさすがにつらさがあります。
テストコードで確認できるならそっちのほうがいいですよね。
でgolangでテストコードどう書くんでしたっけ?
Webの海をさまよい、golangのテストコードは以下のことを守ればよさそうです。
・testingパッケージをimportする
・ファイル名は_test.goとする
・Testで始まる関数を作成して、引数で(t *testing.T)を取る
・go testコマンドで実行する。
https://blog.alexellis.io/golang-writing-unit-tests/
※見覚えある名前と思ったら、OpenFaasの作者さんですね。
fizzbuzzの結果を関数でreturnするように変えたものへのテストコードを書いてみました。
package main
import (
"fmt"
)
func fizzbuzz(x int) (result string) {
if x%3 == 0 && x%5 == 0 {
result = "FizzBuzz"
} else if x%3 == 0 {
result = "Fizz"
} else if x%5 == 0 {
result = "Buzz"
} else {
result = ""
}
return
}
func main() {
for i := 1; i < 100; i++ {
fmt.Println(i, fizzbuzz(i))
}
}
テストコードです。
fizzbuzz.goではfizzbuzz関数は引数のiのをチェックしてFizz、Buzz、FizzBuzz、Null文字
を返すようにしているので、テストコードでもそれが正しく返されているかを確認します。
※エラーメッセージはおふざけでごめんなさい
package main
import (
"testing"
)
func Test_FizzBuzz(t *testing.T) {
for i := 0; i < 100; i++ {
result := fizzbuzz(i)
if i%3 == 0 && i%5 == 0 {
if result != "FizzBuzz" {
t.Errorf("あかんやろ")
}
} else if i%3 == 0 {
if result != "Fizz" {
t.Errorf("あかんやろ")
}
} else if i%5 == 0 {
if result != "Buzz" {
t.Errorf("あかんやろ")
}
} else {
if result != "" {
t.Errorf("あかんやろ")
}
}
}
}
テストコードをテスト対象のコードと同じフォルダに置いて実行します。
c:\work\gomi\fizzbuzz\test>ls
fizubuzz.go fizzbuzz_test.go
c:\work\gomi\fizzbuzz\test>go test
PASS
ok _/c_/work/gomi/fizzbuzz/test 0.118s
c:\work\gomi\fizzbuzz\test>
ということでgolangではじめてのテストコードが通りました ヽ(・∀・ )ノ キャッ キャッ
おしまい。