LoginSignup
1
1

More than 3 years have passed since last update.

【Go】【Ginkgo】FizzBuzzをGinkgoでテストしてみる

Last updated at Posted at 2020-08-11

はじめに

最近Goの勉強をしてて、簡単なWebサーバーを作ってみたり、コマンドラインで動作するツールを作ったり、、、としているんですけど、そういやテスト書いたことないなあと思って今回の記事を書くことにしました!

Ginkgoを選んだ理由

Ginkgoの書き方がなんとなくrspecに似てるからです。
昔Railsを書いていたことがあるので、簡単に書けるんじゃないかな〜っていう安易な発想です。

テストの準備

Ginkgoをインストールします。

go get github.com/onsi/ginkgo/ginkgo
go get github.com/onsi/gomega/...

ディレクトリとテスト用ファイルを作成します。

mkdir fizzbuzz
cd fizzbuzz
ginkgo bootstrap
ginkgo generate fizzbuzz

実装

今回作成するテストケースは以下の通りとします。よく見るFizzBuzzですね。

  • 数値が3の倍数であれば「Fizz」を返す
  • 数値が5の倍数であれば「Buzz」を返す
  • 数値が3の倍数かつ5の倍数であれば「FizzBuzz」を返す
  • 数値が3の倍数でも5の倍数でもなければ、そのまま文字列に変換して返す

早速ですが実装は以下の通りです。
シンプルなFizzBuzzなので特に何もないですね。

fizzbuzz.go
package fizzbuzz

import (
    "strconv"
)

func Convert(i int) (string, error) {
    if i%15 == 0 {
        return "FizzBuzz", nil
    }
    if i%3 == 0 {
        return "Fizz", nil
    }
    if i%5 == 0 {
        return "Buzz", nil
    }
    return strconv.Itoa(i), nil
}

こちらがテストコードになります。
こういう書き方がいいのかダメなのかもわかってないですけど、それっぽく書いてみました。

fizzbuzz_test.go
package fizzbuzz

import (
    . "github.com/onsi/ginkgo"
    . "github.com/onsi/gomega"

    "strconv"
)

var _ = Describe("fizzbuzz", func() {

    Describe("Convertメソッド", func() {

        Context("引数が3の倍数でも5の倍数でもない場合", func() {
            data := []int{1, 4, 8, 11, 13, 14, 17, 19, 23, 26}
            for idx := range data {
                // rangeの第2引数はポインタなのでそのままアサーションに使用すると正しくテストが実行されない
                v := data[idx]
                r, err := Convert(v)
                It("そのまま文字列変換した値を返すこと", func() {
                    Expect(r).To(Equal(strconv.Itoa(v)))
                })
                It("エラーがnilであること", func() {
                    Expect(err).To(BeNil())
                })
            }
        })

        Context("引数が3の倍数", func() {
            data := []int{3, 6, 9, 12, 18, 21, 24, 27, 33, 36}
            for idx := range data {
                // rangeの第2引数はポインタなのでそのままアサーションに使用すると正しくテストが実行されない
                v := data[idx]
                r, err := Convert(v)
                It("Fizzという文字列を返すこと", func() {
                    Expect(r).To(Equal("Fizz"))
                })
                It("エラーがnilであること", func() {
                    Expect(err).To(BeNil())
                })
            }
        })

        Context("引数が5の倍数", func() {
            data := []int{5, 10, 20, 25, 35, 40, 50, 55, 65, 70}
            for idx := range data {
                // rangeの第2引数はポインタなのでそのままアサーションに使用すると正しくテストが実行されない
                v := data[idx]
                r, err := Convert(v)
                It("Buzzという文字列を返すこと", func() {
                    Expect(r).To(Equal("Buzz"))
                })
                It("エラーがnilであること", func() {
                    Expect(err).To(BeNil())
                })
            }
        })

        Context("引数が3の倍数かつ5の倍数", func() {
            data := []int{15, 30, 45, 60, 75, 90, 105, 120, 135, 150}
            for idx := range data {
                // rangeの第2引数はポインタなのでそのままアサーションに使用すると正しくテストが実行されない
                v := data[idx]
                r, err := Convert(v)
                It("FizzBuzzという文字列を返すこと", func() {
                    Expect(r).To(Equal("FizzBuzz"))
                })
                It("エラーがnilであること", func() {
                    Expect(err).To(BeNil())
                })
            }
        })

    })

})

おわりに

今回は、Goで簡単なテストを書いてみました。
標準のテストを書いたことがない状態で、いきなりGinkgoを書いていいものか悩みましたが、まあよしとしましょう。
何かの参考になれば幸いです。

1
1
0

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