前に使ってたバージョンがDelphi2009なのでTRttiContextを使うのはこれが初めて。
TRttiContextを使ってメソッド名の取得や取得したメソッドの実行ができるので、xUnit(DUnitとか)なテストフレームワークを作ってみました。
"Test"という名前で始まるメソッドを探して実行する部分のコードはこんな感じ。細かい部分は省略してます。
procedure TTestCase.Run(TestResultList: TObjectList<TTestResult>); var RttiContext: TRttiContext; RttiType: TRttiType; Method: TRttiMethod; begin RttiContext := TRttiContext.Create; try RttiType := RttiContext.GetType(ClassType); for Method in RttiType.GetMethods do begin if LeftStr(Method.Name, 4) = 'Test' then begin try try SetUp; Method.Invoke(Self, []); // テストメソッドを呼び出し except on E: EAssertionError do // テスト結果を記録(省略) on E: ESkipTest do // テスト結果を記録(省略) on E: Exception do // テスト結果を記録(省略) end; finally TearDown; end; end; end; finally RttiContext.Free; end; end;
DUnitがあるので別にこれを使う必要はないですが、練習で作ってみました。
TStopWatchも使っているのですが、便利ですね。
まだアサーションのメソッドは少ししか作ってないです。
実行結果
Exampleの下のソースコードをmakeコマンドでビルドして実行するとこんな感じ。
Pythonのunittestモジュールの出力を参考に作ってみました。
C:\Users\tokibito\_bitbucket\delphi-unittest\Example>TestProject.exe ..FS.. ====================================================================== FAIL: TestAddFail (TMyUnit1Test) ---------------------------------------------------------------------- EAssertionError: 30 != 40 ---------------------------------------------------------------------- Ran 6 tests in 0.501s FAILED (failures=1, skipped=1)
ビルドしたTestProjectはMacOSXでも動作しました。