1
1
// Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt
2
2
3
3
using System ;
4
- using System . Globalization ;
5
4
using System . IO ;
6
- using System . Reflection ;
7
5
using System . Xml ;
8
6
using NUnit . TextDisplay ;
9
7
using NUnit . Engine ;
@@ -17,7 +15,6 @@ public class AgentDirectRunner
17
15
private AgentOptions _options ;
18
16
19
17
private ColorConsoleWriter OutWriter { get ; } = new ColorConsoleWriter ( ) ;
20
- private int ReportIndex { get ; set ; }
21
18
22
19
public AgentDirectRunner ( AgentOptions options )
23
20
{
@@ -30,7 +27,7 @@ public void ExecuteTestsDirectly()
30
27
{
31
28
var testFile = _options . Files [ 0 ] ;
32
29
33
- WriteHeader ( OutWriter ) ;
30
+ ResultReporter . WriteHeader ( OutWriter ) ;
34
31
35
32
TestPackage package = new TestPackage ( testFile ) . SubPackages [ 0 ] ;
36
33
@@ -40,18 +37,9 @@ public void ExecuteTestsDirectly()
40
37
var runner = new LocalTestRunner ( package ) ;
41
38
#endif
42
39
var xmlResult = runner . Run ( null , TestFilter . Empty ) . Xml ;
40
+ var summary = new ResultSummary ( xmlResult ) ;
43
41
44
- WriteRunSettingsReport ( xmlResult ) ;
45
-
46
- var result = xmlResult . GetAttribute ( "result" ) ;
47
- if ( result == "Failed" || result == "Warning" )
48
- WriteErrorsFailuresAndWarningsReport ( xmlResult ) ;
49
-
50
- int notrunCount = int . Parse ( xmlResult . GetAttribute ( "skipped" ) ?? "0" ) ;
51
- if ( notrunCount > 0 )
52
- WriteNotRunReport ( xmlResult ) ;
53
-
54
- WriteSummaryReport ( xmlResult ) ;
42
+ ResultReporter . ReportResults ( summary , OutWriter ) ;
55
43
56
44
var pathToResultFile = Path . Combine ( _options . WorkDirectory , "TestResult.xml" ) ;
57
45
WriteResultFile ( xmlResult , pathToResultFile ) ;
@@ -66,241 +54,6 @@ public void ExecuteTestsDirectly()
66
54
Environment . Exit ( AgentExitCodes . OK ) ;
67
55
}
68
56
69
- private static void WriteHeader ( ExtendedTextWriter outWriter )
70
- {
71
- var ea = Assembly . GetEntryAssembly ( ) ;
72
- if ( ea is not null )
73
- {
74
- var title = GetAttribute < AssemblyTitleAttribute > ( ea ) ? . Title ;
75
- var version = GetAttribute < AssemblyFileVersionAttribute > ( ea ) ? . Version ;
76
- var copyright = GetAttribute < AssemblyCopyrightAttribute > ( ea ) ? . Copyright ;
77
-
78
- outWriter . WriteLine ( ColorStyle . Header , $ "{ title } { version } ") ;
79
- if ( copyright is not null )
80
- outWriter . WriteLine ( ColorStyle . SubHeader , copyright ) ;
81
- outWriter . WriteLine ( ColorStyle . SubHeader , DateTime . Now . ToString ( CultureInfo . CurrentCulture . DateTimeFormat . FullDateTimePattern ) ) ;
82
- outWriter . WriteLine ( ) ;
83
- }
84
- }
85
-
86
- private static TAttr ? GetAttribute < TAttr > ( Assembly assembly )
87
- where TAttr : Attribute
88
- {
89
- return assembly ? . GetCustomAttribute < TAttr > ( ) ;
90
- }
91
-
92
- internal void WriteRunSettingsReport ( XmlNode resultNode )
93
- {
94
- var settings = resultNode . SelectNodes ( "settings/setting" ) ;
95
-
96
- if ( settings is not null && settings . Count > 0 )
97
- {
98
- OutWriter . WriteLine ( ColorStyle . SectionHeader , "Run Settings" ) ;
99
- settings . ForEachNode ( WriteSettingsNode ) ;
100
- OutWriter . WriteLine ( ) ;
101
- }
102
- }
103
-
104
- private void WriteSettingsNode ( XmlNode node )
105
- {
106
- var items = node . SelectNodes ( "item" ) ;
107
- var name = node . GetAttribute ( "name" ) ;
108
- var val = node . GetAttribute ( "value" ) ?? string . Empty ;
109
-
110
- if ( items is not null )
111
- {
112
- OutWriter . WriteLabelLine ( $ " { name } :", items . Count > 0 ? string . Empty : $ " { val } ") ;
113
-
114
- items . ForEachNode ( ( item ) =>
115
- {
116
- var key = item . GetAttribute ( "key" ) ;
117
- var value = item . GetAttribute ( "value" ) ;
118
- OutWriter . WriteLine ( ColorStyle . Value , $ " { key } -> { value } ") ;
119
- } ) ;
120
- }
121
- }
122
-
123
- public void WriteSummaryReport ( XmlNode resultNode )
124
- {
125
- var overallResult = resultNode . GetAttribute ( "result" ) ?? "Unknown" ;
126
- if ( overallResult == "Skipped" )
127
- overallResult = "Warning" ;
128
-
129
- ColorStyle resultColor = overallResult == "Passed"
130
- ? ColorStyle . Pass
131
- : overallResult == "Failed" || overallResult == "Unknown"
132
- ? ColorStyle . Failure
133
- : overallResult == "Warning"
134
- ? ColorStyle . Warning
135
- : ColorStyle . Output ;
136
-
137
- OutWriter . WriteLine ( ColorStyle . SectionHeader , "Test Run Summary" ) ;
138
- OutWriter . WriteLabelLine ( overallResult , resultColor ) ;
139
-
140
- int cases = resultNode . GetAttribute ( "testcasecount" , 0 ) ;
141
- int passed = resultNode . GetAttribute ( "passed" , 0 ) ;
142
- int failed = resultNode . GetAttribute ( "failed" , 0 ) ;
143
- int warnings = resultNode . GetAttribute ( "warnings" , 0 ) ;
144
- int inconclusive = resultNode . GetAttribute ( "inconclusive" , 0 ) ;
145
- int skipped = resultNode . GetAttribute ( "skipped" , 0 ) ;
146
-
147
- WriteSummaryCount ( " Test Cases: " , cases ) ;
148
- WriteSummaryCount ( ", Passed: " , passed ) ;
149
- WriteSummaryCount ( ", Failed: " , failed , ColorStyle . Failure ) ;
150
- WriteSummaryCount ( ", Warnings: " , warnings , ColorStyle . Warning ) ;
151
- WriteSummaryCount ( ", Inconclusive: " , inconclusive ) ;
152
- WriteSummaryCount ( ", Skipped: " , skipped ) ;
153
- OutWriter . WriteLine ( ) ;
154
-
155
- var duration = resultNode . GetAttribute ( "duration" , 0.0 ) ;
156
- var startTime = resultNode . GetAttribute ( "start-time" , DateTime . MinValue ) ;
157
- var endTime = resultNode . GetAttribute ( "end-time" , DateTime . MaxValue ) ;
158
-
159
- OutWriter . WriteLabelLine ( " Start time: " , startTime . ToString ( "u" ) ) ;
160
- OutWriter . WriteLabelLine ( " End time: " , endTime . ToString ( "u" ) ) ;
161
- OutWriter . WriteLabelLine ( " Duration: " , string . Format ( NumberFormatInfo . InvariantInfo , "{0:0.000} seconds" , duration ) ) ;
162
- OutWriter . WriteLine ( ) ;
163
- }
164
-
165
- public void WriteErrorsFailuresAndWarningsReport ( XmlNode resultNode )
166
- {
167
- ReportIndex = 0 ;
168
- OutWriter . WriteLine ( ColorStyle . SectionHeader , "Errors, Failures and Warnings" ) ;
169
- OutWriter . WriteLine ( ) ;
170
-
171
- WriteErrorsFailuresAndWarnings ( resultNode ) ;
172
- }
173
-
174
- private void WriteErrorsFailuresAndWarnings ( XmlNode resultNode )
175
- {
176
- const string OLD_NUNIT_CHILD_HAD_ERRORS_MESSAGE = "One or more child tests had errors" ;
177
- const string OLD_NUNIT_CHILD_HAD_WARNINGS_MESSAGE = "One or more child tests had errors" ;
178
-
179
- string resultState = resultNode . GetAttribute ( "result" ) ?? string . Empty ;
180
-
181
- switch ( resultNode . Name )
182
- {
183
- case "test-case" :
184
- if ( resultState == "Failed" || resultState == "Warning" )
185
- DisplayResultItem ( resultNode ) ;
186
- return ;
187
-
188
- // Not present in this agent but retain for use with other agents
189
- case "test-run" :
190
- resultNode . ForEachChildNode ( WriteErrorsFailuresAndWarnings ) ;
191
- break ;
192
-
193
- case "test-suite" :
194
- if ( resultState == "Failed" || resultState == "Warning" )
195
- {
196
- var suiteType = resultNode . GetAttribute ( "type" ) ;
197
- if ( suiteType == "Theory" )
198
- {
199
- // Report failure of the entire theory and then go on
200
- // to list the individual cases that failed
201
- DisplayResultItem ( resultNode ) ;
202
- }
203
- else
204
- {
205
- // Where did this happen? Default is in the current test.
206
- var site = resultNode . GetAttribute ( "site" ) ;
207
-
208
- // Correct a problem in some framework versions, whereby warnings and some failures
209
- // are promulgated to the containing suite without setting the FailureSite.
210
- if ( site is null )
211
- {
212
- if ( resultNode . SelectSingleNode ( "reason/message" ) ? . InnerText == OLD_NUNIT_CHILD_HAD_WARNINGS_MESSAGE ||
213
- resultNode . SelectSingleNode ( "failure/message" ) ? . InnerText == OLD_NUNIT_CHILD_HAD_ERRORS_MESSAGE )
214
- {
215
- site = "Child" ;
216
- }
217
- else
218
- site = "Test" ;
219
- }
220
-
221
- // Only report errors in the current test method, setup or teardown
222
- if ( site == "SetUp" || site == "TearDown" || site == "Test" )
223
- {
224
- DisplayResultItem ( resultNode ) ;
225
- }
226
-
227
- // Do not list individual "failed" tests after a one-time setup failure
228
- if ( site == "SetUp" )
229
- return ;
230
- }
231
- }
232
-
233
- resultNode . ForEachChildNode ( WriteErrorsFailuresAndWarnings ) ;
234
-
235
- break ;
236
- }
237
- }
238
-
239
- public void WriteNotRunReport ( XmlNode resultNode )
240
- {
241
- ReportIndex = 0 ;
242
- OutWriter . WriteLine ( ColorStyle . SectionHeader , "Tests Not Run" ) ;
243
- OutWriter . WriteLine ( ) ;
244
- WriteNotRunResults ( resultNode ) ;
245
- }
246
-
247
- private void WriteNotRunResults ( XmlNode resultNode )
248
- {
249
- switch ( resultNode . Name )
250
- {
251
- case "test-case" :
252
- string ? status = resultNode . GetAttribute ( "result" ) ;
253
-
254
- if ( status == "Skipped" )
255
- DisplayResultItem ( resultNode ) ;
256
-
257
- break ;
258
-
259
- case "test-suite" :
260
- case "test-run" :
261
- resultNode . ForEachChildNode ( WriteNotRunResults ) ;
262
-
263
- break ;
264
- }
265
- }
266
-
267
- private static readonly char [ ] EOL_CHARS = new char [ ] { '\r ' , '\n ' } ;
268
-
269
- private void DisplayResultItem ( XmlNode resultNode )
270
- {
271
- string ? resultState = resultNode . GetAttribute ( "result" ) ;
272
- string ? fullName = resultNode . GetAttribute ( "fullname" ) ;
273
- string ? message = ( resultNode . SelectSingleNode ( "failure/message" ) ?? resultNode . SelectSingleNode ( "reason/message" ) ) ? . InnerText . Trim ( EOL_CHARS ) ;
274
-
275
- OutWriter . WriteLine ( GetColorStyle ( ) ,
276
- string . Format ( $ "{ ++ ReportIndex } ) { resultState } : { fullName } ") ) ;
277
- if ( ! string . IsNullOrEmpty ( message ) )
278
- OutWriter . WriteLine ( ColorStyle . Output , message ) ;
279
- var stackTrace = resultNode . SelectSingleNode ( "failure/stack-trace" ) ? . InnerText ;
280
- if ( ! string . IsNullOrEmpty ( stackTrace ) )
281
- OutWriter . WriteLine ( stackTrace ) ;
282
- OutWriter . WriteLine ( ) ;
283
-
284
- ColorStyle GetColorStyle ( )
285
- {
286
- return resultState == "Failed"
287
- ? ColorStyle . Failure
288
- : resultState == "Warning"
289
- ? ColorStyle . Warning
290
- : ColorStyle . Output ;
291
- }
292
- }
293
-
294
- private void WriteSummaryCount ( string label , int count )
295
- {
296
- OutWriter . WriteLabel ( label , count . ToString ( CultureInfo . CurrentUICulture ) ) ;
297
- }
298
-
299
- private void WriteSummaryCount ( string label , int count , ColorStyle color )
300
- {
301
- OutWriter . WriteLabel ( label , count . ToString ( CultureInfo . CurrentUICulture ) , count > 0 ? color : ColorStyle . Value ) ;
302
- }
303
-
304
57
public static void WriteResultFile ( XmlNode resultNode , string outputPath )
305
58
{
306
59
using ( var stream = new FileStream ( outputPath , FileMode . Create , FileAccess . Write ) )
0 commit comments