@@ -14,7 +14,7 @@ namespace RuntimeUnitTestToolkit
14
14
public class UnitTestRunner : MonoBehaviour
15
15
{
16
16
// object is IEnumerator or Func<IEnumerator>
17
- Dictionary < string , List < KeyValuePair < string , object > > > tests = new Dictionary < string , List < KeyValuePair < string , object > > > ( ) ;
17
+ Dictionary < string , List < TestKeyValuePair > > tests = new Dictionary < string , List < TestKeyValuePair > > ( ) ;
18
18
19
19
List < Pair > additionalActionsOnFirst = new List < Pair > ( ) ;
20
20
@@ -133,45 +133,69 @@ static IEnumerable<Type> GetTestTargetTypes()
133
133
{
134
134
foreach ( var method in item . GetMethods ( ) )
135
135
{
136
- var t1 = method . GetCustomAttribute < TestAttribute > ( true ) ;
136
+ TestAttribute t1 = null ;
137
+ try
138
+ {
139
+ t1 = method . GetCustomAttribute < TestAttribute > ( true ) ;
140
+ }
141
+ catch ( Exception ex )
142
+ {
143
+ Debug . Log ( "TestAttribute Load Fail, Assembly:" + assembly . FullName ) ;
144
+ Debug . LogException ( ex ) ;
145
+ goto NEXT_ASSEMBLY ;
146
+ }
137
147
if ( t1 != null )
138
148
{
139
149
yield return item ;
140
150
break ;
141
151
}
142
- var t2 = method . GetCustomAttribute < UnityTestAttribute > ( true ) ;
152
+
153
+ UnityTestAttribute t2 = null ;
154
+ try
155
+ {
156
+ t2 = method . GetCustomAttribute < UnityTestAttribute > ( true ) ;
157
+ }
158
+ catch ( Exception ex )
159
+ {
160
+ Debug . Log ( "UnityTestAttribute Load Fail, Assembly:" + assembly . FullName ) ;
161
+ Debug . LogException ( ex ) ;
162
+ goto NEXT_ASSEMBLY ;
163
+ }
143
164
if ( t2 != null )
144
165
{
145
166
yield return item ;
146
167
break ;
147
168
}
148
169
}
149
170
}
171
+
172
+ NEXT_ASSEMBLY :
173
+ continue ;
150
174
}
151
175
}
152
176
153
- public void AddTest ( string group , string title , Action test )
177
+ public void AddTest ( string group , string title , Action test , List < Action > setups , List < Action > teardowns )
154
178
{
155
- List < KeyValuePair < string , object > > list ;
179
+ List < TestKeyValuePair > list ;
156
180
if ( ! tests . TryGetValue ( group , out list ) )
157
181
{
158
- list = new List < KeyValuePair < string , object > > ( ) ;
182
+ list = new List < TestKeyValuePair > ( ) ;
159
183
tests [ group ] = list ;
160
184
}
161
185
162
- list . Add ( new KeyValuePair < string , object > ( title , test ) ) ;
186
+ list . Add ( new TestKeyValuePair ( title , test , setups , teardowns ) ) ;
163
187
}
164
188
165
- public void AddAsyncTest ( string group , string title , Func < IEnumerator > asyncTestCoroutine )
189
+ public void AddAsyncTest ( string group , string title , Func < IEnumerator > asyncTestCoroutine , List < Action > setups , List < Action > teardowns )
166
190
{
167
- List < KeyValuePair < string , object > > list ;
191
+ List < TestKeyValuePair > list ;
168
192
if ( ! tests . TryGetValue ( group , out list ) )
169
193
{
170
- list = new List < KeyValuePair < string , object > > ( ) ;
194
+ list = new List < TestKeyValuePair > ( ) ;
171
195
tests [ group ] = list ;
172
196
}
173
197
174
- list . Add ( new KeyValuePair < string , object > ( title , asyncTestCoroutine ) ) ;
198
+ list . Add ( new TestKeyValuePair ( title , asyncTestCoroutine , setups , teardowns ) ) ;
175
199
}
176
200
177
201
public void AddCutomAction ( string name , UnityAction action )
@@ -193,6 +217,29 @@ public void RegisterAllMethods(Type testType)
193
217
var test = Activator . CreateInstance ( testType ) ;
194
218
195
219
var methods = testType . GetMethods ( System . Reflection . BindingFlags . Instance | System . Reflection . BindingFlags . Public ) ;
220
+ List < Action > setups = new List < Action > ( ) ;
221
+ List < Action > teardowns = new List < Action > ( ) ;
222
+ foreach ( var item in methods )
223
+ {
224
+ try
225
+ {
226
+ var setup = item . GetCustomAttribute < NUnit . Framework . SetUpAttribute > ( true ) ;
227
+ if ( setup != null )
228
+ {
229
+ setups . Add ( ( Action ) Delegate . CreateDelegate ( typeof ( Action ) , test , item ) ) ;
230
+ }
231
+ var teardown = item . GetCustomAttribute < NUnit . Framework . TearDownAttribute > ( true ) ;
232
+ if ( teardown != null )
233
+ {
234
+ teardowns . Add ( ( Action ) Delegate . CreateDelegate ( typeof ( Action ) , test , item ) ) ;
235
+ }
236
+ }
237
+ catch ( Exception e )
238
+ {
239
+ UnityEngine . Debug . LogError ( testType . Name + "." + item . Name + " failed to register setup/teardown method, exception: " + e . ToString ( ) ) ;
240
+ }
241
+ }
242
+
196
243
foreach ( var item in methods )
197
244
{
198
245
try
@@ -203,7 +250,7 @@ public void RegisterAllMethods(Type testType)
203
250
if ( item . GetParameters ( ) . Length == 0 && item . ReturnType == typeof ( IEnumerator ) )
204
251
{
205
252
var factory = ( Func < IEnumerator > ) Delegate . CreateDelegate ( typeof ( Func < IEnumerator > ) , test , item ) ;
206
- AddAsyncTest ( factory . Target . GetType ( ) . Name , factory . Method . Name , factory ) ;
253
+ AddAsyncTest ( factory . Target . GetType ( ) . Name , factory . Method . Name , factory , setups , teardowns ) ;
207
254
}
208
255
else
209
256
{
@@ -217,7 +264,7 @@ public void RegisterAllMethods(Type testType)
217
264
if ( item . GetParameters ( ) . Length == 0 && item . ReturnType == typeof ( void ) )
218
265
{
219
266
var invoke = ( Action ) Delegate . CreateDelegate ( typeof ( Action ) , test , item ) ;
220
- AddTest ( invoke . Target . GetType ( ) . Name , invoke . Method . Name , invoke ) ;
267
+ AddTest ( invoke . Target . GetType ( ) . Name , invoke . Method . Name , invoke , setups , teardowns ) ;
221
268
}
222
269
else
223
270
{
@@ -244,7 +291,7 @@ System.Collections.IEnumerator ScrollLogToEndNextFrame()
244
291
logScrollBar . value = 0 ;
245
292
}
246
293
247
- IEnumerator RunTestInCoroutine ( KeyValuePair < string , List < KeyValuePair < string , object > > > actionList )
294
+ IEnumerator RunTestInCoroutine ( KeyValuePair < string , List < TestKeyValuePair > > actionList )
248
295
{
249
296
Button self = null ;
250
297
foreach ( var btn in list . GetComponentsInChildren < Button > ( ) )
@@ -266,66 +313,81 @@ IEnumerator RunTestInCoroutine(KeyValuePair<string, List<KeyValuePair<string, ob
266
313
var totalExecutionTime = new List < double > ( ) ;
267
314
foreach ( var item2 in actionList . Value )
268
315
{
269
- // before start, cleanup
270
- GC . Collect ( ) ;
271
- GC . WaitForPendingFinalizers ( ) ;
272
- GC . Collect ( ) ;
273
-
274
- logText . text += "<color=teal>" + item2 . Key + "</color>\n " ;
275
- yield return null ;
276
-
277
- var v = item2 . Value ;
278
-
279
- var methodStopwatch = System . Diagnostics . Stopwatch . StartNew ( ) ;
280
- Exception exception = null ;
281
- if ( v is Action )
316
+ // setup
317
+ try
282
318
{
283
- try
319
+ foreach ( var setup in item2 . Setups )
284
320
{
285
- ( ( Action ) v ) . Invoke ( ) ;
321
+ setup ( ) ;
286
322
}
287
- catch ( Exception ex )
323
+
324
+ // before start, cleanup
325
+ GC . Collect ( ) ;
326
+ GC . WaitForPendingFinalizers ( ) ;
327
+ GC . Collect ( ) ;
328
+
329
+ logText . text += "<color=teal>" + item2 . Key + "</color>\n " ;
330
+ yield return null ;
331
+
332
+ var v = item2 . Value ;
333
+
334
+ var methodStopwatch = System . Diagnostics . Stopwatch . StartNew ( ) ;
335
+ Exception exception = null ;
336
+ if ( v is Action )
288
337
{
289
- exception = ex ;
338
+ try
339
+ {
340
+ ( ( Action ) v ) . Invoke ( ) ;
341
+ }
342
+ catch ( Exception ex )
343
+ {
344
+ exception = ex ;
345
+ }
290
346
}
291
- }
292
- else
293
- {
294
- var coroutineFactory = ( Func < IEnumerator > ) v ;
295
- IEnumerator coroutine = null ;
296
- try
347
+ else
297
348
{
298
- coroutine = coroutineFactory ( ) ;
349
+ var coroutineFactory = ( Func < IEnumerator > ) v ;
350
+ IEnumerator coroutine = null ;
351
+ try
352
+ {
353
+ coroutine = coroutineFactory ( ) ;
354
+ }
355
+ catch ( Exception ex )
356
+ {
357
+ exception = ex ;
358
+ }
359
+ if ( exception == null )
360
+ {
361
+ yield return StartCoroutine ( UnwrapEnumerator ( coroutine , ex =>
362
+ {
363
+ exception = ex ;
364
+ } ) ) ;
365
+ }
299
366
}
300
- catch ( Exception ex )
367
+ methodStopwatch . Stop ( ) ;
368
+ totalExecutionTime . Add ( methodStopwatch . Elapsed . TotalMilliseconds ) ;
369
+ if ( exception == null )
301
370
{
302
- exception = ex ;
371
+ logText . text += "OK, " + methodStopwatch . Elapsed . TotalMilliseconds . ToString ( "0.00" ) + "ms\n " ;
372
+ WriteToConsoleResult ( item2 . Key + ", " + methodStopwatch . Elapsed . TotalMilliseconds . ToString ( "0.00" ) + "ms" , true ) ;
303
373
}
304
- if ( exception == null )
374
+ else
305
375
{
306
- yield return StartCoroutine ( UnwrapEnumerator ( coroutine , ex =>
307
- {
308
- exception = ex ;
309
- } ) ) ;
376
+ // found match line...
377
+ var line = string . Join ( "\n " , exception . StackTrace . Split ( '\n ' ) . Where ( x => x . Contains ( actionList . Key ) || x . Contains ( item2 . Key ) ) . ToArray ( ) ) ;
378
+ logText . text += "<color=red>" + exception . Message + "\n " + line + "</color>\n " ;
379
+ WriteToConsoleResult ( item2 . Key + ", " + exception . Message , false ) ;
380
+ WriteToConsole ( line ) ;
381
+ allGreen = false ;
382
+ allTestGreen = false ;
310
383
}
311
384
}
312
-
313
- methodStopwatch . Stop ( ) ;
314
- totalExecutionTime . Add ( methodStopwatch . Elapsed . TotalMilliseconds ) ;
315
- if ( exception == null )
316
- {
317
- logText . text += "OK, " + methodStopwatch . Elapsed . TotalMilliseconds . ToString ( "0.00" ) + "ms\n " ;
318
- WriteToConsoleResult ( item2 . Key + ", " + methodStopwatch . Elapsed . TotalMilliseconds . ToString ( "0.00" ) + "ms" , true ) ;
319
- }
320
- else
385
+ finally
321
386
{
322
- // found match line...
323
- var line = string . Join ( "\n " , exception . StackTrace . Split ( '\n ' ) . Where ( x => x . Contains ( actionList . Key ) || x . Contains ( item2 . Key ) ) . ToArray ( ) ) ;
324
- logText . text += "<color=red>" + exception . Message + "\n " + line + "</color>\n " ;
325
- WriteToConsoleResult ( item2 . Key + ", " + exception . Message , false ) ;
326
- WriteToConsole ( line ) ;
327
- allGreen = false ;
328
- allTestGreen = false ;
387
+ foreach ( var teardown in item2 . Teardowns )
388
+ {
389
+ teardown ( ) ;
390
+ }
329
391
}
330
392
}
331
393
@@ -447,4 +509,21 @@ struct Pair
447
509
public UnityAction Action ;
448
510
}
449
511
}
512
+
513
+ public class TestKeyValuePair
514
+ {
515
+ public string Key ;
516
+ /// <summary>IEnumerator or Func[IEnumerator]</summary>
517
+ public object Value ;
518
+ public List < Action > Setups ;
519
+ public List < Action > Teardowns ;
520
+
521
+ public TestKeyValuePair ( string key , object value , List < Action > setups , List < Action > teardowns )
522
+ {
523
+ this . Key = key ;
524
+ this . Value = value ;
525
+ this . Setups = setups ;
526
+ this . Teardowns = teardowns ;
527
+ }
528
+ }
450
529
}
0 commit comments