テスト — RSpecなしで生きる方法
Goのテストは標準ライブラリに組み込まれている。gem install不要。
Rubyのテスト環境を構築した人は分かる。RSpecインストール、spec_helper.rb設定、FactoryBotセットアップ、DatabaseCleaner追加、shoulda-matchers接続...最初のテスト1行を実行するまで30分はかかる。
Goは?_test.goファイルを作ってgo testを実行すれば終わり。
ファイル名がルール
user.goのテストはuser_test.goに書く。_test.goで終わるファイルはgo test実行時のみコンパイルされる。Rubyのspec/ディレクトリ分離の代わりに、ソースファイルの隣にテストファイルを置く。
RSpecのdescribe/it vs GoのTest関数
Ruby:
RSpec.describe User do
it "has a name" do
expect(user.name).to eq("kim")
end
end
Go:
func TestUserName(t *testing.T) {
user := User{Name: "kim"}
if user.Name != "kim" {
t.Errorf("expected kim, got %s", user.Name)
}
}
RSpecのDSLに慣れているとGoのテストが原始的に見えるかもしれない。expect/toのようなマッチャーがない。if文で直接比較。Go の「標準ライブラリで十分」哲学。
テーブル駆動テスト — Goの核心パターン
Goでは複数ケースをテストする時、structスライスでテストケースを定義:
tests := []struct{ input int; want int }{
{1, 2}, {2, 4}, {3, 6},
}
RSpecのshared_examplesと似た役割。
go test -v, -run, -cover
go test -v — 詳細出力(RSpec --format documentationのようなもの)
go test -run TestUser — 特定テストのみ実行(rspec spec/models/user_spec.rbのようなもの)
go test -cover — カバレッジ確認(simplecovのようなもの)
別途gemインストールなしで全て内蔵。
RubyからGoへ
Ruby: spec/ディレクトリ + RSpec gem → Go: _test.goファイル(内蔵、gem不要)
Ruby: describe/it/expect → Go: func TestXxx(t *testing.T) + if + t.Errorf
Ruby: shared_examples → Go: テーブル駆動テスト(structスライス)
Ruby: rspec --format doc → Go: go test -v / -run / -cover(全て内蔵)
メリット
- ✓ セットアップゼロ — gem install、spec_helper、.rspecファイル全て不要
- ✓ go test -coverが内蔵 — SimpleCovなしでカバレッジ確認可能
デメリット
- ✗ RSpecのexpect().to eq()のような可読性の高いマッチャーがない — if文が冗長
- ✗ FactoryBotのようなテストデータ生成ツールが標準にない — 自前で実装必要