Help us understand the problem. What is going on with this article?

はじめてのgolang デバッグ&テストコード

More than 1 year has passed since last update.

というわけで最近 Tour of go をやり直してます。
golangのデバッグとテストコードはそういえばどうやるんだろう思ってやってみました。

対象は以下のFizzBuzzコードです。

fizzbuzz.go
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 というのを使いました。

https://github.com/derekparker/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するように変えたものへのテストコードを書いてみました。

fizzbuzz.go
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文字
を返すようにしているので、テストコードでもそれが正しく返されているかを確認します。
※エラーメッセージはおふざけでごめんなさい

fizzbuzz_test.go
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ではじめてのテストコードが通りました ヽ(・∀・ )ノ キャッ キャッ

おしまい。

sat0ken
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away