これからいくつかテストの定石を紹介します。一番最初は、ログ文字列(Log String)です。
この定石は複雑な呼び出しシーケンスがあるときに、ちゃんと意図したとおりにメソッドが呼び出されたかどうか確認するためのものです。「論よりコード」とも言いますので、まず「1.座標の足し算」の最後で、initialize()、setup(),teardown()の順番を確認するために書いたコードをこの定石を使って書き直してみましょう。
---PointTest.rb----------------------
class PointTest < Test::Unit::TestCase
def initialize(method)
super
@log = "initialize() "
end
def setup()
@log.concat("setup() ")
@point = Point.new(3, 4)
end
def teardown()
@log.concat("teardown() ")
end
def testGetXY()
assert_equal("initialize() setup() ", @log)
assert_equal(3, @point.getX())
assert_equal(4, @point.getY())
end
def testPlus()
assert_equal("initialize() setup() ", @log)
assert_equal(Point.new(5, 5), @point.plus(Point.new(2, 1)))
end
def testMinus()
assert_equal("initialize() setup() ", @log)
assert_equal(Point.new(1, 3), @point.minus(Point.new(2, 1)))
end
def testPoduct()
assert_equal("initialize() setup() ", @log)
assert_equal(Point.new(6, 8), @point.product(2))
end
def testDevide()
assert_equal("initialize() setup() ", @log)
assert_equal(Point.new(1, 2), @point.devide(2))
end
end
--------------------------------
initialize()でメンバー変数@logを"initialize() "で初期化し、setup()で@logに"setup() "を付け加えています。したがって、意図した順番でinitialize()とsetup()が呼ばれれば、各テストメソッドを実行するときには@logは"initialize() setup() "になっているはずです。
テストを動かします。
|
|
>$ ruby PointTest.rb Loaded suite PointTest Started ..... Finished in 0.0 seconds. 5 tests, 11 assertions, 0 failures, 0 errors
意図した順番でinitialize()とsetup()が呼ばれたことが、出力結果を注意してみなくてもわかります。
たったこれだけのことですが、複数のオブジェクトが複雑に相互作用しているときには重宝するテスト方法です。
上記の例では、PointTestのなかでTestCaseの使われ方テストしていましたが、ちゃんとTestCaseの使われ方のテストを分離して書いて見ましょう。
---TestCaseTest.rb----------------------
require 'test/unit'
require 'test/unit/ui/console/testrunner'
class TestCaseTest < Test::Unit::TestCase
def initialize(method)
super
@log = "initialize() "
end
def setup()
@log.concat("setup() ")
end
def teardown()
@log.concat("teardown() ")
end
def testA()
@log.concat("testA() ")
end
def getLog()
return @log
end
end
class TestCaseTestTest < Test::Unit::TestCase
def setup()
#TestCaseTestのtestAをテストするインスタンスを作ります。
@test = TestCaseTest.new("testA")
end
def testTestCase()
#テストをrunさせます。
Test::Unit::UI::Console::TestRunner.run(@test)
#ログを確認します。
assert_equal("initialize() setup() testA() teardown() ", @test.getLog())
end
end
--------------------------------
TestCaseTestでlogを書くようにして、TestCaseTestTestからTestCaseTestのインスタンスを作ってrunさせ、TestCaseTestのログを確かめています。これならちゃんとteardownが呼ばれたところまで確かめられますね。このようにテスト対象のオブジェクトにログを持たせて、テストからテスト対象のログをチェックするのが普通のやり方です。