テストケースの書き方OSLの開発はテストを書きながら行う。テストをきちんと書くことには、以下のようなメリットがある:
手順
実例「空成り」を判定する bool isKaranari(Move); という関数を作りたくなったとする。空成りとは将棋用語で
まずテストファイルを作るosl/test/test-template.t.cc をコピーして karanari.t.cc を作る cd osl/test cp test-template.t.cc karanari.t.cc template を karanari に置換する。 ESC % Template RET Karanari
テストを書くまずは駒を取るかどうかに注目したテストを書いてみる。 簡単なテストから始めるのがミソ。いきなり全ての場合を尽くしたテストを書くのは大抵は無謀。 void testKaranari() { const Move m2823RY = newMove(newMove(newPosition(2,8),newPosition(2,3),PROOK,PTYPE_EMPTY,true,BLACK); // 23飛車成 (駒をとらない) CPPUNIT_ASSERT(isKaranari(m2823RY)); } void testNotKaranari() { const Move m2823RY_PAWN = newMove(newMove(newPosition(2,8),newPosition(2,3),PROOK,PAWN,true,BLACK); // 23飛車成 (歩を取る) CPPUNIT_ASSERT(! isKaranari(m2823RY_PAWN)); } 以上の二つのメソッドをpublic:以下の部分に挿入する。
また、クラスの先頭の部分に、メソッド名を記述する。 CPPUNIT_TEST_SUITE(TemplateTest); CPPUNIT_TEST(testKaranari); CPPUNIT_TEST(testNotKaranari); CPPUNIT_TEST_SUITE_END(); ここに書かないと、テストは実行されないので注意。 コンパイルするmake karanari.t この時点では、isKaranari() 関数ができていないので、当然コンパイルエラーになるはずである。 ダミー関数を書いてコンパイルを通すいよいよ関数を書き始めるがまだ本物を作らない。 まずは必ず真を返す関数を作る。 karanari.h に /** 空成りを判定する */ inline bool isKaranari(Move) { /* fake version */ return true; } と定義して、 make karanari.t とする。今度はめでたくコンパイルが通るはずである。
続いてテストを通すことに目を向ける。 testKaranari()はパスするが、testNotKaranari?() は失敗する。 実は失敗しないと問題である。なぜならテストが間違っていたことになるから。 初めから正しい関数を書かなかった理由はテストをテストするためでもある。 続いて、これを改良してゆく。 関数の改良空成りの条件の一部の「駒を取らない」部分を書いてみる。 inline bool isKaranari(Move m) { /* fake version */ return getCapturePtype(m) != PTYPE_EMPTY; } 今度はめでたくテストが通る。 しかし、まだ「成る」部分の判定が入っていないため、テストは通ったものの完成したわけではない。そこで... テストの改良「駒を取るが成らない」指手に付いてのテストを testNotKaranari?() に追加する。 const Move m2823HI_PAWN = newMove(newMove(newPosition(2,8),newPosition(2,3),ROOK,PAWN,false,BLACK); // 23飛車不成 (歩を取る) CPPUNIT_ASSERT(! isKaranari(m2823HI_PAWN)); コンパイルしてテストに失敗することを確認する。 失敗したということは「テストが正しく書けた」ということである。 関数の改良「成る」部分の条件を追加する。 inline bool isKaranari(Move m) { return (getCapturePtype(m) != PTYPE_EMPTY) && getPromoteMask(m); } テスト新しく書いたテストをパスできることを確認する。このように
テストの自動化Makefile に登録することで testAll を実行した時に、このテストも実行されるようにする。 BOARD_OBJS = ... karanari.t.o 登録する場所は4種類あるが、この場合は BOARD_OBJS の末尾に追加しておく。 参考文献 |