GitHubのイシューを読めばそれで終わるんですが。
test-unitってアンドキュメンテドな便利機能が色々あるので日本語で残しておこうと思いました。
こんなクラスの実装があるとします。
my_book.rb
class MyBook
class << self
def from_epub(epub)
# ...
self.new
end
def from_kindle_format(mobi)
# ...
self.new
end
def from_pdf(pdf)
# ...
self.new
end
end
attr_reader :author, :title
end
これをテストするのにこんなの書いたりします。
test_my_book_redundant.rb
require 'test/unit'
require 'my_book'
class TestMyBook < Test::Unit::TestCase
def setup
@author = "It's me"
@title = 'My Special Book'
end
class TestEPUB < self
def setup
super
@book = MyBook.from_epub('path/to/book.epub')
end
def test_author
assert_equal @author, @book.author
end
def test_title
assert_equal @title, @book.title
end
end
class TestKindleFormat < self
def setup
super
@book = MyBook.from_kindle_format('path/to/book.mobi')
end
def test_author
assert_equal @author, @book.author
end
def test_title
assert_equal @title, @book.title
end
end
class TestPDF < self
def setup
super
@book = MyBook.from_pdf('path/to/book.pdf')
end
def test_author
assert_equal @author, @book.author
end
def test_title
assert_equal @title, @book.title
end
end
end
$ ruby -I. test_my_book_redundant.rb
...
Finished in 0.019281834 seconds.
6 tests, 6 assertions, 6 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
0% passed
311.17 tests/s, 311.17 assertions/s
(今実装がないのでコケるのはご愛嬌)
#test_author
と#test_title
の重複が明らかに臭いですね。
重複を取り除くのに、RSpecだとshared_examplesを使うところですが、test-unitではRubyの標準のモジュールを使います。
test_my_book_shared
require 'test/unit'
require 'my_book'
module TestAttributes
def test_author
assert_equal @author, @book.author
end
def test_title
assert_equal @title, @book.title
end
end
class TestMyBook < Test::Unit::TestCase
def setup
@author = "It's me"
@title = 'My Special Book'
end
class TestEPUB < self
include TestAttributes
def setup
super
@book = MyBook.from_epub('path/to/book.epub')
end
end
class TestKindleFormat < self
include TestAttributes
def setup
super
@book = MyBook.from_kindle_format('path/to/book.mobi')
end
end
class TestPDF < self
include TestAttributes
def setup
super
@book = MyBook.from_pdf('path/to/book.pdf')
end
end
end
$ ruby -I. test_my_book_shared.rb
...
Finished in 0.017621966 seconds.
6 tests, 6 assertions, 6 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
0% passed
340.48 tests/s, 340.48 assertions/s
「6 tests, 6 assertions」、つまり、一つのモジュールにテストをまとめても、それをinclude
しているテストクラス三つ分、ちゃんと実行されています。