2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【初歩の初歩】Go言語でテストコードを作ってみた

Last updated at Posted at 2023-11-08

はじめに

この記事は、エンジニア成り立ての「見習いエンジニア」が作成した記事になります。記事の内容で間違っているとことがありましたらコメントでご指摘いただけますと非常に励みになります!

テストコード作成の決まり

その1『ファイル名』

Goのテストでは、ファイル名を以下のような記載にする必要があります。

xxx_test.go

その2『"testing"』パッケージ

そして、importに以下のように"testing"パッケージの記載が必要です。

import {
    "testing"
}

その3『関数名は"func TestXxx(t *testing.T)"』

以上をまとめると以下のような記載になります。

// ファイル名 xxx_test.go

packege main

import {
    "testing"
}

func TestXxx(t *testing.T) {
    テスト内容
}

(t *testing.T)って何?

(t *testing.T) はGoのテスト関数における慣習的な引数です。

 *testing.T 型の変数で、Goの testing パッケージが提供する型。ここの変数 t はテスト中の状態を管理し、テストの制御やレポートを行うためのメソッドをいくつか提供できます。

変数 t を使用することにより、テスト関数の中で、以下のような操作が可能になります。

  • t.Errorf():エラーメッセージを出力してテストを失敗とします。
  • t.Fatalf():エラーメッセージを出力してテストを中止します。
  • t.Logf():テストのログ出力を行います。

テストコードの書いてみよう

モデルの例(model)

package model

type NameModel struct {
	FamilyName string
	LastName   string
}

func NewNameModel(
    familyName string, 
    lastName string) *NameModel {
    
	return &NameModel{
		FamilyName: familyName,
		LastName:   lastName,
	}
}

テストの例(test) ~正しい結果.ver~

package model

import "testing"

func TestNewNameModel(t *testing.T) {
	familyName := "山田"
	lastName   := "太郎"

	// NewNameModelを使って新しいNameModelを作成
	nm := NewNameModel(familyName, lastName)

	// FamilyNameが正しく設定されているかを確認
	if nm.FamilyName != familyName {
		t.Errorf("FamilyNameが期待する値でない。期待値: %v, 実際: %v", familyName, nm.FamilyName)
	}

	// LastNameが正しく設定されているかを確認
	if nm.LastName != lastName {
		t.Errorf("LastNameが期待する値ではない。期待値: %v, 実際: %v", lastName, nm.LastName)
	}
}

以上のテストコードをターミナルで以下のコマンドで実行してみます。

$ go test
    
PASS
ok      namaModel       0.241s

このように ok と出力されれば、テストは成功しています。

ちなみに、以下のコマンドの場合はログの詳細を含めてた上で出力がされます。

$ go test -v //(verboseモード)詳細情報を出力するためのログ出力

=== RUN   TestNewNameModel
--- PASS: TestNewNameModel (0.00s)
PASS
ok      namaModel       0.225s

さらにちなみに、以下のコマンドにすると、指定のテスト関数のみが実行されます。

$ go test -run TestNewNameModel -v

=== RUN   TestNewNameModel
--- PASS: TestNewNameModel (0.00s)
PASS
ok      namaModel       0.298s

テストの例(test) ~エラー結果.ver~

package model

import "testing"

func TestNewNameModel(t *testing.T) {
	familyName := "山田"
	lastName   := "太郎"

    // この部分で故意に間違った値を設定
	nm := NewNameModel("田中", "一郎") 

	if nm.FamilyName != familyName {
		t.Errorf("FamilyNameが期待する値でない。期待値: %v, 実際: %v", familyName, nm.FamilyName)
	}

	if nm.LastName != lastName {
		t.Errorf("LastNameが期待する値ではない。期待値: %v, 実際: %v", lastName, nm.LastName)
	}
}

このように正常系の結果と違う異常系の場合は以下のような結果になります。

$ go test -v

=== RUN   TestNewNameModel
    name_test.go:15: FamilyNameが期待する値でない期待値: 山田, 実際: 田中
    name_test.go:20: LastNameが期待する値ではない期待値: 太郎, 実際: 一郎
--- FAIL: TestNewNameModel (0.00s)
FAIL
exit status 1

TestNewNameModel を実行(Run)したところ、

name_test.go:15: FamilyNameが期待する値でない。期待値: 山田, 実際: 田中
name_test.go:20: LastNameが期待する値ではない。期待値: 太郎, 実際: 一郎

という結果でテストが失敗しました。
この結果は、NameModel のテストが期待する値と一致しなかったことを示しています。

このような記載が一般的なGoのテスト方法になります。これをベースにより詳細にテストを作成することも可能です。

t.Logf()関数を使用してみる

先ほどに記載しましたt.Logf()関数を使用することで、テストの実行中にログメッセージを出力するために使用されます。

テストが成功した場合、これらのログメッセージは通常非表示ですが、テストが失敗した場合に出力されます。

t.Logf()の例

package model

import "testing"

func TestNewNameModel(t *testing.T) {
	// NewNameModelを使って新しいNameModelを作成
	nm := NewNameModel("山田", "太郎")

	// テストの開始をログ出力
	t.Log("NewNameModelのテストを開始します。")

	// FamilyNameが正しく設定されているかを確認
	if nm.FamilyName != "山田" {
		t.Errorf("FamilyNameが正しくありません。期待する値: %s, 取得した値: %s", "山田", nm.FamilyName)
	} else {
		t.Logf("FamilyNameが正しく設定されています。値: %s", nm.FamilyName)
	}

	// LastNameが正しく設定されているかを確認
	if nm.LastName != "太郎" {
		t.Errorf("LastNameが正しくありません。期待する値: %s, 取得した値: %s", "太郎", nm.LastName)
	} else {
		t.Logf("LastNameが正しく設定されています。値: %s", nm.LastName)
	}
}
$ go test -run TestNewNameModel -v
=== RUN   TestNewNameModel
    name_test.go:10: NewNameModelのテストを開始します
    name_test.go:16: FamilyNameが正しく設定されています: 山田
    name_test.go:23: LastNameが正しく設定されています: 太郎
--- PASS: TestNewNameModel (0.00s)
PASS
ok      namaModel       0.274s

このようにt.Logfを使用すると、より詳細にテストコードの結果を出力することができます。

『%s』って何?
%s はGo言語における書式指定子(フォーマット指定子)の一つです。
PrintfやSprintf、Fprintfなどの関数で使用され、文字列(String)を書式指定して出力する場合に使用します。
今回の場合は、Logfの関数においてnm変数のFamilyNameプロパティの文字列値を出力しています。

まとめ

今回は、Go言語での基本的なテストコードの記載方法をまとめてみました。
今後は、テーブル駆動テストの記載方法をまとめていきたいと思います。

まだまだ学べることに感謝!

以上

この記事は以下のサイトや書籍を参考にして執筆しました

2
2
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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?