はじめに
「学生ひよこ界隈が送るGo/Javaで実現する「はじめてのバックエンド」Advent Calendar 2025」13日目の記事は、Goでのテストの書き方についてです。
個人開発のレベルにおいては「とりあえず動けばOK」と思い、テストを後回しにしがちです。
ですが、システムの規模がだんだん大きくなってくると、良かれと思って修正したコードが、別の機能に意図しないバグを生む、といった事案も増えてきます。
この記事では、バックエンドの品質を支える「テスト」を、Go言語の標準ライブラリだけを使って始める方法を紹介します。
- テストを書いたことがなく、何から始めれば良いか分からない方
- 自分の書いたバックエンドのコードに自信を持ちたい初学者の方
この記事で、Goで簡単な関数のユニットテストを作成・実行し、コードの品質を担保するための第一歩を踏み出せるように、頑張りましょう!
テストの重要性
まず、テストを書く目的について、幾つかおさらいです。
- バグの早期発見: 開発の早い段階でバグを見つけ、修正コストを低く抑えます
- リファクタリング: テストが「安全網」となり、コードの改善や変更を恐れずに行えるようになります
- 生きたドキュメント: テストコードは、その関数が「どのように動作することを期待されているか」を示す、最も正確な仕様書(ドキュメント)になります
テストを書くと、後々修正作業にかける時間のコストを比較したときに圧倒的に差がつくため、実はテストを書いている時間以上の価値があります。
【実践】testing パッケージを使ったテストの実装
Goは、テストのためのフレームワークが標準ライブラリに組み込まれています。
それで、サードパーティのライブラリをインストールしなくても、すぐにテストを書き始めることができます。
Goのテストには、いくつかのシンプルな規約があります。
- テストファイルの名前は
xxx_test.goのように、_test.goで終わる。 - テスト用の関数名は
Testで始まり、その後にテスト対象の関数名などを続ける(例:TestAdd)。 - テスト関数は、引数として
t *testing.Tを受け取る。
そして、テストの実行は go test コマンド一つで完了します。
シンプルな関数のユニットテストの実装
それでは、実際にテストを書いてみましょう。
go mod initした状態から始めます。
まず、テスト対象となる、2つの整数を足し算する簡単な関数を用意します。
add.goに以下のように記述します。
package main
func Add(a, b int) int {
return a + b
}
次に、このAdd関数をテストするためのコードを、同じディレクトリにadd_test.goという名前で作成し、以下のコードを記述します。
package main
import "testing"
func TestAdd(t *testing.T) {
// 期待する結果 (want) と、実際の結果 (got) を比較する
got := Add(2, 3)
want := 5
if got != want {
// 結果が異なれば、t.Errorfでエラーメッセージを出力
t.Errorf("Add(2, 3) = %d; want %d", got, want)
}
}
このテストコードは、Add(2, 3)を実行し、その結果が5になることを期待しています。もし結果が5でなければ、t.Errorfが呼ばれてテストが失敗したことを知らせてくれます。
ターミナルでgo testコマンドを実行してみましょう。
# テストが成功した場合
$ go test
PASS
ok my-project/math 0.001s
# もしAdd関数が間違っていて、gotが4になった場合
$ go test
--- FAIL: TestAdd (0.00s)
math_test.go:10: Add(2, 3) = 4; want 5
FAIL
FAIL my-project/math 0.001s
このように、Goのテストは非常に直感的に書くことができます。
テスト駆動開発(TDD)とは?
テストに慣れてきたら、テスト駆動開発(TDD: Test-Driven Development)という開発手法に挑戦してみるのも良いかもしれません。
これは、通常の「実装→テスト」という順序を逆転させ、「テスト→実装」の順で開発を進める手法です。
TDDは、以下の3つのサイクルを繰り返します。
- Red: まず、失敗するテストを書く。まだ実装が存在しないので、テストは必ず失敗(Red)します。
- Green: このテストをパスさせるための、最小限のコードを実装する。テストが成功(Green)すればOKです。
- Refactor: テストが成功している状態を維持しながら、コードを綺麗にリファクタリング(整理)する。
このサイクルを回すことで、必要十分なコードだけが実装され、かつすべてのコードがテスト可能な状態で設計されるというメリットがあります。
おわりに
この記事では、Goの標準パッケージtestingを使ったユニットテストの書き方を学びました。
_test.goファイルを作り、Testで始まる関数を書くだけですぐにテストできる手軽さは、とてもありがたいです。
テストは何かとハードルを高く構えがちですが、簡単にテストが記述できるのは大きな魅力だなと感じました。
これからの個人開発にも積極的に取り入れてみたいと感じました。
最後までお読みいただき、ありがとうございました!
この「学生ひよこ界隈が送るGo/Javaで実現する「はじめてのバックエンド」Advent Calendar 2025」では、GoやJavaを使い、APIの作り方、データベースとの接続、テストやDockerといった気になったバックエンド技術の基本を振り返った学びを共有しています。
ぜひ他の記事もチェックして、筆者がこのひとりアドカレを完遂することができるか、確認してみてください(^^)
学生ひよこ界隈が送るGo/Javaで実現する「はじめてのバックエンド」Advent Calendar 2025
それでは、明日の「学生ひよこ界隈が送るGo/Javaで実現する「はじめてのバックエンド」Advent Calendar 2025」の記事もお楽しみに!
参考文献