| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- unit IdTest;
- {
- minimal/example test runner for .net/mono
- feel free to improve this code
- for example, better format for the output
- }
- interface
- uses
- System.Reflection,
- System.Threading,
- IdObjs,
- IdBaseComponent;
- type
- TIdTest = class;
- TIdTestClass = class of TIdTest;
- TOutputStringProcedure = procedure(const AString: string);
- TIdTest = class(TIdBaseComponent)
- private
- FOnOutputString: TOutputStringProcedure;
- protected
- procedure SetUp; virtual;
- procedure TearDown; virtual;
- public
- procedure OutputLn(const ALine: string);
- class procedure RegisterTest(const aClass:TIdTestClass);
- class function TestList:TIdList;
- property OnOutputString: TOutputStringProcedure read FOnOutputString write FOnOutputString;
- end;
- TIdBasicRunner = class(TObject)
- private
- FLockObj: &Object;
- FDebugInfo: Boolean;
- procedure WriteLn(const aStr:string);
- procedure WriteOutput(const AString: string);
- procedure RecordPass(const aTest:TIdTest;const aMethod:string);
- procedure RecordFail(const aTest:TIdTest;const aMethod:string;const e:exception);
- procedure WriteString(const AString: string);
- public
- PassCount:integer;
- FailCount:integer;
- constructor Create;
- procedure Execute;
- end;
- implementation
- var
- // this should really be a classlist
- FRegisterList:TIdList;
- class procedure TIdTest.RegisterTest(const aClass: TIdTestClass);
- begin
- TestList.Add(aClass.Create);
- end;
- class function TIdTest.TestList: TIdList;
- begin
- if FRegisterList=nil then
- begin
- FRegisterList:=TIdList.Create;
- end;
- Result:=FRegisterList;
- end;
- procedure TIdTest.OutputLn(const ALine: string);
- begin
- if Assigned(FOnOutputString) then
- begin
- FOnOutputString(ALine + Environment.NewLine);
- end;
- end;
- { TIdBasicRunner }
- constructor TIdBasicRunner.Create;
- function ShouldOutputDebuggingInfo: Boolean;
- var
- I: Integer;
- begin
- Result := False;
- for I := 0 to High(Environment.GetCommandLineArgs) do
- Result := Result or (Environment.GetCommandLineArgs[i].ToLower = '/debug');
- end;
- begin
- inherited;
- FLockObj := &Object.Create;
- FDebugInfo := ShouldOutputDebuggingInfo;
- end;
- procedure TIdBasicRunner.WriteOutput(const AString: string);
- begin
- WriteString('INFO: ' + AString);
- end;
- procedure TIdBasicRunner.WriteString(const AString: string);
- begin
- if FDebugInfo then
- begin
- Monitor.Enter(FLockObj);
- try
- Console.Write(' ' + AString);
- finally
- Monitor.Exit(FLockObj);
- end;
- end;
- end;
- procedure TIdBasicRunner.Execute;
- var
- aMethods:array of methodinfo;
- aMethodCount:integer;
- aTestCount:integer;
- aMethod:methodinfo;
- aTest:TIdTest;
- begin
- PassCount:=0;
- FailCount:=0;
- for aTestCount:=0 to TIdTest.TestList.Count-1 do
- begin
- aTest:=TIdTest.TestList[aTestCount] as TIdTest; //aClass.Create();
- aTest.OnOutputString := WriteOutput;
- aMethods:=aTest.GetType.GetMethods;
- WriteLn('Test:'+aTest.classname);
- for aMethodCount:=low(aMethods) to high(aMethods) do
- begin
- aMethod:=aMethods[aMethodCount];
- if not aMethod.Name.StartsWith('Test') then continue;
- try
- WriteLn(' ' + aMethod.Name);
- aTest.SetUp;
- try
- aMethod.Invoke(aTest,[]);
- finally
- aTest.TearDown;
- end;
- //commented out, makes easier to see the fails
- RecordPass(aTest,aMethod.name);
- except
- on e:exception do
- begin
- RecordFail(aTest,aMethod.name,e);
- end;
- end;
- end; //methods
- end; //tests
- WriteLn('Results: Pass='+PassCount.ToString+', Fail='+FailCount.ToString);
- end;
- procedure TIdBasicRunner.RecordPass(const aTest: TIdTest;
- const aMethod: string);
- begin
- inc(PassCount);
- WriteString('Passed' + Environment.NewLine);
- end;
- procedure TIdBasicRunner.RecordFail(const aTest: TIdTest; const aMethod: string;
- const e: exception);
- var
- ie:TargetInvocationException;
- begin
- inc(failcount);
- WriteLn(' Fail:');
- //this exception is raised as we are calling methods using reflection
- if e is TargetInvocationException then
- begin
- ie:=e as TargetInvocationException;
- WriteLn(' '+ie.InnerException.classname+':'+ie.InnerException.Message);
- WriteLn(ie.InnerException.StackTrace);
- end else begin
- WriteLn(' '+e.classname);
- end;
- end;
- procedure TIdBasicRunner.WriteLn(const aStr: string);
- begin
- Monitor.Enter(FLockObj);
- try
- Console.WriteLine(AStr);
- finally
- Monitor.Exit(FLockObj);
- end;
- end;
- procedure TIdTest.SetUp;
- begin
- end;
- procedure TIdTest.TearDown;
- begin
- end;
- end.
|