yikegaya’s blog

仕事関連(Webエンジニア)と資産運用について書いてます

Ruby→Goの移行PJでginkgoとgomegaを使ってるとテストコード移行作業がやりやすい

今でRubyAPIやjobをGoに移行する仕事をしていますがginkgo使うとrubyrspecで書かれたテスト移植しやすいなー。と感じます。

ginkgoについて

Goのテストフレームワークです。

Goの本やブログ読んでてもあんまり情報なく自分も職場のチームリーダに紹介してもらうまで知らなかったんですがgithubのstarも2023年10月時点で7.5kついてます。

github.com

Goには標準でテストコードを書くための機能が用意されてるのでそれのみを使って実装していくプロジェクトが多いと思うんですがそれだけだとrspecでよくやるbefore_each、describe、context句などを使った構造化がやりにくいです。

ginkgoを使うと構造化ができて一緒に使うことが推奨されてるgomegaというマッチャも合わせて使うとrspecと似た雰囲気のテストコードが書きやすい。

サンプル

ChatGPTで作った適当なrspecとginkgoの比較サンプル

# spec/calculator_spec.rb

require 'rspec'
require_relative 'calculator'

RSpec.describe Calculator do
  before(:each) do
    @calculator = Calculator.new
  end

  describe '#add' do
    context 'when adding two positive numbers' do
      it 'returns the sum' do
        result = @calculator.add(3, 4)
        expect(result).to eq(7)
      end
    end

    context 'when adding a positive number and a negative number' do
      it 'returns the correct result' do
        result = @calculator.add(3, -2)
        expect(result).to eq(1)
      end
    end
  end

  describe '#subtract' do
    context 'when subtracting two positive numbers' do
      it 'returns the difference' do
        result = @calculator.subtract(7, 3)
        expect(result).to eq(4)
      end
    end

    context 'when subtracting a negative number from a positive number' do
      it 'returns the correct result' do
        result = @calculator.subtract(5, -2)
        expect(result).to eq(7)
      end
    end
  end
end
// calculator_test.go

package main_test

import (
    . "github.com/onsi/ginkgo"
    . "github.com/onsi/gomega"
    . "path/to/your/package" // パッケージの実際のパスに変更してください
)

var _ = Describe("Calculator", func() {
    var (
        calc *Calculator
    )

    BeforeEach(func() {
        calc = &Calculator{}
    })

    Describe("#Add", func() {
        Context("when adding two positive numbers", func() {
            It("returns the sum", func() {
                result := calc.Add(3, 4)
                Expect(result).To(Equal(7))
            })
        })

        Context("when adding a positive number and a negative number", func() {
            It("returns the correct result", func() {
                result := calc.Add(3, -2)
                Expect(result).To(Equal(1))
            })
        })
    })

    Describe("#Subtract", func() {
        Context("when subtracting two positive numbers", func() {
            It("returns the difference", func() {
                result := calc.Subtract(7, 3)
                Expect(result).To(Equal(4))
            })
        })

        Context("when subtracting a negative number from a positive number", func() {
            It("returns the correct result", func() {
                result := calc.Subtract(5, -2)
                Expect(result).To(Equal(7))
            })
        })
    })
})