Ruby test-unit でテストを書いてみる(FizzBuzz)

FizzBuzz 問題を題材に TDD(テスト駆動開発)を学んだので、実際に動画の流れに沿って、Ruby でテストを書いてみた。

(動画はこちら:TDD Boot Camp 2020 Online #1 基調講演/ライブコーディング - YouTube

Ruby 標準のテスティングフレームワークである test-unit を初めて使った。

FizzBuzz 問題

1から100までの数字を順番に出力するプログラムです。ただし、3の倍数のときは数字の代わりに「Fizz」、5の倍数のときは「Buzz」、3と5両方の倍数のときは「FizzBuzz」と出力してください。

fizzbuzz_test.rb

require "test/unit"
require "./fizzbuzz"

class FizzbuzzTest < Test::Unit::TestCase
  def setup
    @fb = Fizzbuzz.new
  end

  def test_1を渡すと文字列1を返す
    assert_equal "1", @fb.fizzbuzz(1)
  end

  def test_3を渡すと文字列Fizzを返す
    assert_equal "Fizz", @fb.fizzbuzz(3)
  end

  def test_5を渡すと文字列Buzzを返す
    assert_equal "Buzz", @fb.fizzbuzz(5)
  end

  def test_15を渡すと文字列FizzBuzzを返す
    assert_equal "FizzBuzz", @fb.fizzbuzz(15)
  end
end

(動画のやり方に従ってテスト名を日本語にしている)

test-unit の使い方はこちらの記事を参考にした。

qiita.com

まず、"test/unit"を require する。

テストクラスは、Test::Unit::TestCaseを継承する。

アサーションの書き方は Minitest とほとんど変わらない。

Module: Test::Unit::Assertions — test-unit - test-unit

assert_equal 期待値, 実際の値 で検証。期待値 == 実際の値であれば、テストが通る。

assert_equalの反対は、refute_equal。たとえば以下のようになる。

  def test_15を渡すと文字列Buzzを返さない
    refute_equal "Buzz", @fb.fizzbuzz(15)
  end

FizzBuzz 本体のコードは以下のようになった。

fizzbuzz.rb

class Fizzbuzz
  def fizzbuzz(num)
    if num % 15 == 0
      "FizzBuzz"
    elsif num % 3 == 0
      "Fizz"
    elsif num % 5 == 0
      "Buzz"
    else
      num.to_s
    end
  end
end

以下のように、テストを実行するとちゃんと通る。

$ ruby fizzbuzz_test.rb 
Loaded suite fizzbuzz_test
Started
....
Finished in 0.000509 seconds.
--------------------------------------------------------------------------------
4 tests, 4 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
--------------------------------------------------------------------------------
7858.55 tests/s, 7858.55 assertions/s

個人的には、Minitest よりカラフルになるところが好みだった。ここでは表現できなくて残念(ラインが全部 Green や Red になる)。

ただ、test-unit を使っている人はそれほど多くはなさそう。