@@ -14,7 +14,7 @@ namespace RuntimeUnitTestToolkit
1414 public class UnitTestRunner : MonoBehaviour
1515 {
1616 // 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 > > ( ) ;
1818
1919 List < Pair > additionalActionsOnFirst = new List < Pair > ( ) ;
2020
@@ -174,28 +174,28 @@ static IEnumerable<Type> GetTestTargetTypes()
174174 }
175175 }
176176
177- 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 )
178178 {
179- List < KeyValuePair < string , object > > list ;
179+ List < TestKeyValuePair > list ;
180180 if ( ! tests . TryGetValue ( group , out list ) )
181181 {
182- list = new List < KeyValuePair < string , object > > ( ) ;
182+ list = new List < TestKeyValuePair > ( ) ;
183183 tests [ group ] = list ;
184184 }
185185
186- list . Add ( new KeyValuePair < string , object > ( title , test ) ) ;
186+ list . Add ( new TestKeyValuePair ( title , test , setups , teardowns ) ) ;
187187 }
188188
189- 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 )
190190 {
191- List < KeyValuePair < string , object > > list ;
191+ List < TestKeyValuePair > list ;
192192 if ( ! tests . TryGetValue ( group , out list ) )
193193 {
194- list = new List < KeyValuePair < string , object > > ( ) ;
194+ list = new List < TestKeyValuePair > ( ) ;
195195 tests [ group ] = list ;
196196 }
197197
198- list . Add ( new KeyValuePair < string , object > ( title , asyncTestCoroutine ) ) ;
198+ list . Add ( new TestKeyValuePair ( title , asyncTestCoroutine , setups , teardowns ) ) ;
199199 }
200200
201201 public void AddCutomAction ( string name , UnityAction action )
@@ -217,6 +217,29 @@ public void RegisterAllMethods(Type testType)
217217 var test = Activator . CreateInstance ( testType ) ;
218218
219219 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+
220243 foreach ( var item in methods )
221244 {
222245 try
@@ -227,7 +250,7 @@ public void RegisterAllMethods(Type testType)
227250 if ( item . GetParameters ( ) . Length == 0 && item . ReturnType == typeof ( IEnumerator ) )
228251 {
229252 var factory = ( Func < IEnumerator > ) Delegate . CreateDelegate ( typeof ( Func < IEnumerator > ) , test , item ) ;
230- AddAsyncTest ( factory . Target . GetType ( ) . Name , factory . Method . Name , factory ) ;
253+ AddAsyncTest ( factory . Target . GetType ( ) . Name , factory . Method . Name , factory , setups , teardowns ) ;
231254 }
232255 else
233256 {
@@ -241,7 +264,7 @@ public void RegisterAllMethods(Type testType)
241264 if ( item . GetParameters ( ) . Length == 0 && item . ReturnType == typeof ( void ) )
242265 {
243266 var invoke = ( Action ) Delegate . CreateDelegate ( typeof ( Action ) , test , item ) ;
244- AddTest ( invoke . Target . GetType ( ) . Name , invoke . Method . Name , invoke ) ;
267+ AddTest ( invoke . Target . GetType ( ) . Name , invoke . Method . Name , invoke , setups , teardowns ) ;
245268 }
246269 else
247270 {
@@ -268,7 +291,7 @@ System.Collections.IEnumerator ScrollLogToEndNextFrame()
268291 logScrollBar . value = 0 ;
269292 }
270293
271- IEnumerator RunTestInCoroutine ( KeyValuePair < string , List < KeyValuePair < string , object > > > actionList )
294+ IEnumerator RunTestInCoroutine ( KeyValuePair < string , List < TestKeyValuePair > > actionList )
272295 {
273296 Button self = null ;
274297 foreach ( var btn in list . GetComponentsInChildren < Button > ( ) )
@@ -290,66 +313,81 @@ IEnumerator RunTestInCoroutine(KeyValuePair<string, List<KeyValuePair<string, ob
290313 var totalExecutionTime = new List < double > ( ) ;
291314 foreach ( var item2 in actionList . Value )
292315 {
293- // before start, cleanup
294- GC . Collect ( ) ;
295- GC . WaitForPendingFinalizers ( ) ;
296- GC . Collect ( ) ;
297-
298- logText . text += "<color=teal>" + item2 . Key + "</color>\n " ;
299- yield return null ;
300-
301- var v = item2 . Value ;
302-
303- var methodStopwatch = System . Diagnostics . Stopwatch . StartNew ( ) ;
304- Exception exception = null ;
305- if ( v is Action )
316+ // setup
317+ try
306318 {
307- try
319+ foreach ( var setup in item2 . Setups )
308320 {
309- ( ( Action ) v ) . Invoke ( ) ;
321+ setup ( ) ;
310322 }
311- 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 )
312337 {
313- exception = ex ;
338+ try
339+ {
340+ ( ( Action ) v ) . Invoke ( ) ;
341+ }
342+ catch ( Exception ex )
343+ {
344+ exception = ex ;
345+ }
314346 }
315- }
316- else
317- {
318- var coroutineFactory = ( Func < IEnumerator > ) v ;
319- IEnumerator coroutine = null ;
320- try
347+ else
321348 {
322- 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+ }
323366 }
324- catch ( Exception ex )
367+ methodStopwatch . Stop ( ) ;
368+ totalExecutionTime . Add ( methodStopwatch . Elapsed . TotalMilliseconds ) ;
369+ if ( exception == null )
325370 {
326- 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 ) ;
327373 }
328- if ( exception == null )
374+ else
329375 {
330- yield return StartCoroutine ( UnwrapEnumerator ( coroutine , ex =>
331- {
332- exception = ex ;
333- } ) ) ;
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 ;
334383 }
335384 }
336-
337- methodStopwatch . Stop ( ) ;
338- totalExecutionTime . Add ( methodStopwatch . Elapsed . TotalMilliseconds ) ;
339- if ( exception == null )
340- {
341- logText . text += "OK, " + methodStopwatch . Elapsed . TotalMilliseconds . ToString ( "0.00" ) + "ms\n " ;
342- WriteToConsoleResult ( item2 . Key + ", " + methodStopwatch . Elapsed . TotalMilliseconds . ToString ( "0.00" ) + "ms" , true ) ;
343- }
344- else
385+ finally
345386 {
346- // found match line...
347- var line = string . Join ( "\n " , exception . StackTrace . Split ( '\n ' ) . Where ( x => x . Contains ( actionList . Key ) || x . Contains ( item2 . Key ) ) . ToArray ( ) ) ;
348- logText . text += "<color=red>" + exception . Message + "\n " + line + "</color>\n " ;
349- WriteToConsoleResult ( item2 . Key + ", " + exception . Message , false ) ;
350- WriteToConsole ( line ) ;
351- allGreen = false ;
352- allTestGreen = false ;
387+ foreach ( var teardown in item2 . Teardowns )
388+ {
389+ teardown ( ) ;
390+ }
353391 }
354392 }
355393
@@ -471,4 +509,21 @@ struct Pair
471509 public UnityAction Action ;
472510 }
473511 }
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+ }
474529}
0 commit comments