これからいくつかテストの定石を紹介します。一番最初は、ログ文字列(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が呼ばれたところまで確かめられますね。このようにテスト対象のオブジェクトにログを持たせて、テストからテスト対象のログをチェックするのが普通のやり方です。