LoginSignup
68
40

More than 5 years have passed since last update.

Go でコードカバレッジを取得する

Posted at

ローカル環境でコードカバレッジを確認する

まずテストを記述する必要がある. How to Write Go Code を参考にして,

feature/greet.go
func Greet(name string, lang string) string {
    switch lang {
    case "en":
        return fmt.Sprintf("Hello, %s.", name)
    case "ja":
        return fmt.Sprintf("こんにちは, %s.", name)
    }
    return "..."
}

という関数に対して,

feature/greet_test.go
type TestCase struct {
    Name     string
    Language string
}

func TestGreet(t *testing.T) {
    cases := []struct {
        in       TestCase
        expected string
    }{
        {TestCase{Name: "World", Language: "en"}, "Hello, World."},
        {TestCase{Name: "Kazumasa", Language: "ja"}, "こんにちは, Kazumasa."},
    }
    for _, c := range cases {
        actual := Greet(c.in.Name, c.in.Language)
        if actual != c.expected {
            t.Errorf("Greet(%q, %q) == %q, expect %q",
                c.in.Name, c.in.Language, actual, c.expected)
        }
    }
}

というようなテストを書いてみる. (完全なソースファイルは ここ にある.)

テストを用意したところで, go test-cover オプション付きで実行すると, カバレッジが出力される.

$ go test -cover ./feature/
ok      github.com/kkohtaka/go-scaffold/feature 0.006s  coverage: 75.0% of statements

普通はどの行がカバーされていないかが知りたいと思うので HTML で出力してみる. そこで, go test-coverprofile オプションでカバレッジプロファイルをファイルへ出力し, go tool cover で HTML へ変換する.

$ go test -coverprofile=cover.out ./feature/
ok      github.com/kkohtaka/go-scaffold/feature 0.006s  coverage: 75.0% of statements
$ go tool cover -html=cover.out -o cover.html
$ open cover.html

出力された HTML のサンプルは このような感じ.

CI と組み合わせてコードカバレッジを共有する

ローカル環境でコードカバレッジを確認するだけでなく, 他の開発者とコードカバレッジを共有する方法として, CodecovCoveralls を試してみた. また, CI サービスとしては Travis CI を利用した. (同じ要領で Drone.io でも動作を確認した.)

流れとしては,

  1. CI 環境で必要なパッケージをインストール
  2. テストを実行してカバレッジプロファイルを出力
  3. Codecov, Coveralls それぞれの用意しているスクリプトで結果をアップロード

となる. .travis.yml は下記のような感じ.

.travis.yml
before_install:
# Codecov に必要なファイルをインストール
- go get github.com/onsi/gomega
- go get github.com/onsi/ginkgo
# Coveralls に必要なファイルをインストール
- go get github.com/mattn/goveralls
# 両方に必要なファイルをインストール
- go get golang.org/x/tools/cmd/cover

script:
# テストを実行してカバレッジプロファイルを出力
- ./go_test.sh

after_success:
# Codecov へ結果をアップロード
- bash <(curl -s https://codecov.io/bash)
# Coveralls へ結果をアップロード
- $GOPATH/bin/goveralls -coverprofile=coverage.txt -covermode=count -service=travis-ci -repotoken $COVERALLS_TOKEN

注意しなければいけない点として, go test -cover が複数の Go パッケージのテストをサポートしていないので, カバレッジの取得対象が複数のパッケージを含んでいる場合には各々のカバレッジ結果をマージする必要がある. ここでは下記のようなスクリプトを記述することで対応した. (完全なソースファイルは ここ にある.)

go_test.sh
echo "mode: $COVERMODE" > $COVERAGE_FILE

for PKG in $(go list ./...); do
  go test -v -coverprofile=$TMP_FILE -covermode=$COVERMODE $PKG
  if [ -f $TMP_FILE ]; then
    # カバレッジ結果の先頭の "mode: ..." という行を削除
    cat $TMP_FILE | tail -n +2 >> $COVERAGE_FILE
    rm $TMP_FILE
  fi
done

Codecov, Coveralls それぞれでの出力結果は下記で確認できる.

参考

68
40
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
68
40