TextTestRunner.pas
上传用户:yjb1804
上传日期:2021-01-30
资源大小:3105k
文件大小:10k
源码类别:

Email服务器

开发平台:

Delphi

  1. { $Id: TextTestRunner.pas,v 1.29 2006/07/19 02:45:55 judc Exp $ }
  2. {: DUnit: An XTreme testing framework for Delphi programs.
  3.    @author  The DUnit Group.
  4.    @version $Revision: 1.29 $
  5. }
  6. (*
  7.  * The contents of this file are subject to the Mozilla Public
  8.  * License Version 1.1 (the "License"); you may not use this file
  9.  * except in compliance with the License. You may obtain a copy of
  10.  * the License at http://www.mozilla.org/MPL/
  11.  *
  12.  * Software distributed under the License is distributed on an "AS
  13.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  14.  * implied. See the License for the specific language governing
  15.  * rights and limitations under the License.
  16.  *
  17.  * The Original Code is DUnit.
  18.  *
  19.  * The Initial Developers of the Original Code are Kent Beck, Erich Gamma,
  20.  * and Juancarlo A馿z.
  21.  * Portions created The Initial Developers are Copyright (C) 1999-2000.
  22.  * Portions created by The DUnit Group are Copyright (C) 2000-2004.
  23.  * All rights reserved.
  24.  *
  25.  * Contributor(s):
  26.  * Kent Beck <kentbeck@csi.com>
  27.  * Erich Gamma <Erich_Gamma@oti.com>
  28.  * Juanco A馿z <juanco@users.sourceforge.net>
  29.  * Chris Morris <chrismo@users.sourceforge.net>
  30.  * Jeff Moore <JeffMoore@users.sourceforge.net>
  31.  * Kris Golko <neuromancer@users.sourceforge.net>
  32.  * The DUnit group at SourceForge <http://dunit.sourceforge.net>
  33.  *
  34.  *)
  35. unit TextTestRunner;
  36. interface
  37. uses
  38.   Classes,
  39.   TestFramework;
  40. const
  41.   rcs_id :string = '#(@)$Id: TextTestRunner.pas,v 1.29 2006/07/19 02:45:55 judc Exp $';
  42. type
  43.   TRunnerExitBehavior = (
  44.     rxbContinue,
  45.     rxbPause,
  46.     rxbHaltOnFailures
  47.     );
  48.   TTextTestListener = class(TInterfacedObject, ITestListener, ITestListenerX)
  49.   protected
  50.     startTime: TDateTime;
  51.     endTime: TDateTime;
  52.     runTime: TDateTime;
  53.   public
  54.     // implement the ITestListener interface
  55.     procedure AddSuccess(test: ITest); virtual;
  56.     procedure AddError(error: TTestFailure); virtual;
  57.     procedure AddFailure(failure: TTestFailure); virtual;
  58.     function  ShouldRunTest(test :ITest):boolean; virtual;
  59.     procedure StartSuite(suite: ITest); virtual;
  60.     procedure EndSuite(suite: ITest); virtual;
  61.     procedure StartTest(test: ITest); virtual;
  62.     procedure EndTest(test: ITest); virtual;
  63.     procedure TestingStarts; virtual;
  64.     procedure TestingEnds(testResult: TTestResult); virtual;
  65.     procedure Status(test :ITest; const Msg :string);
  66.     procedure Warning(test :ITest; const Msg :string);
  67.     function  Report(r: TTestResult): string;
  68.     class function RunTest(suite: ITest; exitBehavior: TRunnerExitBehavior = rxbContinue): TTestResult; overload;
  69.     class function RunRegisteredTests(exitBehavior: TRunnerExitBehavior = rxbContinue): TTestResult;
  70.   protected
  71.     function  PrintErrors(r: TTestResult): string; virtual;
  72.     function  PrintFailures(r: TTestResult): string; virtual;
  73.     function  PrintHeader(r: TTestResult): string; virtual;
  74.     function  PrintFailureItems(r :TTestResult): string; virtual;
  75.     function  PrintErrorItems(r :TTestResult): string; virtual;
  76.     function  TruncateString(s: string; len: integer): string; virtual;
  77.   end;
  78.   {: This type defines what the RunTest and RunRegisteredTests methods will do when
  79.      testing has ended.
  80.      @enum rxbContinue Just return the TestResult.
  81.      @enum rxbPause    Pause with a ReadLn before returnng the TestResult.
  82.      @enum rxbHaltOnFailures   Halt the program if errors or failures occurred, setting
  83.                                the program exit code to FailureCount+ErrorCount;
  84.                                behave like rxbContinue if all tests suceeded.
  85.      @seeAlso <See Unit="TextTestRunner" Routine="RunTest">
  86.      @seeAlso <See Unit="TextTestRunner" Routine="RunRegisteredTests">
  87.      }
  88. {: Run the given test suite
  89. }
  90. function RunTest(suite: ITest; exitBehavior: TRunnerExitBehavior = rxbContinue): TTestResult; overload;
  91. function RunRegisteredTests(exitBehavior: TRunnerExitBehavior = rxbContinue): TTestResult; overload;
  92. implementation
  93. uses
  94.   SysUtils;
  95. const
  96.   CRLF = #13#10;
  97. { TTExtTestListener }
  98. procedure TTextTestListener.AddSuccess(test: ITest);
  99. begin
  100. // No display for successes
  101. end;
  102. procedure TTextTestListener.AddError(error: TTestFailure);
  103. begin
  104.   write('E');
  105. end;
  106. procedure TTextTestListener.AddFailure(failure: TTestFailure);
  107. begin
  108.   write('F');
  109. end;
  110. {:
  111.    Prints failures to the standard output
  112.  }
  113. function TTextTestListener.Report(r: TTestResult): string;
  114. begin
  115.   result := PrintHeader(r) +
  116.             PrintErrors(r) +
  117.             PrintFailures(r);
  118. end;
  119. {:
  120.    Prints the errors to the standard output
  121.  }
  122. function TTextTestListener.PrintErrors(r: TTestResult): string;
  123. begin
  124.   result := '';
  125.   if (r.errorCount <> 0) then begin
  126.     if (r.errorCount = 1) then
  127.       result := result + format('There was %d error:', [r.errorCount]) + CRLF
  128.     else
  129.       result := result + format('There were %d errors:', [r.errorCount]) + CRLF;
  130.     result := result + PrintErrorItems(r);
  131.     result := result + CRLF
  132.   end
  133. end;
  134. function TTextTestListener.PrintFailureItems(r :TTestResult): string;
  135. var
  136.   i: Integer;
  137.   failure: TTestFailure;
  138. begin
  139.   result := '';
  140.   for i := 0 to r.FailureCount-1 do begin
  141.     failure := r.Failures[i];
  142.     result := result + format('%3d) %s: %s'#13#10'     at %s'#13#10'      "%s"',
  143.                                [
  144.                                i+1,
  145.                                failure.failedTest.name,
  146.                                failure.thrownExceptionName,
  147.                                failure.LocationInfo,
  148.                                failure.thrownExceptionMessage
  149.                                ]) + CRLF;
  150.   end;
  151. end;
  152. function TTextTestListener.PrintErrorItems(r :TTestResult): string;
  153. var
  154.   i: Integer;
  155.   failure: TTestFailure;
  156. begin
  157.   result := '';
  158.   for i := 0 to r.ErrorCount-1 do begin
  159.     failure := r.Errors[i];
  160.     result := result + format('%3d) %s: %s'#13#10'     at %s'#13#10'      "%s"',
  161.                                [
  162.                                i+1,
  163.                                failure.failedTest.name,
  164.                                failure.thrownExceptionName,
  165.                                failure.LocationInfo,
  166.                                failure.thrownExceptionMessage
  167.                                ]) + CRLF;
  168.   end;
  169. end;
  170. {:
  171.    Prints failures to the standard output
  172.  }
  173. function TTextTestListener.PrintFailures(r: TTestResult): string;
  174. begin
  175.   result := '';
  176.   if (r.failureCount <> 0) then begin
  177.     if (r.failureCount = 1) then
  178.       result := result + format('There was %d failure:', [r.failureCount]) + CRLF
  179.     else
  180.       result := result + format('There were %d failures:', [r.failureCount]) + CRLF;
  181.     result := result + PrintFailureItems(r);
  182.     result := result + CRLF
  183.   end
  184. end;
  185. {:
  186.    Prints the header of the Report
  187.  }
  188. function TTextTestListener.PrintHeader(r: TTestResult): string;
  189. begin
  190.   result := '';
  191.   if r.wasSuccessful then
  192.   begin
  193.     result := result + CRLF;
  194.     result := result + format('OK: %d tests'+CRLF, [r.runCount]);
  195.   end
  196.   else
  197.   begin
  198.     result := result + CRLF;
  199.     result := result + 'FAILURES!!!'+CRLF;
  200.     result := result + 'Test Results:'+CRLF;
  201.     result := result + format('Run:      %8d'+CRLF+'Failures: %8d'+CRLF+'Errors:   %8d'+CRLF,
  202.                       [r.runCount, r.failureCount, r.errorCount]
  203.                       );
  204.   end
  205. end;
  206. procedure TTextTestListener.StartTest(test: ITest);
  207. begin
  208.   write('.');
  209. end;
  210. procedure TTextTestListener.EndTest(test: ITest);
  211. begin
  212. end;
  213. function TTextTestListener.TruncateString(s: string; len: integer): string;
  214. begin
  215.   if Length(s) > len then
  216.     result := copy(s, 1, len) + '...'
  217.   else
  218.     result := s
  219. end;
  220. procedure TTextTestListener.TestingStarts;
  221. begin
  222.   writeln;
  223.   writeln('DUnit / Testing');
  224.   startTime := now;
  225. end;
  226. procedure TTextTestListener.TestingEnds(testResult: TTestResult);
  227. var
  228.   h, m, s, l :Word;
  229. begin
  230.   endTime := now;
  231.   runTime := endTime-startTime;
  232.   writeln;
  233.   DecodeTime(runTime, h,  m, s, l);
  234.   writeln(Format('Time: %d:%2.2d:%2.2d.%d', [h, m, s, l]));
  235.   writeln(Report(testResult));
  236.   writeln;
  237. end;
  238. class function TTextTestListener.RunTest(suite: ITest; exitBehavior: TRunnerExitBehavior = rxbContinue): TTestResult;
  239. begin
  240.   Result := TestFramework.RunTest(suite, [TTextTestListener.Create]);
  241.   case exitBehavior of
  242.     rxbPause:
  243.       try
  244.         writeln('Press <RETURN> to continue.');
  245.         readln
  246.       except
  247.       end;
  248.     rxbHaltOnFailures:
  249. {$IFNDEF CLR}
  250.       with Result do
  251.       begin
  252.         if not WasSuccessful then
  253.           System.Halt(ErrorCount+FailureCount);
  254.       end
  255. {$ENDIF}
  256.     // else fall through
  257.   end;
  258. end;
  259. class function TTextTestListener.RunRegisteredTests(exitBehavior: TRunnerExitBehavior = rxbContinue): TTestResult;
  260. begin
  261.   Result := RunTest(registeredTests, exitBehavior);
  262. end;
  263. function RunTest(suite: ITest; exitBehavior: TRunnerExitBehavior = rxbContinue): TTestResult;
  264. begin
  265.   Result := TestFramework.RunTest(suite, [TTextTestListener.Create]);
  266.   case exitBehavior of
  267.     rxbPause:
  268.       try
  269.         writeln('Press <RETURN> to continue.');
  270.         readln
  271.       except
  272.       end;
  273.     rxbHaltOnFailures:
  274. {$IFNDEF CLR}
  275.       with Result do
  276.       begin
  277.         if not WasSuccessful then
  278.           System.Halt(ErrorCount+FailureCount);
  279.       end
  280. {$ENDIF}
  281.     // else fall through
  282.   end;
  283. end;
  284. function RunRegisteredTests(exitBehavior: TRunnerExitBehavior = rxbContinue): TTestResult;
  285. begin
  286.    Result := RunTest(registeredTests, exitBehavior);
  287. end;
  288. procedure TTextTestListener.Status(test: ITest; const Msg: string);
  289. begin
  290.   writeln(Format('%s: %s', [test.Name, Msg]));
  291. end;
  292. procedure TTextTestListener.Warning(test: ITest; const Msg: string);
  293. begin
  294.   writeln(Format('%s: %s', [test.Name, Msg]));
  295. end;
  296. function TTextTestListener.ShouldRunTest(test: ITest): boolean;
  297. begin
  298.   Result := test.Enabled;
  299. end;
  300. procedure TTextTestListener.EndSuite(suite: ITest);
  301. begin
  302. end;
  303. procedure TTextTestListener.StartSuite(suite: ITest);
  304. begin
  305. end;
  306. end.