🧪

テスト — 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へ

1

Ruby: spec/ディレクトリ + RSpec gem → Go: _test.goファイル(内蔵、gem不要)

2

Ruby: describe/it/expect → Go: func TestXxx(t *testing.T) + if + t.Errorf

3

Ruby: shared_examples → Go: テーブル駆動テスト(structスライス)

4

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のようなテストデータ生成ツールが標準にない — 自前で実装必要

ユースケース

RSpecなしでも十分なテストを書きたい時(Go標準testingパッケージ)

参考資料