testreport.pp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. {$mode objfpc}
  2. {$h+}
  3. {
  4. This file is part of the Free Component Library (FCL)
  5. Copyright (c) 2004 by Dean Zobec, Michael Van Canneyt
  6. an example of a console test runner of FPCUnit tests.
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. unit testreport;
  14. interface
  15. uses
  16. classes, SysUtils, fpcunit, testutils;
  17. type
  18. { TXMLResultsWriter }
  19. TXMLResultsWriter = class(TNoRefCountObject, ITestListener)
  20. public
  21. procedure WriteHeader;
  22. procedure WriteResult(aResult: TTestResult);
  23. {ITestListener}
  24. procedure AddFailure(ATest: TTest; AFailure: TTestFailure);
  25. procedure AddError(ATest: TTest; AError: TTestFailure);
  26. procedure StartTest(ATest: TTest);
  27. procedure EndTest(ATest: TTest);
  28. procedure StartTestSuite(ATestSuite: TTestSuite);
  29. procedure EndTestSuite(ATestSuite: TTestSuite);
  30. end;
  31. { TPlainResultsWriter }
  32. TPlainResultsWriter = class(TNoRefCountObject, ITestListener)
  33. public
  34. procedure WriteHeader;
  35. procedure WriteResult(aResult: TTestResult);
  36. {ITestListener}
  37. procedure AddFailure(ATest: TTest; AFailure: TTestFailure);
  38. procedure AddError(ATest: TTest; AError: TTestFailure);
  39. procedure StartTest(ATest: TTest);
  40. procedure EndTest(ATest: TTest);
  41. procedure StartTestSuite(ATestSuite: TTestSuite);
  42. procedure EndTestSuite(ATestSuite: TTestSuite);
  43. end;
  44. {
  45. TLatexResultsWriter = class(TNoRefCountObject, ITestListener)
  46. public
  47. procedure AddFailure(ATest: TTest; AFailure: TTestFailure);
  48. procedure AddError(ATest: TTest; AError: TTestFailure);
  49. procedure StartTest(ATest: TTest);
  50. procedure EndTest(ATest: TTest);
  51. procedure StartTestSuite(ATestSuite: TTestSuite);
  52. procedure EndTestSuite(ATestSuite: TTestSuite);
  53. end;}
  54. function TestSuiteAsXML(aSuite:TTestSuite; Indent : Integer): string;
  55. function TestSuiteAsXML(aSuite: TTestSuite): string;
  56. function TestSuiteAsLatex(aSuite:TTestSuite): string;
  57. function TestSuiteAsPlain(aSuite:TTestSuite): string;
  58. function GetSuiteAsXML(aSuite: TTestSuite): string;
  59. function GetSuiteAsLatex(aSuite: TTestSuite): string;
  60. function GetSuiteAsPlain(aSuite: TTestSuite): string;
  61. function TestResultAsXML(aTestResult: TTestResult): string;
  62. function TestResultAsPlain(aTestResult: TTestResult): string;
  63. implementation
  64. {TXMLResultsWriter}
  65. procedure TXMLResultsWriter.WriteHeader;
  66. begin
  67. writeln('<testresults>');
  68. writeln('<testlisting>');
  69. end;
  70. procedure TXMLResultsWriter.WriteResult(aResult: TTestResult);
  71. begin
  72. writeln('</testlisting>');
  73. writeln(TestResultAsXML(aResult));
  74. writeln('</testresults>');
  75. end;
  76. procedure TXMLResultsWriter.AddFailure(ATest: TTest; AFailure: TTestFailure);
  77. begin
  78. writeln('<failure ExceptionClassName="', AFailure.ExceptionClassName, '">');
  79. writeln('<message>', AFailure.ExceptionMessage, '</message>');
  80. writeln('</failure>');
  81. end;
  82. procedure TXMLResultsWriter.AddError(ATest: TTest; AError: TTestFailure);
  83. begin
  84. writeln('<error ExceptionClassName="', AError.ExceptionClassName, '">');
  85. writeln('<message>', AError.ExceptionMessage, '</message>');
  86. writeln('<sourceunit>', AError.SourceUnitName, '</sourceunit>');
  87. writeln('<methodname>', AError.FailedMethodName, '</methodname>');
  88. writeln('<linenumber>', AError.LineNumber, '</linenumber>');
  89. writeln('</error>');
  90. end;
  91. procedure TXMLResultsWriter.StartTest(ATest: TTest);
  92. begin
  93. writeln('<test name="' , ATest.TestSuiteName + '.' + ATest.TestName, '">');
  94. end;
  95. procedure TXMLResultsWriter.EndTest(ATest: TTest);
  96. begin
  97. writeln('</test>');
  98. end;
  99. procedure TXMLResultsWriter.StartTestSuite(ATestSuite: TTestSuite);
  100. begin
  101. end;
  102. procedure TXMLResultsWriter.EndTestSuite(ATestSuite: TTestSuite);
  103. begin
  104. end;
  105. {TPlainResultsWriter}
  106. procedure TPlainResultsWriter.WriteHeader;
  107. begin
  108. end;
  109. procedure TPlainResultsWriter.WriteResult(aResult: TTestResult);
  110. begin
  111. writeln('', TestResultAsPlain(aResult));
  112. end;
  113. procedure TPlainResultsWriter.AddFailure(ATest: TTest; AFailure: TTestFailure);
  114. begin
  115. writeln('', AFailure.ExceptionMessage);
  116. end;
  117. procedure TPlainResultsWriter.AddError(ATest: TTest; AError: TTestFailure);
  118. begin
  119. writeln(' Error: ', AError.ExceptionClassName);
  120. writeln(' Exception: ', AError.ExceptionMessage);
  121. writeln(' Source unit: ', AError.SourceUnitName);
  122. writeln(' Method name: ', AError.FailedMethodName);
  123. writeln(' Line number: ', AError.LineNumber);
  124. end;
  125. procedure TPlainResultsWriter.StartTest(ATest: TTest);
  126. begin
  127. write('Test: ', ATest.TestSuiteName + '.' + ATest.TestName);
  128. end;
  129. procedure TPlainResultsWriter.EndTest(ATest: TTest);
  130. begin
  131. writeln;
  132. end;
  133. procedure TPlainResultsWriter.StartTestSuite(ATestSuite: TTestSuite);
  134. begin
  135. { example output }
  136. // Writeln('TestSuite: ' + ATestSuite.TestName);
  137. end;
  138. procedure TPlainResultsWriter.EndTestSuite(ATestSuite: TTestSuite);
  139. begin
  140. { example output }
  141. // Writeln('TestSuite: ' + ATestSuite.TestName + ' - END ');
  142. end;
  143. function TestSuiteAsXML(aSuite:TTestSuite): string;
  144. begin
  145. Result:=TestSuiteAsXML(ASuite,0);
  146. end;
  147. function TestSuiteAsXML(aSuite:TTestSuite; Indent : Integer): string;
  148. var
  149. i: integer;
  150. begin
  151. Result := StringOfChar(' ',Indent) + '<TestSuite name="' + ASuite.TestName + '">' + System.sLineBreak;
  152. Inc(Indent, 2);
  153. for i := 0 to aSuite.Tests.Count - 1 do
  154. if TTest(aSuite.Tests.Items[i]) is TTestSuite then
  155. Result := Result + TestSuiteAsXML(TTestSuite(aSuite.Tests.Items[i]),Indent)
  156. else
  157. if TTest(aSuite.Tests.Items[i]) is TTestCase then
  158. Result := Result + StringOfChar(' ',Indent) + '<test>' + TTestcase(aSuite.Tests.Items[i]).TestName + '</test>' + System.sLineBreak;
  159. Dec(Indent, 2);
  160. Result := Result + StringOfChar(' ',Indent) + '</TestSuite>' + System.sLineBreak;
  161. end;
  162. function TestSuiteAsLatex(aSuite:TTestSuite): string;
  163. var
  164. i,j: integer;
  165. s: TTestSuite;
  166. begin
  167. Result := '\flushleft' + System.sLineBreak;
  168. for i := 0 to aSuite.Tests.Count - 1 do
  169. begin
  170. s := TTestSuite(ASuite.Tests.Items[i]);
  171. Result := Result + s.TestSuiteName + System.sLineBreak;
  172. Result := Result + '\begin{itemize}'+ System.sLineBreak;
  173. for j := 0 to s.Tests.Count - 1 do
  174. if TTest(s.Tests.Items[j]) is TTestCase then
  175. Result := Result + '\item[-] ' + TTestcase(s.Tests.Items[j]).TestName + System.sLineBreak;
  176. Result := Result +'\end{itemize}' + System.sLineBreak;
  177. end;
  178. end;
  179. function TestSuiteAsPlain(aSuite:TTestSuite): string;
  180. var
  181. i,j: integer;
  182. s: TTestSuite;
  183. begin
  184. for i := 0 to aSuite.Tests.Count - 1 do
  185. if TTest(aSuite.Tests.Items[i]) is TTestSuite then
  186. Result := Result + TestSuiteAsPlain(TTestSuite(aSuite.Tests.Items[i]))
  187. else
  188. if TTest(aSuite.Tests.Items[i]) is TTestCase then
  189. Result := Result + ' ' + ASuite.TestName+'.' + TTestcase(aSuite.Tests.Items[i]).TestName + System.sLineBreak;
  190. end;
  191. function GetSuiteAsXML(aSuite: TTestSuite): string;
  192. begin
  193. if aSuite <> nil then
  194. begin
  195. if aSuite.TestName = '' then
  196. aSuite.TestName := 'Test Suite';
  197. Result := TestSuiteAsXML(aSuite)
  198. end
  199. else
  200. Result := '';
  201. end;
  202. function GetSuiteAsLatex(aSuite: TTestSuite): string;
  203. begin
  204. if aSuite <> nil then
  205. begin
  206. Result := '\documentclass[a4paper,12pt]{article}' + System.sLineBreak;
  207. Result := Result + '\usepackage{array}' + System.sLineBreak;
  208. Result := Result + '\usepackage{mdwlist}' + System.sLineBreak + System.sLineBreak;
  209. Result := Result + '\begin{document}' + System.sLineBreak + System.sLineBreak;
  210. if aSuite.TestName = '' then
  211. aSuite.TestName := 'Test Suite';
  212. Result := Result + TestSuiteAsLatex(aSuite);
  213. Result := Result + '\end{document}';
  214. end
  215. else
  216. Result := '';
  217. end;
  218. function GetSuiteAsPlain(aSuite: TTestSuite): string;
  219. begin
  220. Result := '';
  221. if aSuite <> nil then
  222. Result := 'TestSuites: ' + System.sLineBreak + TestSuiteAsPlain(aSuite);
  223. end;
  224. function TestResultAsXML(aTestResult: TTestResult): string;
  225. var
  226. i: longint;
  227. f: TTestFailure;
  228. begin
  229. with aTestResult do
  230. begin
  231. Result := '<NumberOfRunnedTests>' + intToStr(RunTests) + '</NumberOfRunnedTests>' + System.sLineBreak;
  232. Result := Result + '<NumberOfErrors>' + intToStr(NumberOfErrors) + '</NumberOfErrors>' + System.sLineBreak;
  233. Result := Result + '<NumberOfFailures>' + intToStr(NumberOfFailures) + '</NumberOfFailures>';
  234. if NumberOfErrors <> 0 then
  235. begin
  236. Result := Result + System.sLineBreak;
  237. Result := Result + '<ListOfErrors>';
  238. for i := 0 to Errors.Count - 1 do
  239. begin
  240. Result := Result + System.sLineBreak;
  241. Result := Result + '<Error>' + System.sLineBreak;
  242. f := TTestFailure(Errors.Items[i]);
  243. Result := Result + ' <Message>' + f.AsString + '</Message>' + System.sLineBreak;
  244. Result := Result + ' <ExceptionClass>' + f.ExceptionClassName + '</ExceptionClass>' + System.sLineBreak;
  245. Result := Result + ' <ExceptionMessage>' + f.ExceptionMessage + '</ExceptionMessage>' + System.sLineBreak;
  246. Result := Result + ' <SourceUnitName>' + f.SourceUnitName + '</SourceUnitName>' + System.sLineBreak;
  247. Result := Result + ' <LineNumber>' + IntToStr(f.LineNumber) + '</LineNumber>' + System.sLineBreak;
  248. Result := Result + ' <FailedMethodName>' + f.FailedMethodName + '</FailedMethodName>' + System.sLineBreak;
  249. Result := Result + '</Error>' + System.sLineBreak;
  250. end;
  251. Result := Result + '</ListOfErrors>';
  252. end;
  253. if NumberOfFailures <> 0 then
  254. begin
  255. Result := Result + System.sLineBreak;
  256. Result := Result + '<ListOfFailures>' + System.sLineBreak;
  257. for i := 0 to Failures.Count - 1 do
  258. begin
  259. Result := Result + '<Failure>' + System.sLineBreak;
  260. f := TTestFailure(Failures.Items[i]);
  261. Result := Result + ' <Message>' + f.AsString + '</Message>' + System.sLineBreak;
  262. Result := Result + ' <ExceptionClass>' + f.ExceptionClassName + '</ExceptionClass>' + System.sLineBreak;
  263. Result := Result + ' <ExceptionMessage>' + f.ExceptionMessage + '</ExceptionMessage>' + System.sLineBreak;
  264. Result := Result + '</Failure>' + System.sLineBreak;
  265. end;
  266. Result := Result + '</ListOfFailures>';
  267. end;
  268. end;
  269. end;
  270. function TestResultAsPlain(aTestResult: TTestResult): string;
  271. var
  272. i: longint;
  273. f: TTestFailure;
  274. begin
  275. with aTestResult do
  276. begin
  277. Result := 'Number of run tests: ' + intToStr(RunTests) + System.sLineBreak;
  278. Result := Result + 'Number of errors: ' + intToStr(NumberOfErrors) + System.sLineBreak;
  279. Result := Result + 'Number of failures: ' + intToStr(NumberOfFailures);
  280. if NumberOfErrors <> 0 then
  281. begin
  282. Result := Result + System.sLineBreak;
  283. Result := Result + System.sLineBreak;
  284. Result := Result + 'List of errors:';
  285. for i := 0 to Errors.Count - 1 do
  286. begin
  287. Result := Result + System.sLineBreak;
  288. Result := Result + ' Error: ' + System.sLineBreak;
  289. f := TTestFailure(Errors.Items[i]);
  290. Result := Result + ' Message: ' + f.AsString + System.sLineBreak;
  291. Result := Result + ' Exception class: ' + f.ExceptionClassName + System.sLineBreak;
  292. Result := Result + ' Exception message: ' + f.ExceptionMessage + System.sLineBreak;
  293. Result := Result + ' Source unitname: ' + f.SourceUnitName + System.sLineBreak;
  294. Result := Result + ' Line number: ' + IntToStr(f.LineNumber) + System.sLineBreak;
  295. Result := Result + ' Failed methodname: ' + f.FailedMethodName + System.sLineBreak;
  296. end;
  297. end;
  298. if NumberOfFailures <> 0 then
  299. begin
  300. Result := Result + System.sLineBreak;
  301. Result := Result + System.sLineBreak;
  302. Result := Result + 'List of failures:' + System.sLineBreak;
  303. for i := 0 to Failures.Count - 1 do
  304. begin
  305. Result := Result + ' Failure: ' + System.sLineBreak;
  306. f := TTestFailure(Failures.Items[i]);
  307. Result := Result + ' Message: ' + f.AsString + System.sLineBreak;
  308. Result := Result + ' Exception class: ' + f.ExceptionClassName + System.sLineBreak;
  309. Result := Result + ' Exception message: ' + f.ExceptionMessage + System.sLineBreak;
  310. end;
  311. end;
  312. end;
  313. Result := Result + System.sLineBreak;
  314. end;
  315. end.