Skip to content

Commit 8750a6c

Browse files
committed
Setup, Teardown
1 parent 276a100 commit 8750a6c

File tree

1 file changed

+140
-61
lines changed

1 file changed

+140
-61
lines changed

RuntimeUnitTestToolkit/Assets/RuntimeUnitTestToolkit/UnitTestRunner.cs

Lines changed: 140 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -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

@@ -133,45 +133,69 @@ static IEnumerable<Type> GetTestTargetTypes()
133133
{
134134
foreach (var method in item.GetMethods())
135135
{
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+
}
137147
if (t1 != null)
138148
{
139149
yield return item;
140150
break;
141151
}
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+
}
143164
if (t2 != null)
144165
{
145166
yield return item;
146167
break;
147168
}
148169
}
149170
}
171+
172+
NEXT_ASSEMBLY:
173+
continue;
150174
}
151175
}
152176

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)
154178
{
155-
List<KeyValuePair<string, object>> list;
179+
List<TestKeyValuePair> list;
156180
if (!tests.TryGetValue(group, out list))
157181
{
158-
list = new List<KeyValuePair<string, object>>();
182+
list = new List<TestKeyValuePair>();
159183
tests[group] = list;
160184
}
161185

162-
list.Add(new KeyValuePair<string, object>(title, test));
186+
list.Add(new TestKeyValuePair(title, test, setups, teardowns));
163187
}
164188

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)
166190
{
167-
List<KeyValuePair<string, object>> list;
191+
List<TestKeyValuePair> list;
168192
if (!tests.TryGetValue(group, out list))
169193
{
170-
list = new List<KeyValuePair<string, object>>();
194+
list = new List<TestKeyValuePair>();
171195
tests[group] = list;
172196
}
173197

174-
list.Add(new KeyValuePair<string, object>(title, asyncTestCoroutine));
198+
list.Add(new TestKeyValuePair(title, asyncTestCoroutine, setups, teardowns));
175199
}
176200

177201
public void AddCutomAction(string name, UnityAction action)
@@ -193,6 +217,29 @@ public void RegisterAllMethods(Type testType)
193217
var test = Activator.CreateInstance(testType);
194218

195219
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+
196243
foreach (var item in methods)
197244
{
198245
try
@@ -203,7 +250,7 @@ public void RegisterAllMethods(Type testType)
203250
if (item.GetParameters().Length == 0 && item.ReturnType == typeof(IEnumerator))
204251
{
205252
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);
207254
}
208255
else
209256
{
@@ -217,7 +264,7 @@ public void RegisterAllMethods(Type testType)
217264
if (item.GetParameters().Length == 0 && item.ReturnType == typeof(void))
218265
{
219266
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);
221268
}
222269
else
223270
{
@@ -244,7 +291,7 @@ System.Collections.IEnumerator ScrollLogToEndNextFrame()
244291
logScrollBar.value = 0;
245292
}
246293

247-
IEnumerator RunTestInCoroutine(KeyValuePair<string, List<KeyValuePair<string, object>>> actionList)
294+
IEnumerator RunTestInCoroutine(KeyValuePair<string, List<TestKeyValuePair>> actionList)
248295
{
249296
Button self = null;
250297
foreach (var btn in list.GetComponentsInChildren<Button>())
@@ -266,66 +313,81 @@ IEnumerator RunTestInCoroutine(KeyValuePair<string, List<KeyValuePair<string, ob
266313
var totalExecutionTime = new List<double>();
267314
foreach (var item2 in actionList.Value)
268315
{
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
282318
{
283-
try
319+
foreach (var setup in item2.Setups)
284320
{
285-
((Action)v).Invoke();
321+
setup();
286322
}
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)
288337
{
289-
exception = ex;
338+
try
339+
{
340+
((Action)v).Invoke();
341+
}
342+
catch (Exception ex)
343+
{
344+
exception = ex;
345+
}
290346
}
291-
}
292-
else
293-
{
294-
var coroutineFactory = (Func<IEnumerator>)v;
295-
IEnumerator coroutine = null;
296-
try
347+
else
297348
{
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+
}
299366
}
300-
catch (Exception ex)
367+
methodStopwatch.Stop();
368+
totalExecutionTime.Add(methodStopwatch.Elapsed.TotalMilliseconds);
369+
if (exception == null)
301370
{
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);
303373
}
304-
if (exception == null)
374+
else
305375
{
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;
310383
}
311384
}
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
321386
{
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+
}
329391
}
330392
}
331393

@@ -447,4 +509,21 @@ struct Pair
447509
public UnityAction Action;
448510
}
449511
}
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+
}
450529
}

0 commit comments

Comments
 (0)