LoginSignup
1
1

More than 1 year has passed since last update.

[Go]テストコード

Last updated at Posted at 2022-09-02

1. テストコードの実装に必要なこと

  • テストコードを書くファイルについて
    • ファイル名: xxx_test.goとする
    • ファイルの配置: テスト対象関数のパッケージのディレクトリ
  • テストコードファイルの記述
    • packageディレクティブでテスト対象関数のパッケージを指定
    • 標準出力のテストの場合
      • 対象関数に対するテストは、引数なしのExampleXxxという名前の関数で記述する
    • 標準出力以外のテストの場合
      • importディレクティブでテストtestingパッケージを指定
      • 対象関数に対するテストは、引数がt *testing.TであるTestXxxという名前の関数で記述する

2. テストコードの実装

2.1. 前提

以下のような構成・内容のモジュールが存在するとして、各関数に対してテストコードを実装する場合を例にする。

ディレクトリ・ファイル構成

go_test_code/
  return_values/
    return_add_value.go
    return_sub_value.go
  print_values/
    print_add_value.go
    print_sub_value.go
  go.mod
return_add_value.go
package return_values

// 引数x, yの和を返す
func ReturnAddValue(x, y int) int {
  return x + y
}
return_sub_value.go
package return_values

// 引数x, yの差を返す
func ReturnSubValue(x, y int) int {
  return x - y
}
print_add_value.go
package print_values

import "fmt"

// 引数x, yの和を出力
func PrintAddValue(x, y int) {
  fmt.Println(x + y)
}
print_add_value.go
package print_values

import "fmt"

// 引数x, yの差を出力
func PrintSubValue(x, y int) {
  fmt.Println(x - y)
}
go.mod
module github.com/<オーナー名>/go_test_code

go 1.19

※go.modは、「ディレクトリ・ファイル構成」にあるgo.mod以外のディレクトリ・ファイルを配置した上でgo mod init github.com/<オーナー名>/go_test_codeを実行して作成

2.2. テストコードの実装

2.1.に引き続いて、テストコードファイルとして、以下★のファイルを作成する。

ディレクトリ・ファイル構成

go_test_code/
  return_values/
    return_add_value.go
    return_sub_value.go
    return_values_test.go # ★
  print_values/
    print_add_value.go
    print_sub_value.go
    print_values_test.go # ★
  go.mod
return_values_test.go
package return_values

import "testing"

// テスト関数名はTestXxxという形でさえあればいいが、「Test+<テスト対象関数名>」という命名にするのが無難そう

// ReturnAddValue()のテスト
func TestReturnAddValue(t *testing.T) {
    // テストに際し、テスト対象関数に与える引数を定義
    x, y := 2, 3

    // 期待結果を定義
    expect := 5

    // テスト対象関数を実行
    got := ReturnAddValue(x, y)
    
    // 実行結果と期待結果を比較し、エラーだったら出力
    if got != expect {
      t.Errorf("exec ReturnAddValue() expect: %v, got: %v, x: %v, y: %v", expect, got, x, y)
    }
}

// ReturnSubValue()のテスト
func TestReturnSubValue(t *testing.T) {
	// テストに際し、テスト対象関数に与える引数を定義
	x, y := 8, 3

	// 期待結果を定義
	expect := 5

	// テスト対象関数を実行
	got := ReturnSubValue(x, y)
	
	// 実行結果と期待結果を比較し、エラーだったら出力
	if got != expect {
		t.Errorf("exec ReturnSubValue() expect: %v, got: %v, x: %v, y: %v", expect, got, x, y)
	}
}


print_values_test.go
package print_values

// PrintAddValue()のテスト
func ExamplePrintAddValue() {
	// テストに際し、テスト対象関数に与える引数を定義
	x, y := 2, 3

	// テスト対象関数を実行
    PrintAddValue(x,y)

	// 期待結果

    // Output:
    // 5
}

// PrintSubValue()のテスト
func ExamplePrintSubValue() {
	// テストに際し、テスト対象関数に与える引数を定義
	x, y := 2, 3

	// テスト対象関数を実行
    PrintSubValue(x,y)

	// 期待結果
	
    // Output:
    // -1
}

2.3. テストの実行

# モジュールパス直下へ移動
cd <モジュールパス直下>

# テストの実行
## カレントディレクトリ以下のすべてのテストコードを実行する場合
go test -v ./...
## 特定のディレクトリのテストコードを実行する場合
go test -v <ディレクトリへのパス>
## 特定のディレクトリ以下のすべてのテストコードを実行する場合
go test -v <ディレクトリへのパス>/...
## カレントディレクトリ以下の特定の文字列をテスト関数名に含むテストコードを実行する場合
go test -v -run <文字列> ./...

補足
...は、goコマンドでワイルドカード的な意味をもつらしい。
-vはとりあえずつけておいた方がよい。

3. ルールを破ったらどうなるのか実験

3.1. テストコードのファイル名を_test.goじゃないものにして実行

「テストファイルがない」と言われる!

# go_test_code/print/values/return_values_test.go を return_values_test2.goに変更してある
go test -v ./print_values
=>
?       github.com/<オーナー名>/go_test_code/print_values  [no test files]

3.2. テスト関数名をTestXxx、じゃないものにして実行

テストが飛ばされる!(エラーは発生しない)

# 1. 何もせず以下実行
go test -v ./return_values
=>
=== RUN   TestReturnAddValue
--- PASS: TestReturnAddValue (0.00s)
=== RUN   TestReturnSubValue
--- PASS: TestReturnSubValue (0.00s)
PASS
ok      github.com/<オーナー名>/go_test_code/return_values

# 2. return_values_test.go内の「TestReturnAddValue」を「TesReturnAddValue」に変更後に以下実行
go test -v ./return_values
=> [TestReturnAddValueの出力がない!]
=== RUN   TestReturnSubValue
--- PASS: TestReturnSubValue (0.00s)
PASS
ok      github.com/<オーナー名>/go_test_code/return_values 0.230s

3.3. テスト対象関数のファイルがあるディレクトリじゃないところへ、テスト対象関数のテストコードを書いた_test.goファイルを配置して実行

テスト対象の関数が未定義だと言われ、ビルドに失敗する

# go_test_code/return_values/return_values_test.go を go_test_code/ へ移動して以下実行
go test -v ./...
=>
# github.com/<オーナー名>/go_test_code [github.com/<オーナー名>/go_test_code.test]
./return_values_test.go:16:12: undefined: ReturnAddValue
./return_values_test.go:33:9: undefined: ReturnSubValue
FAIL    github.com/<オーナー名>/go_test_code [build failed]
=== RUN   ExamplePrintAddValue
--- PASS: ExamplePrintAddValue (0.00s)
=== RUN   ExamplePrintSubValue
--- PASS: ExamplePrintSubValue (0.00s)
PASS
ok      github.com/<オーナー名>/go_test_code/print_values  (cached)
?       github.com/<オーナー名>/go_test_code/return_values [no test files]
FAIL

参考

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