Skip to content
This repository has been archived by the owner on Feb 16, 2024. It is now read-only.

Commit

Permalink
fix testrunner
Browse files Browse the repository at this point in the history
  • Loading branch information
neuecc committed Jul 1, 2019
1 parent ce5e875 commit 0cb5009
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 71 deletions.
173 changes: 114 additions & 59 deletions Assets/RuntimeUnitTestToolkit/UnitTestRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace RuntimeUnitTestToolkit
public class UnitTestRunner : MonoBehaviour
{
// object is IEnumerator or Func<IEnumerator>
Dictionary<string, List<KeyValuePair<string, object>>> tests = new Dictionary<string, List<KeyValuePair<string, object>>>();
Dictionary<string, List<TestKeyValuePair>> tests = new Dictionary<string, List<TestKeyValuePair>>();

List<Pair> additionalActionsOnFirst = new List<Pair>();

Expand Down Expand Up @@ -174,28 +174,28 @@ static IEnumerable<Type> GetTestTargetTypes()
}
}

public void AddTest(string group, string title, Action test)
public void AddTest(string group, string title, Action test, List<Action> setups, List<Action> teardowns)
{
List<KeyValuePair<string, object>> list;
List<TestKeyValuePair> list;
if (!tests.TryGetValue(group, out list))
{
list = new List<KeyValuePair<string, object>>();
list = new List<TestKeyValuePair>();
tests[group] = list;
}

list.Add(new KeyValuePair<string, object>(title, test));
list.Add(new TestKeyValuePair(title, test, setups, teardowns));
}

public void AddAsyncTest(string group, string title, Func<IEnumerator> asyncTestCoroutine)
public void AddAsyncTest(string group, string title, Func<IEnumerator> asyncTestCoroutine, List<Action> setups, List<Action> teardowns)
{
List<KeyValuePair<string, object>> list;
List<TestKeyValuePair> list;
if (!tests.TryGetValue(group, out list))
{
list = new List<KeyValuePair<string, object>>();
list = new List<TestKeyValuePair>();
tests[group] = list;
}

list.Add(new KeyValuePair<string, object>(title, asyncTestCoroutine));
list.Add(new TestKeyValuePair(title, asyncTestCoroutine, setups, teardowns));
}

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

var methods = testType.GetMethods(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
List<Action> setups = new List<Action>();
List<Action> teardowns = new List<Action>();
foreach (var item in methods)
{
try
{
var setup = item.GetCustomAttribute<NUnit.Framework.SetUpAttribute>(true);
if (setup != null)
{
setups.Add((Action)Delegate.CreateDelegate(typeof(Action), test, item));
}
var teardown = item.GetCustomAttribute<NUnit.Framework.TearDownAttribute>(true);
if (teardown != null)
{
teardowns.Add((Action)Delegate.CreateDelegate(typeof(Action), test, item));
}
}
catch (Exception e)
{
UnityEngine.Debug.LogError(testType.Name + "." + item.Name + " failed to register setup/teardown method, exception: " + e.ToString());
}
}

foreach (var item in methods)
{
try
Expand All @@ -227,7 +250,7 @@ public void RegisterAllMethods(Type testType)
if (item.GetParameters().Length == 0 && item.ReturnType == typeof(IEnumerator))
{
var factory = (Func<IEnumerator>)Delegate.CreateDelegate(typeof(Func<IEnumerator>), test, item);
AddAsyncTest(factory.Target.GetType().Name, factory.Method.Name, factory);
AddAsyncTest(factory.Target.GetType().Name, factory.Method.Name, factory, setups, teardowns);
}
else
{
Expand All @@ -241,7 +264,7 @@ public void RegisterAllMethods(Type testType)
if (item.GetParameters().Length == 0 && item.ReturnType == typeof(void))
{
var invoke = (Action)Delegate.CreateDelegate(typeof(Action), test, item);
AddTest(invoke.Target.GetType().Name, invoke.Method.Name, invoke);
AddTest(invoke.Target.GetType().Name, invoke.Method.Name, invoke, setups, teardowns);
}
else
{
Expand All @@ -268,7 +291,7 @@ System.Collections.IEnumerator ScrollLogToEndNextFrame()
logScrollBar.value = 0;
}

IEnumerator RunTestInCoroutine(KeyValuePair<string, List<KeyValuePair<string, object>>> actionList)
IEnumerator RunTestInCoroutine(KeyValuePair<string, List<TestKeyValuePair>> actionList)
{
Button self = null;
foreach (var btn in list.GetComponentsInChildren<Button>())
Expand All @@ -290,66 +313,81 @@ IEnumerator RunTestInCoroutine(KeyValuePair<string, List<KeyValuePair<string, ob
var totalExecutionTime = new List<double>();
foreach (var item2 in actionList.Value)
{
// before start, cleanup
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

logText.text += "<color=teal>" + item2.Key + "</color>\n";
yield return null;

var v = item2.Value;

var methodStopwatch = System.Diagnostics.Stopwatch.StartNew();
Exception exception = null;
if (v is Action)
// setup
try
{
try
foreach (var setup in item2.Setups)
{
((Action)v).Invoke();
setup();
}
catch (Exception ex)

// before start, cleanup
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

logText.text += "<color=teal>" + item2.Key + "</color>\n";
yield return null;

var v = item2.Value;

var methodStopwatch = System.Diagnostics.Stopwatch.StartNew();
Exception exception = null;
if (v is Action)
{
exception = ex;
try
{
((Action)v).Invoke();
}
catch (Exception ex)
{
exception = ex;
}
}
}
else
{
var coroutineFactory = (Func<IEnumerator>)v;
IEnumerator coroutine = null;
try
else
{
coroutine = coroutineFactory();
var coroutineFactory = (Func<IEnumerator>)v;
IEnumerator coroutine = null;
try
{
coroutine = coroutineFactory();
}
catch (Exception ex)
{
exception = ex;
}
if (exception == null)
{
yield return StartCoroutine(UnwrapEnumerator(coroutine, ex =>
{
exception = ex;
}));
}
}
catch (Exception ex)
methodStopwatch.Stop();
totalExecutionTime.Add(methodStopwatch.Elapsed.TotalMilliseconds);
if (exception == null)
{
exception = ex;
logText.text += "OK, " + methodStopwatch.Elapsed.TotalMilliseconds.ToString("0.00") + "ms\n";
WriteToConsoleResult(item2.Key + ", " + methodStopwatch.Elapsed.TotalMilliseconds.ToString("0.00") + "ms", true);
}
if (exception == null)
else
{
yield return StartCoroutine(UnwrapEnumerator(coroutine, ex =>
{
exception = ex;
}));
// found match line...
var line = string.Join("\n", exception.StackTrace.Split('\n').Where(x => x.Contains(actionList.Key) || x.Contains(item2.Key)).ToArray());
logText.text += "<color=red>" + exception.Message + "\n" + line + "</color>\n";
WriteToConsoleResult(item2.Key + ", " + exception.Message, false);
WriteToConsole(line);
allGreen = false;
allTestGreen = false;
}
}

methodStopwatch.Stop();
totalExecutionTime.Add(methodStopwatch.Elapsed.TotalMilliseconds);
if (exception == null)
{
logText.text += "OK, " + methodStopwatch.Elapsed.TotalMilliseconds.ToString("0.00") + "ms\n";
WriteToConsoleResult(item2.Key + ", " + methodStopwatch.Elapsed.TotalMilliseconds.ToString("0.00") + "ms", true);
}
else
finally
{
// found match line...
var line = string.Join("\n", exception.StackTrace.Split('\n').Where(x => x.Contains(actionList.Key) || x.Contains(item2.Key)).ToArray());
logText.text += "<color=red>" + exception.Message + "\n" + line + "</color>\n";
WriteToConsoleResult(item2.Key + ", " + exception.Message, false);
WriteToConsole(line);
allGreen = false;
allTestGreen = false;
foreach (var teardown in item2.Teardowns)
{
teardown();
}
}
}

Expand Down Expand Up @@ -471,4 +509,21 @@ struct Pair
public UnityAction Action;
}
}

public class TestKeyValuePair
{
public string Key;
/// <summary>IEnumerator or Func[IEnumerator]</summary>
public object Value;
public List<Action> Setups;
public List<Action> Teardowns;

public TestKeyValuePair(string key, object value, List<Action> setups, List<Action> teardowns)
{
this.Key = key;
this.Value = value;
this.Setups = setups;
this.Teardowns = teardowns;
}
}
}
19 changes: 7 additions & 12 deletions Assets/Scripts/UnityTests/Rx/Observable.ConcurrencyTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public void Dispose()
[Test]
public void ObserveOnTest()
{
Init();

var xs = Observable.Range(1, 10)
.ObserveOn(Scheduler.ThreadPool)
.ToArrayWait();
Expand All @@ -49,15 +51,8 @@ public void ObserveOnTest()
[Test]
public void AmbTest()
{
var xs = Observable.Return(10).Delay(TimeSpan.FromSeconds(1)).Concat(Observable.Range(1, 3));

var xss = Observable.Return(10).Concat(Observable.Range(1, 3));
xss.ToArray().Wait();
xss.ToArray().Wait();
xss.ToArray().Wait();


var ys = Observable.Return(30).Delay(TimeSpan.FromSeconds(2)).Concat(Observable.Range(5, 3));
var xs = Observable.Return(10).Delay(TimeSpan.FromSeconds(1), Scheduler.ThreadPool).Concat(Observable.Range(1, 3));
var ys = Observable.Return(30).Delay(TimeSpan.FromSeconds(2), Scheduler.ThreadPool).Concat(Observable.Range(5, 3));

// win left
var result = xs.Amb(ys).ToArray().Wait();
Expand All @@ -79,9 +74,9 @@ public void AmbTest()
[Test]
public void AmbMultiTest()
{
var xs = Observable.Return(10).Delay(TimeSpan.FromSeconds(5)).Concat(Observable.Range(1, 3));
var ys = Observable.Return(30).Delay(TimeSpan.FromSeconds(1)).Concat(Observable.Range(5, 3));
var zs = Observable.Return(50).Delay(TimeSpan.FromSeconds(3)).Concat(Observable.Range(9, 3));
var xs = Observable.Return(10).Delay(TimeSpan.FromSeconds(5), Scheduler.ThreadPool).Concat(Observable.Range(1, 3));
var ys = Observable.Return(30).Delay(TimeSpan.FromSeconds(1), Scheduler.ThreadPool).Concat(Observable.Range(5, 3));
var zs = Observable.Return(50).Delay(TimeSpan.FromSeconds(3), Scheduler.ThreadPool).Concat(Observable.Range(9, 3));

// win center
var result = Observable.Amb(xs, ys, zs).ToArray().Wait();
Expand Down

0 comments on commit 0cb5009

Please sign in to comment.