31
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ディップAdvent Calendar 2022

Day 21

go testのチュートリアルを作ってみた

Last updated at Posted at 2022-12-20

はじめに

この記事はディップ Advent Calendar 2022の21日目の投稿です。
早いもので今年のアドカレも残すところあと5日となりました。

弊社ではGoを用いたプロダクトが拡大中+内製化のため鋭意増員中です。
いずれのプロダクトでも単体テストを書く文化が根付いているため、
新規参画メンバーが早く馴染めるようにgo testのチュートリアルを作ってみました。

どんなもの?

あらかじめ実装されているコードに対し、単体テストを作成するチュートリアルです。

テストケースの作り方とgomockの使い方が学べる内容になっており、
Goに初めて触れる、単体テストを書いた経験が少ないひとをターゲットとしています。

課題はchapter5まであり、徐々に難易度が上がっていきます。
また、後半のchapterは実践向けな構成になっています。

ちょっと紹介

chapter1を紹介します。

課題内容

2つの数値を加算する関数がテスト対象です。
ただカバレッジを100%にするだけではNGで、以下の観点がテストケースに盛り込まれていることがポイントになります。

  • チェック順は仕様通りか確認できているか
  • 境界値チェックは実施できているか

スクリーンショット 2022-12-12 16.48.16.png

実装コード

chapter1.go
package chapter1

import "fmt"

func addtion(numA int, numB int) (int, error) {
	if numA < 0 {
		return 0, fmt.Errorf("numAは0以上の数値を指定してください。")
	}
	if numA > 100 {
		return 0, fmt.Errorf("numAは100以下の数値を指定してください。")
	}
	if numB < 10 {
		return 0, fmt.Errorf("numBは10以上の数値を指定してください。")
	}
	if numB > 200 {
		return 0, fmt.Errorf("numBは200以下の数値を指定してください。")
	}

	return numA + numB, nil
}

テストコード

chapter1_test.go
package chapter1

import (
	"testing"
)

func TestAddition(t *testing.T) {
	// 正常系のテストパターン
	success := map[string]struct {
		numA int
		numB int
		want int
	}{
		// FIXME: テストケースを追加
	}
	// エラー系のテストパターン
	fail := map[string]struct {
		numA       int
		numB       int
		wantErrStr string
	}{
		// FIXME: テストケースを追加
	}

	for tt, tc := range success {
		t.Run(tt, func(t *testing.T) {
			got, err := addtion(tc.numA, tc.numB)
			if err != nil {
				t.Errorf("err is not nil: %s", err)
			}
			if tc.want != got {
				t.Errorf("unexpected return. want:%d actual:%d", tc.want, got)
			}
		})
	}
	for tt, tc := range fail {
		t.Run(tt, func(t *testing.T) {
			got, err := addtion(tc.numA, tc.numB)
			if got != 0 {
				t.Errorf("unexpected return. want:0 actual:%d", got)
			}
			if tc.wantErrStr != err.Error() {
				t.Errorf("unexpected err. want:%s actual:%s", tc.wantErrStr, err)
			}
		})
	}
}

運用の話

弊社では新規に参画したメンバーにはまず当チュートリアルに取り組んでもらい、その後に業務へ合流していただいています。
チュートリアルは以下レギュレーションで実施しています。

  • chapterごとにプルリクエストを作成
  • slackでレビュー依頼を通知
  • 先輩エンジニアが適宜レビュー
  • 1名以上のapproveで次のchapterへ

ここで、個人的に重要だと感じているのが先輩エンジニアが適宜レビューの箇所です。
レビュー依頼が来たらできるだけ素早くリアクションし、レビューを実施しましょう。
チュートリアルを実施しているのは参画したばかりの人です。不安も多いかと思います。
先輩たちが率先して盛り上げていきましょう。

また、レビュー依頼は業務のコメントで流れてしまいがちなのでチュートリアル用チャンネルを作ると良いです。

さいごに

当チュートリアルをきっかけに少しでもGoに興味を持って頂ければ幸いです。
改善点、要望等ありましたらプルリクエストお待ちしています。

31
7
1

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?