LoginSignup
1
1

More than 3 years have passed since last update.

Golang勉強メモ②単体テスト

Last updated at Posted at 2020-05-10

golangの単体テストは、golangの標準パッケージ
testingを使用することで作成することができる。
testing

検証環境のディレクトリ構造

golang
├main.go
└person
 ├person.go
 └person_test.go

VSCode上での単体テスト作成方法

テストしたいメソッドの上でコンテキストメニューを開き、
Go:generate Unit Tests For Functionを選択するとテストコードが生成される。
testing{テスト対象のソース名}_test.goというファイルを生成する。

ezgif.com-video-to-gif (5).gif

main.go
package main

import (
    "fmt"
    "./person"
)

func main() {
    fmt.Println("start")
    person.InitPerson()

}
person.go
package person

import "fmt"

// Person Recording Persons Score & rank.
type Person struct {
    name    string
    english int
    rank    string
}

// InitPerson doing Initialize Person.
func InitPerson() {
    Bob := Person{"Bob", 60, ""}
    Bob.rank = Score(Bob)
    fmt.Printf("Name:%v\n", Bob.name)
    fmt.Printf("Score:%v\n", Bob.english)
    fmt.Printf("rank:%v\n", Bob.rank)
}

// Score Return rank by score.
func Score(p Person) string {
    if p.english > 80 {
        return "A"
    } else if p.english > 60 {
        return "B"
    } else {
        return "C"
    }
}

person.goのScoreメソッドに対して、下記のテストコードが生成される。

person_test.go
package person

import (
    "testing"
)
func TestScore(t *testing.T) {
    type args struct {
        p Person
    }
    tests := []struct {
        name string
        args args
        want string
    }{
        // TODO: Add test cases.
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            if got := Score(tt.args.p); got != tt.want {
                t.Errorf("Score() = %v, want %v", got, tt.want)
            }
        })
    }
}

生成されたコードのstructにテスト対象の値を渡し、テストを実行することもできるが、
今回はスケルトンを使用せず、下記の通りテストコードを作成した。

score_test.go
package person

import (
    "testing"
)

func TestScore_1(t *testing.T) {
    p := Person{"Bob", 60, ""}
    actual := Score(p)
    expected := "C"
    if actual != expected {
        t.Errorf("got %v want %v", actual, expected)
    }
}

VSCode上で、メソッド上部に表示されるrun testを実行すると
メソッド単位でテストを実行することができる。
実行すると、下記の結果がターミナルに出力される。

Running tool: /usr/local/go/bin/go test -timeout 30s -run ^(TestScore_1)$

PASS
ok      _/Users/username/golang/golang/person   0.010s
Success: Tests passed.

また、テストコードを格納しているディレクトリで
go test .を実行すると、ディレクトリ内の全テストを実行する事ができる。
先程のコードに新たに2ケース追加した。
失敗時の動作を確認するためTestScore_3はNGケースを設定している。

person_test.go
package person

import (
    "testing"
)

func TestScore_1(t *testing.T) {
    p := Person{"Bob", 90, ""}
    actual := Score(p)
    expected := "A"
    if actual != expected {
        t.Errorf("got %v want %v", actual, expected)
    }
}

func TestScore_2(t *testing.T) {
    p := Person{"Bob", 80, ""}
    actual := Score(p)
    expected := "B"
    if actual != expected {
        t.Errorf("got %v want %v", actual, expected)
    }
}

//NG case
func TestScore_3(t *testing.T) {
    p := Person{"Bob", 60, ""}
    actual := Score(p)
    expected := "B"
    if actual != expected {
        t.Errorf("got %v want %v", actual, expected)
    }
}

上記テストの実行結果は下記の通りである。
失敗すると、正常な結果が得られなかったソースの箇所と、
設定したエラーメッセージがターミナルに表示される。
1箇所エラーが発生した時点で、後続のコードは実行されない。

$ go test .
--- FAIL: TestScore_3 (0.00s)
    person_test.go:31: got C want B
FAIL
FAIL    _/Users/username/golang/golang/person 0.006s
FAIL

カバレッジの取得

-coverオプションをつけることで、カバレッジを取得することができる。

go test . -cover
ok      _/Users/username/golang/golang/person 0.011s  coverage: 50.0% of statements

また、カバレッジをHTMLとして出力することもできる。
test-coverprofileオプションで、カバレッジプロファイルをファイルに出力し、
出力したファイルをgo tool coverでHTMLファイルへ変換する。

$go test -coverprofile=cover.out ./
ok      _/Users/username/golang/golang/person 0.007s  coverage: 50.0% of statements
$ go tool cover -html=cover.out -o cover.html

カバレッジをhtmlで表示すると下記の通り。

image.png

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1