Skip to content

Instantly share code, notes, and snippets.

@xiaobin83
Last active December 29, 2016 21:53
Show Gist options
  • Save xiaobin83/c795c94ddc6f461854ac6faaa027cf21 to your computer and use it in GitHub Desktop.
Save xiaobin83/c795c94ddc6f461854ac6faaa027cf21 to your computer and use it in GitHub Desktop.
copy & paste NUnit test code and run it on device
using UnityEngine;
using System.Linq;
using System;
using System.Reflection;
using System.Collections.Generic;
namespace playingtest
{
public class TestAttribute : Attribute
{
}
public class TestFixtureSetUpAttribute: Attribute
{
}
public class TestFixtureTearDownAttribute : Attribute
{
}
public class ExpectedExceptionAttribute : Attribute
{
Type expectedExceptionType;
public ExpectedExceptionAttribute(Type exceptionType)
{
expectedExceptionType = exceptionType;
}
public bool IsExpected(Exception e)
{
return e.GetType() == expectedExceptionType;
}
}
public class AssertionException : Exception
{
public AssertionException(string message)
: base(message)
{
}
public AssertionException(string message, Exception inner)
: base(message, inner)
{
}
}
public class Assert
{
public static void True(bool condition)
{
if (!condition)
{
throw new AssertionException("Expected True, but failed.");
}
}
static string ToString(object value)
{
if (value != null)
{
return value.ToString();
}
return "null";
}
public static void AreEqual(object expected, object actual)
{
if (expected == actual) return;
var expectedType = expected.GetType();
var actualType = actual.GetType();
if (expectedType == typeof(Int16)
|| expectedType == typeof(Int32)
|| expectedType == typeof(Int64))
{
if (actualType == typeof(Int16)
|| actualType == typeof(Int32)
|| actualType == typeof(Int64))
{
if (expected == actual)
return;
}
}
else if(expectedType == typeof(Single)
|| expectedType == typeof(Double))
{
if (actualType == typeof(Single)
|| actualType == typeof(Double))
{
if ((double)expected == (double)actual)
return;
}
}
object convertedActual = null;
try
{
convertedActual = Convert.ChangeType(actual, expected.GetType());
}
catch (Exception e)
{
throw new AssertionException(
"Incorrect type conversion between object being compared.", e);
}
if (!expected.Equals(convertedActual))
{
throw new AssertionException(
string.Format("Expected {0}, but {1} got.", ToString(expected), ToString(actual)));
}
}
public static void Fail(string message)
{
throw new AssertionException(message);
}
}
public class PlayingTest : MonoBehaviour
{
class Context
{
Type targetType;
List<MethodInfo> testMethods;
public Context(Type targetType, List<MethodInfo> testMethods)
{
this.targetType = targetType;
this.testMethods = testMethods;
}
public List<Exception> failedTests { get; private set; }
public int testCount
{
get
{
if (testMethods != null)
{
return testMethods.Count(m => m.GetCustomAttributes(typeof(TestAttribute), false).Length > 0);
}
return 0;
}
}
public int passedCount { get; private set; }
public void Run()
{
failedTests = new List<Exception>();
passedCount = 0;
var testObject = Activator.CreateInstance(targetType);
var setUps = testMethods.Where(m => m.GetCustomAttributes(typeof(TestFixtureSetUpAttribute), false).Length > 0).ToArray();
if (setUps.Length > 0)
{
if (setUps.Length > 1)
{
Debug.LogWarning("Found more than one SetUp function!");
}
var setUp = setUps[0];
try
{
setUp.Invoke(testObject, null); // invoke it
}
catch (Exception e)
{
failedTests.Add(new Exception("Failed in SetUp", e));
return;
}
}
var tests = testMethods.Where(m => m.GetCustomAttributes(typeof(TestAttribute), false).Length > 0);
foreach (var test in tests)
{
try
{
test.Invoke(testObject, null);
passedCount = passedCount + 1;
}
catch (Exception e)
{
bool isExpected = false;
var expectedExpcetions = test.GetCustomAttributes(typeof(ExpectedExceptionAttribute), false);
if (expectedExpcetions.Length > 0)
{
foreach (var expected in expectedExpcetions)
{
var attr = (ExpectedExceptionAttribute)expected;
if (attr.IsExpected(e.InnerException))
{
passedCount = passedCount + 1;
isExpected = true;
}
}
}
if (!isExpected)
failedTests.Add(e.InnerException);
}
}
var tearDowns = testMethods.Where(m => m.GetCustomAttributes(typeof(TestFixtureTearDownAttribute), false).Length > 0).ToArray();
if (tearDowns.Length > 0)
{
if (tearDowns.Length > 1)
{
Debug.LogWarning("Found more than one TearDown function!");
}
var tearDown = tearDowns[0];
try
{
tearDown.Invoke(testObject, null); // invoke it
}
catch (Exception e)
{
failedTests.Add(new Exception("Failed in TearDown", e));
passedCount = passedCount - 1; // failed in teardown
}
}
}
}
void Start()
{
var allTests = Assembly.Load("Assembly-CSharp").GetTypes()
.Union(Assembly.Load("Assembly-CSharp-firstpass").GetTypes())
.SelectMany(t => t.GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
.Where(m => m.GetCustomAttributes(typeof(TestFixtureSetUpAttribute), false).Length > 0
|| m.GetCustomAttributes(typeof(TestFixtureTearDownAttribute), false).Length > 0
|| m.GetCustomAttributes(typeof(TestAttribute), false).Length > 0)
.GroupBy(m => m.DeclaringType)
.ToDictionary(grp => grp.Key, grp => grp.ToList())
.Select(kv => new Context(kv.Key, kv.Value)).ToArray();
foreach (var test in allTests)
{
test.Run();
}
var passedTestCount = allTests.Sum(t => t.passedCount);
var totalTestCount = allTests.Sum(t => t.testCount);
if (passedTestCount < totalTestCount)
{
var sb = new System.Text.StringBuilder();
sb.AppendFormat("PlayingTest {0}/{1} Passed:\n", passedTestCount, totalTestCount);
var allFailedExpections = allTests.SelectMany(context => context.failedTests);
foreach (var e in allFailedExpections)
{
sb.AppendLine("---");
sb.AppendLine(e.Message);
sb.AppendLine(e.StackTrace);
}
Debug.LogError(sb);
}
else
{
Debug.Log("PlayingTest All Passed!");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment