Commit af571a61 authored by BlackAngle233's avatar BlackAngle233
Browse files

212

parent 1d9b5391
using System.Collections; using System.Collections;
using NUnit.Framework.Interfaces; using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal; using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Commands; using NUnit.Framework.Internal.Commands;
namespace UnityEngine.TestRunner.NUnitExtensions.Runner namespace UnityEngine.TestRunner.NUnitExtensions.Runner
{ {
internal class FailCommand : TestCommand, IEnumerableTestMethodCommand internal class FailCommand : TestCommand, IEnumerableTestMethodCommand
{ {
private ResultState m_ResultState; private ResultState m_ResultState;
private string m_Message; private string m_Message;
public FailCommand(Test test, ResultState resultState, string message) public FailCommand(Test test, ResultState resultState, string message)
: base(test) : base(test)
{ {
m_ResultState = resultState; m_ResultState = resultState;
m_Message = message; m_Message = message;
} }
public override TestResult Execute(ITestExecutionContext context) public override TestResult Execute(ITestExecutionContext context)
{ {
context.CurrentResult.SetResult(m_ResultState, m_Message); context.CurrentResult.SetResult(m_ResultState, m_Message);
return context.CurrentResult; return context.CurrentResult;
} }
public IEnumerable ExecuteEnumerable(ITestExecutionContext context) public IEnumerable ExecuteEnumerable(ITestExecutionContext context)
{ {
context.CurrentResult.SetResult(m_ResultState, m_Message); context.CurrentResult.SetResult(m_ResultState, m_Message);
yield return null; yield return null;
} }
} }
} }
\ No newline at end of file
fileFormatVersion: 2 fileFormatVersion: 2
guid: 68e5dc8bfd5d72647a93b7f2e1da831a guid: 68e5dc8bfd5d72647a93b7f2e1da831a
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName: assetBundleName:
assetBundleVariant: assetBundleVariant:
using System.Collections; using System.Collections;
using NUnit.Framework.Internal; using NUnit.Framework.Internal;
namespace UnityEngine.TestRunner.NUnitExtensions.Runner namespace UnityEngine.TestRunner.NUnitExtensions.Runner
{ {
internal interface IEnumerableTestMethodCommand internal interface IEnumerableTestMethodCommand
{ {
IEnumerable ExecuteEnumerable(ITestExecutionContext context); IEnumerable ExecuteEnumerable(ITestExecutionContext context);
} }
} }
fileFormatVersion: 2 fileFormatVersion: 2
guid: dbd43d8a3b8122d4e89b055f53382b11 guid: dbd43d8a3b8122d4e89b055f53382b11
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName: assetBundleName:
assetBundleVariant: assetBundleVariant:
using NUnit.Framework.Interfaces; using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal; using NUnit.Framework.Internal;
namespace UnityEngine.TestRunner.NUnitExtensions.Runner namespace UnityEngine.TestRunner.NUnitExtensions.Runner
{ {
internal class PlaymodeWorkItemFactory : WorkItemFactory internal class PlaymodeWorkItemFactory : WorkItemFactory
{ {
protected override UnityWorkItem Create(TestMethod method, ITestFilter filter, ITest loadedTest) protected override UnityWorkItem Create(TestMethod method, ITestFilter filter, ITest loadedTest)
{ {
return new CoroutineTestWorkItem(method, filter); return new CoroutineTestWorkItem(method, filter);
} }
} }
} }
fileFormatVersion: 2 fileFormatVersion: 2
guid: 7ef6801a8b664544aa9f2ab1bc1f8b60 guid: 7ef6801a8b664544aa9f2ab1bc1f8b60
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName: assetBundleName:
assetBundleVariant: assetBundleVariant:
namespace UnityEngine.TestRunner.NUnitExtensions.Runner namespace UnityEngine.TestRunner.NUnitExtensions.Runner
{ {
internal class RestoreTestContextAfterDomainReload {} internal class RestoreTestContextAfterDomainReload {}
} }
fileFormatVersion: 2 fileFormatVersion: 2
guid: 26721f9940339264fb14bdbfe1290e21 guid: 26721f9940339264fb14bdbfe1290e21
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName: assetBundleName:
assetBundleVariant: assetBundleVariant:
using System; using System;
using System.Collections; using System.Collections;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.Interfaces; using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal; using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Commands; using NUnit.Framework.Internal.Commands;
using UnityEngine.TestTools; using UnityEngine.TestTools;
namespace UnityEngine.TestRunner.NUnitExtensions.Runner namespace UnityEngine.TestRunner.NUnitExtensions.Runner
{ {
internal static class TestCommandBuilder internal static class TestCommandBuilder
{ {
public static TestCommand BuildTestCommand(TestMethod test, ITestFilter filter) public static TestCommand BuildTestCommand(TestMethod test, ITestFilter filter)
{ {
if (test.RunState != RunState.Runnable && if (test.RunState != RunState.Runnable &&
!(test.RunState == RunState.Explicit && filter.IsExplicitMatch(test))) !(test.RunState == RunState.Explicit && filter.IsExplicitMatch(test)))
{ {
return new SkipCommand(test); return new SkipCommand(test);
} }
var testReturnsIEnumerator = test.Method.ReturnType.Type == typeof(IEnumerator); var testReturnsIEnumerator = test.Method.ReturnType.Type == typeof(IEnumerator);
TestCommand command; TestCommand command;
if (!testReturnsIEnumerator) if (!testReturnsIEnumerator)
{ {
command = new TestMethodCommand(test); command = new TestMethodCommand(test);
} }
else else
{ {
command = new EnumerableTestMethodCommand(test); command = new EnumerableTestMethodCommand(test);
} }
command = new UnityLogCheckDelegatingCommand(command); command = new UnityLogCheckDelegatingCommand(command);
foreach (var wrapper in test.Method.GetCustomAttributes<IWrapTestMethod>(true)) foreach (var wrapper in test.Method.GetCustomAttributes<IWrapTestMethod>(true))
{ {
command = wrapper.Wrap(command); command = wrapper.Wrap(command);
if (command == null) if (command == null)
{ {
var message = String.Format("IWrapTestMethod implementation '{0}' returned null as command.", var message = String.Format("IWrapTestMethod implementation '{0}' returned null as command.",
wrapper.GetType().FullName); wrapper.GetType().FullName);
return new FailCommand(test, ResultState.Failure, message); return new FailCommand(test, ResultState.Failure, message);
} }
if (testReturnsIEnumerator && !(command is IEnumerableTestMethodCommand)) if (testReturnsIEnumerator && !(command is IEnumerableTestMethodCommand))
{ {
command = TryReplaceWithEnumerableCommand(command); command = TryReplaceWithEnumerableCommand(command);
if (command != null) if (command != null)
{ {
continue; continue;
} }
var message = String.Format("'{0}' is not supported on {1} as it does not handle returning IEnumerator.", var message = String.Format("'{0}' is not supported on {1} as it does not handle returning IEnumerator.",
wrapper.GetType().FullName, wrapper.GetType().FullName,
GetTestBuilderName(test)); GetTestBuilderName(test));
return new FailCommand(test, ResultState.Failure, message); return new FailCommand(test, ResultState.Failure, message);
} }
} }
command = new UnityEngine.TestTools.TestActionCommand(command); command = new UnityEngine.TestTools.TestActionCommand(command);
command = new UnityEngine.TestTools.SetUpTearDownCommand(command); command = new UnityEngine.TestTools.SetUpTearDownCommand(command);
if (!testReturnsIEnumerator) if (!testReturnsIEnumerator)
{ {
command = new ImmediateEnumerableCommand(command); command = new ImmediateEnumerableCommand(command);
} }
foreach (var wrapper in test.Method.GetCustomAttributes<IWrapSetUpTearDown>(true)) foreach (var wrapper in test.Method.GetCustomAttributes<IWrapSetUpTearDown>(true))
{ {
command = wrapper.Wrap(command); command = wrapper.Wrap(command);
if (command == null) if (command == null)
{ {
var message = String.Format("IWrapSetUpTearDown implementation '{0}' returned null as command.", var message = String.Format("IWrapSetUpTearDown implementation '{0}' returned null as command.",
wrapper.GetType().FullName); wrapper.GetType().FullName);
return new FailCommand(test, ResultState.Failure, message); return new FailCommand(test, ResultState.Failure, message);
} }
if (testReturnsIEnumerator && !(command is IEnumerableTestMethodCommand)) if (testReturnsIEnumerator && !(command is IEnumerableTestMethodCommand))
{ {
command = TryReplaceWithEnumerableCommand(command); command = TryReplaceWithEnumerableCommand(command);
if (command != null) if (command != null)
{ {
continue; continue;
} }
var message = String.Format("'{0}' is not supported on {1} as it does not handle returning IEnumerator.", var message = String.Format("'{0}' is not supported on {1} as it does not handle returning IEnumerator.",
wrapper.GetType().FullName, wrapper.GetType().FullName,
GetTestBuilderName(test)); GetTestBuilderName(test));
return new FailCommand(test, ResultState.Failure, message); return new FailCommand(test, ResultState.Failure, message);
} }
} }
command = new EnumerableSetUpTearDownCommand(command); command = new EnumerableSetUpTearDownCommand(command);
command = new OuterUnityTestActionCommand(command); command = new OuterUnityTestActionCommand(command);
IApplyToContext[] changes = test.Method.GetCustomAttributes<IApplyToContext>(true); IApplyToContext[] changes = test.Method.GetCustomAttributes<IApplyToContext>(true);
if (changes.Length > 0) if (changes.Length > 0)
{ {
command = new EnumerableApplyChangesToContextCommand(command, changes); command = new EnumerableApplyChangesToContextCommand(command, changes);
} }
return command; return command;
} }
private static string GetTestBuilderName(TestMethod testMethod) private static string GetTestBuilderName(TestMethod testMethod)
{ {
return new[] return new[]
{ {
testMethod.Method.GetCustomAttributes<ITestBuilder>(true).Select(attribute => attribute.GetType().Name), testMethod.Method.GetCustomAttributes<ITestBuilder>(true).Select(attribute => attribute.GetType().Name),
testMethod.Method.GetCustomAttributes<ISimpleTestBuilder>(true).Select(attribute => attribute.GetType().Name) testMethod.Method.GetCustomAttributes<ISimpleTestBuilder>(true).Select(attribute => attribute.GetType().Name)
}.SelectMany(v => v).FirstOrDefault(); }.SelectMany(v => v).FirstOrDefault();
} }
private static TestCommand TryReplaceWithEnumerableCommand(TestCommand command) private static TestCommand TryReplaceWithEnumerableCommand(TestCommand command)
{ {
switch (command.GetType().Name) switch (command.GetType().Name)
{ {
case nameof(RepeatAttribute.RepeatedTestCommand): case nameof(RepeatAttribute.RepeatedTestCommand):
return new EnumerableRepeatedTestCommand(command as RepeatAttribute.RepeatedTestCommand); return new EnumerableRepeatedTestCommand(command as RepeatAttribute.RepeatedTestCommand);
case nameof(RetryAttribute.RetryCommand): case nameof(RetryAttribute.RetryCommand):
return new EnumerableRetryTestCommand(command as RetryAttribute.RetryCommand); return new EnumerableRetryTestCommand(command as RetryAttribute.RetryCommand);
default: default:
return null; return null;
} }
} }
} }
} }
\ No newline at end of file
fileFormatVersion: 2 fileFormatVersion: 2
guid: f40df9c8cf926b241b093a37028d8815 guid: f40df9c8cf926b241b093a37028d8815
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName: assetBundleName:
assetBundleVariant: assetBundleVariant:
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using NUnit.Framework.Internal; using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Commands; using NUnit.Framework.Internal.Commands;
using UnityEngine.TestTools; using UnityEngine.TestTools;
using UnityEngine.TestTools.Logging; using UnityEngine.TestTools.Logging;
using UnityEngine.TestTools.TestRunner; using UnityEngine.TestTools.TestRunner;
namespace UnityEngine.TestRunner.NUnitExtensions.Runner namespace UnityEngine.TestRunner.NUnitExtensions.Runner
{ {
class UnityLogCheckDelegatingCommand : DelegatingTestCommand, IEnumerableTestMethodCommand class UnityLogCheckDelegatingCommand : DelegatingTestCommand, IEnumerableTestMethodCommand
{ {
static Dictionary<object, bool?> s_AttributeCache = new Dictionary<object, bool?>(); static Dictionary<object, bool?> s_AttributeCache = new Dictionary<object, bool?>();
public UnityLogCheckDelegatingCommand(TestCommand innerCommand) public UnityLogCheckDelegatingCommand(TestCommand innerCommand)
: base(innerCommand) {} : base(innerCommand) {}
public override TestResult Execute(ITestExecutionContext context) public override TestResult Execute(ITestExecutionContext context)
{ {
using (var logScope = new LogScope()) using (var logScope = new LogScope())
{ {
if (ExecuteAndCheckLog(logScope, context.CurrentResult, () => innerCommand.Execute(context))) if (ExecuteAndCheckLog(logScope, context.CurrentResult, () => innerCommand.Execute(context)))
PostTestValidation(logScope, innerCommand, context.CurrentResult); PostTestValidation(logScope, innerCommand, context.CurrentResult);
} }
return context.CurrentResult; return context.CurrentResult;
} }
public IEnumerable ExecuteEnumerable(ITestExecutionContext context) public IEnumerable ExecuteEnumerable(ITestExecutionContext context)
{ {
if (!(innerCommand is IEnumerableTestMethodCommand enumerableTestMethodCommand)) if (!(innerCommand is IEnumerableTestMethodCommand enumerableTestMethodCommand))
{ {
Execute(context); Execute(context);
yield break; yield break;
} }
using (var logScope = new LogScope()) using (var logScope = new LogScope())
{ {
IEnumerable executeEnumerable = null; IEnumerable executeEnumerable = null;
if (!ExecuteAndCheckLog(logScope, context.CurrentResult, if (!ExecuteAndCheckLog(logScope, context.CurrentResult,
() => executeEnumerable = enumerableTestMethodCommand.ExecuteEnumerable(context))) () => executeEnumerable = enumerableTestMethodCommand.ExecuteEnumerable(context)))
yield break; yield break;
foreach (var step in executeEnumerable) foreach (var step in executeEnumerable)
{ {
// do not check expected logs here - we want to permit expecting and receiving messages to run // do not check expected logs here - we want to permit expecting and receiving messages to run
// across frames. (but we do always want to catch a fail immediately.) // across frames. (but we do always want to catch a fail immediately.)
if (!CheckFailingLogs(logScope, context.CurrentResult)) if (!CheckFailingLogs(logScope, context.CurrentResult))
yield break; yield break;
yield return step; yield return step;
} }
if (!CheckLogs(context.CurrentResult, logScope)) if (!CheckLogs(context.CurrentResult, logScope))
yield break; yield break;
PostTestValidation(logScope, innerCommand, context.CurrentResult); PostTestValidation(logScope, innerCommand, context.CurrentResult);
} }
} }
static bool CaptureException(TestResult result, Action action) static bool CaptureException(TestResult result, Action action)
{ {
try try
{ {
action(); action();
return true; return true;
} }
catch (Exception e) catch (Exception e)
{ {
result.RecordException(e); result.RecordException(e);
return false; return false;
} }
} }
static bool ExecuteAndCheckLog(LogScope logScope, TestResult result, Action action) static bool ExecuteAndCheckLog(LogScope logScope, TestResult result, Action action)
=> CaptureException(result, action) && CheckLogs(result, logScope); => CaptureException(result, action) && CheckLogs(result, logScope);
static void PostTestValidation(LogScope logScope, TestCommand command, TestResult result) static void PostTestValidation(LogScope logScope, TestCommand command, TestResult result)
{ {
if (MustExpect(command.Test.Method.MethodInfo)) if (MustExpect(command.Test.Method.MethodInfo))
CaptureException(result, logScope.NoUnexpectedReceived); CaptureException(result, logScope.NoUnexpectedReceived);
} }
static bool CheckLogs(TestResult result, LogScope logScope) static bool CheckLogs(TestResult result, LogScope logScope)
=> CheckFailingLogs(logScope, result) && CheckExpectedLogs(logScope, result); => CheckFailingLogs(logScope, result) && CheckExpectedLogs(logScope, result);
static bool CheckFailingLogs(LogScope logScope, TestResult result) static bool CheckFailingLogs(LogScope logScope, TestResult result)
{ {
if (!logScope.AnyFailingLogs()) if (!logScope.AnyFailingLogs())
return true; return true;
var failingLog = logScope.FailingLogs.First(); var failingLog = logScope.FailingLogs.First();
result.RecordException(new UnhandledLogMessageException(failingLog)); result.RecordException(new UnhandledLogMessageException(failingLog));
return false; return false;
} }
static bool CheckExpectedLogs(LogScope logScope, TestResult result) static bool CheckExpectedLogs(LogScope logScope, TestResult result)
{ {
if (!logScope.ExpectedLogs.Any()) if (!logScope.ExpectedLogs.Any())
return true; return true;
var expectedLog = logScope.ExpectedLogs.Peek(); var expectedLog = logScope.ExpectedLogs.Peek();
result.RecordException(new UnexpectedLogMessageException(expectedLog)); result.RecordException(new UnexpectedLogMessageException(expectedLog));
return false; return false;
} }
static bool MustExpect(MemberInfo method) static bool MustExpect(MemberInfo method)
{ {
// method // method
var methodAttr = method.GetCustomAttributes<TestMustExpectAllLogsAttribute>(true).FirstOrDefault(); var methodAttr = method.GetCustomAttributes<TestMustExpectAllLogsAttribute>(true).FirstOrDefault();
if (methodAttr != null) if (methodAttr != null)
return methodAttr.MustExpect; return methodAttr.MustExpect;
// fixture // fixture
var fixture = method.DeclaringType; var fixture = method.DeclaringType;
if (!s_AttributeCache.TryGetValue(fixture, out var mustExpect)) if (!s_AttributeCache.TryGetValue(fixture, out var mustExpect))
{ {
var fixtureAttr = fixture.GetCustomAttributes<TestMustExpectAllLogsAttribute>(true).FirstOrDefault(); var fixtureAttr = fixture.GetCustomAttributes<TestMustExpectAllLogsAttribute>(true).FirstOrDefault();
mustExpect = s_AttributeCache[fixture] = fixtureAttr?.MustExpect; mustExpect = s_AttributeCache[fixture] = fixtureAttr?.MustExpect;
} }
if (mustExpect != null) if (mustExpect != null)
return mustExpect.Value; return mustExpect.Value;
// assembly // assembly
var assembly = fixture.Assembly; var assembly = fixture.Assembly;
if (!s_AttributeCache.TryGetValue(assembly, out mustExpect)) if (!s_AttributeCache.TryGetValue(assembly, out mustExpect))
{ {
var assemblyAttr = assembly.GetCustomAttributes<TestMustExpectAllLogsAttribute>().FirstOrDefault(); var assemblyAttr = assembly.GetCustomAttributes<TestMustExpectAllLogsAttribute>().FirstOrDefault();
mustExpect = s_AttributeCache[assembly] = assemblyAttr?.MustExpect; mustExpect = s_AttributeCache[assembly] = assemblyAttr?.MustExpect;
} }
return mustExpect == true; return mustExpect == true;
} }
} }
} }
fileFormatVersion: 2 fileFormatVersion: 2
guid: 48230e4e90fb4d14a9d56bddea898413 guid: 48230e4e90fb4d14a9d56bddea898413
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName: assetBundleName:
assetBundleVariant: assetBundleVariant:
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using NUnit; using NUnit;
using NUnit.Framework.Interfaces; using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal; using NUnit.Framework.Internal;
using UnityEngine.TestTools; using UnityEngine.TestTools;
using UnityEngine.TestTools.NUnitExtensions; using UnityEngine.TestTools.NUnitExtensions;
namespace UnityEngine.TestRunner.NUnitExtensions.Runner namespace UnityEngine.TestRunner.NUnitExtensions.Runner
{ {
internal interface IUnityTestAssemblyRunner internal interface IUnityTestAssemblyRunner
{ {
ITest LoadedTest { get; } ITest LoadedTest { get; }
ITestResult Result { get; } ITestResult Result { get; }
bool IsTestLoaded { get; } bool IsTestLoaded { get; }
bool IsTestRunning { get; } bool IsTestRunning { get; }
bool IsTestComplete { get; } bool IsTestComplete { get; }
UnityWorkItem TopLevelWorkItem { get; set; } UnityWorkItem TopLevelWorkItem { get; set; }
UnityTestExecutionContext GetCurrentContext(); UnityTestExecutionContext GetCurrentContext();
ITest Load(Assembly[] assemblies, TestPlatform testPlatform, IDictionary<string, object> settings); ITest Load(Assembly[] assemblies, TestPlatform testPlatform, IDictionary<string, object> settings);
IEnumerable Run(ITestListener listener, ITestFilter filter); IEnumerable Run(ITestListener listener, ITestFilter filter);
void StopRun(); void StopRun();
} }
internal class UnityTestAssemblyRunner : IUnityTestAssemblyRunner internal class UnityTestAssemblyRunner : IUnityTestAssemblyRunner
{ {
private readonly UnityTestAssemblyBuilder unityBuilder; private readonly UnityTestAssemblyBuilder unityBuilder;
private readonly WorkItemFactory m_Factory; private readonly WorkItemFactory m_Factory;
protected UnityTestExecutionContext Context { get; set; } protected UnityTestExecutionContext Context { get; set; }
public UnityTestExecutionContext GetCurrentContext() public UnityTestExecutionContext GetCurrentContext()
{ {
return UnityTestExecutionContext.CurrentContext; return UnityTestExecutionContext.CurrentContext;
} }
protected IDictionary<string, object> Settings { get; set; } protected IDictionary<string, object> Settings { get; set; }
public ITest LoadedTest { get; protected set; } public ITest LoadedTest { get; protected set; }
public ITestResult Result public ITestResult Result
{ {
get { return TopLevelWorkItem == null ? null : TopLevelWorkItem.Result; } get { return TopLevelWorkItem == null ? null : TopLevelWorkItem.Result; }
} }
public bool IsTestLoaded public bool IsTestLoaded
{ {
get { return LoadedTest != null; } get { return LoadedTest != null; }
} }
public bool IsTestRunning public bool IsTestRunning
{ {
get { return TopLevelWorkItem != null && TopLevelWorkItem.State == NUnit.Framework.Internal.Execution.WorkItemState.Running; } get { return TopLevelWorkItem != null && TopLevelWorkItem.State == NUnit.Framework.Internal.Execution.WorkItemState.Running; }
} }
public bool IsTestComplete public bool IsTestComplete
{ {
get { return TopLevelWorkItem != null && TopLevelWorkItem.State == NUnit.Framework.Internal.Execution.WorkItemState.Complete; } get { return TopLevelWorkItem != null && TopLevelWorkItem.State == NUnit.Framework.Internal.Execution.WorkItemState.Complete; }
} }
public UnityTestAssemblyRunner(UnityTestAssemblyBuilder builder, WorkItemFactory factory) public UnityTestAssemblyRunner(UnityTestAssemblyBuilder builder, WorkItemFactory factory)
{ {
unityBuilder = builder; unityBuilder = builder;
m_Factory = factory; m_Factory = factory;
Context = new UnityTestExecutionContext(); Context = new UnityTestExecutionContext();
} }
public ITest Load(Assembly[] assemblies, TestPlatform testPlatform, IDictionary<string, object> settings) public ITest Load(Assembly[] assemblies, TestPlatform testPlatform, IDictionary<string, object> settings)
{ {
Settings = settings; Settings = settings;
if (settings.ContainsKey(FrameworkPackageSettings.RandomSeed)) if (settings.ContainsKey(FrameworkPackageSettings.RandomSeed))
Randomizer.InitialSeed = (int)settings[FrameworkPackageSettings.RandomSeed]; Randomizer.InitialSeed = (int)settings[FrameworkPackageSettings.RandomSeed];
return LoadedTest = unityBuilder.Build(assemblies, Enumerable.Repeat(testPlatform, assemblies.Length).ToArray(), settings); return LoadedTest = unityBuilder.Build(assemblies, Enumerable.Repeat(testPlatform, assemblies.Length).ToArray(), settings);
} }
public IEnumerable Run(ITestListener listener, ITestFilter filter) public IEnumerable Run(ITestListener listener, ITestFilter filter)
{ {
TopLevelWorkItem = m_Factory.Create(LoadedTest, filter); TopLevelWorkItem = m_Factory.Create(LoadedTest, filter);
TopLevelWorkItem.InitializeContext(Context); TopLevelWorkItem.InitializeContext(Context);
UnityTestExecutionContext.CurrentContext = Context; UnityTestExecutionContext.CurrentContext = Context;
Context.Listener = listener; Context.Listener = listener;
return TopLevelWorkItem.Execute(); return TopLevelWorkItem.Execute();
} }
public UnityWorkItem TopLevelWorkItem { get; set; } public UnityWorkItem TopLevelWorkItem { get; set; }
public void StopRun() public void StopRun()
{ {
if (IsTestRunning) if (IsTestRunning)
{ {
TopLevelWorkItem.Cancel(false); TopLevelWorkItem.Cancel(false);
} }
} }
} }
} }
fileFormatVersion: 2 fileFormatVersion: 2
guid: 874e40a588dbb1e48bc128d686337d4e guid: 874e40a588dbb1e48bc128d686337d4e
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName: assetBundleName:
assetBundleVariant: assetBundleVariant:
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.Constraints; using NUnit.Framework.Constraints;
using NUnit.Framework.Interfaces; using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal; using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Execution; using NUnit.Framework.Internal.Execution;
using UnityEngine.TestTools; using UnityEngine.TestTools;
namespace UnityEngine.TestRunner.NUnitExtensions.Runner namespace UnityEngine.TestRunner.NUnitExtensions.Runner
{ {
internal class UnityTestExecutionContext : ITestExecutionContext internal class UnityTestExecutionContext : ITestExecutionContext
{ {
private readonly UnityTestExecutionContext _priorContext; private readonly UnityTestExecutionContext _priorContext;
private TestResult _currentResult; private TestResult _currentResult;
private int _assertCount; private int _assertCount;
public static UnityTestExecutionContext CurrentContext { get; set; } public static UnityTestExecutionContext CurrentContext { get; set; }
public UnityTestExecutionContext Context { get; private set; } public UnityTestExecutionContext Context { get; private set; }
public Test CurrentTest { get; set; } public Test CurrentTest { get; set; }
public DateTime StartTime { get; set; } public DateTime StartTime { get; set; }
public long StartTicks { get; set; } public long StartTicks { get; set; }
public TestResult CurrentResult public TestResult CurrentResult
{ {
get { return _currentResult; } get { return _currentResult; }
set set
{ {
_currentResult = value; _currentResult = value;
if (value != null) if (value != null)
OutWriter = value.OutWriter; OutWriter = value.OutWriter;
} }
} }
public object TestObject { get; set; } public object TestObject { get; set; }
public string WorkDirectory { get; set; } public string WorkDirectory { get; set; }
private TestExecutionStatus _executionStatus; private TestExecutionStatus _executionStatus;
public TestExecutionStatus ExecutionStatus public TestExecutionStatus ExecutionStatus
{ {
get get
{ {
// ExecutionStatus may have been set to StopRequested or AbortRequested // ExecutionStatus may have been set to StopRequested or AbortRequested
// in a prior context. If so, reflect the same setting in this context. // in a prior context. If so, reflect the same setting in this context.
if (_executionStatus == TestExecutionStatus.Running && _priorContext != null) if (_executionStatus == TestExecutionStatus.Running && _priorContext != null)
_executionStatus = _priorContext.ExecutionStatus; _executionStatus = _priorContext.ExecutionStatus;
return _executionStatus; return _executionStatus;
} }
set set
{ {
_executionStatus = value; _executionStatus = value;
// Push the same setting up to all prior contexts // Push the same setting up to all prior contexts
if (_priorContext != null) if (_priorContext != null)
_priorContext.ExecutionStatus = value; _priorContext.ExecutionStatus = value;
} }
} }
public List<ITestAction> UpstreamActions { get; private set; } public List<ITestAction> UpstreamActions { get; private set; }
public int TestCaseTimeout { get; set; } public int TestCaseTimeout { get; set; }
public CultureInfo CurrentCulture { get; set; } public CultureInfo CurrentCulture { get; set; }
public CultureInfo CurrentUICulture { get; set; } public CultureInfo CurrentUICulture { get; set; }
public ITestListener Listener { get; set; } public ITestListener Listener { get; set; }
public UnityTestExecutionContext() public UnityTestExecutionContext()
{ {
UpstreamActions = new List<ITestAction>(); UpstreamActions = new List<ITestAction>();
CurrentContext = this; CurrentContext = this;
} }
public UnityTestExecutionContext(UnityTestExecutionContext other) public UnityTestExecutionContext(UnityTestExecutionContext other)
{ {
_priorContext = other; _priorContext = other;
CurrentTest = other.CurrentTest; CurrentTest = other.CurrentTest;
CurrentResult = other.CurrentResult; CurrentResult = other.CurrentResult;
TestObject = other.TestObject; TestObject = other.TestObject;
WorkDirectory = other.WorkDirectory; WorkDirectory = other.WorkDirectory;
Listener = other.Listener; Listener = other.Listener;
TestCaseTimeout = other.TestCaseTimeout; TestCaseTimeout = other.TestCaseTimeout;
UpstreamActions = new List<ITestAction>(other.UpstreamActions); UpstreamActions = new List<ITestAction>(other.UpstreamActions);
SetUpTearDownState = other.SetUpTearDownState; SetUpTearDownState = other.SetUpTearDownState;
OuterUnityTestActionState = other.OuterUnityTestActionState; OuterUnityTestActionState = other.OuterUnityTestActionState;
TestContext.CurrentTestExecutionContext = this; TestContext.CurrentTestExecutionContext = this;
CurrentCulture = other.CurrentCulture; CurrentCulture = other.CurrentCulture;
CurrentUICulture = other.CurrentUICulture; CurrentUICulture = other.CurrentUICulture;
CurrentContext = this; CurrentContext = this;
} }
public TextWriter OutWriter { get; private set; } public TextWriter OutWriter { get; private set; }
public bool StopOnError { get; set; } public bool StopOnError { get; set; }
public IWorkItemDispatcher Dispatcher { get; set; } public IWorkItemDispatcher Dispatcher { get; set; }
public ParallelScope ParallelScope { get; set; } public ParallelScope ParallelScope { get; set; }
public string WorkerId { get; private set; } public string WorkerId { get; private set; }
public Randomizer RandomGenerator { get; private set; } public Randomizer RandomGenerator { get; private set; }
public ValueFormatter CurrentValueFormatter { get; private set; } public ValueFormatter CurrentValueFormatter { get; private set; }
public bool IsSingleThreaded { get; set; } public bool IsSingleThreaded { get; set; }
public BeforeAfterTestCommandState SetUpTearDownState { get; set; } public BeforeAfterTestCommandState SetUpTearDownState { get; set; }
public BeforeAfterTestCommandState OuterUnityTestActionState { get; set; } public BeforeAfterTestCommandState OuterUnityTestActionState { get; set; }
public int EnumerableRepeatedTestState { get; set; } public int EnumerableRepeatedTestState { get; set; }
public int EnumerableRetryTestState { get; set; } public int EnumerableRetryTestState { get; set; }
internal int AssertCount internal int AssertCount
{ {
get get
{ {
return _assertCount; return _assertCount;
} }
} }
public void IncrementAssertCount() public void IncrementAssertCount()
{ {
_assertCount += 1; _assertCount += 1;
} }
public void AddFormatter(ValueFormatterFactory formatterFactory) public void AddFormatter(ValueFormatterFactory formatterFactory)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
} }
fileFormatVersion: 2 fileFormatVersion: 2
guid: 59ff995fabb3bac45afa0f96f333e5dc guid: 59ff995fabb3bac45afa0f96f333e5dc
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName: assetBundleName:
assetBundleVariant: assetBundleVariant:
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.Interfaces; using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal; using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Execution; using NUnit.Framework.Internal.Execution;
namespace UnityEngine.TestRunner.NUnitExtensions.Runner namespace UnityEngine.TestRunner.NUnitExtensions.Runner
{ {
internal abstract class UnityWorkItem internal abstract class UnityWorkItem
{ {
protected readonly WorkItemFactory m_Factory; protected readonly WorkItemFactory m_Factory;
protected bool m_ExecuteTestStartEvent; protected bool m_ExecuteTestStartEvent;
protected bool m_DontRunRestoringResult; protected bool m_DontRunRestoringResult;
public event EventHandler Completed; public event EventHandler Completed;
public bool ResultedInDomainReload { get; internal set; } public bool ResultedInDomainReload { get; internal set; }
public UnityTestExecutionContext Context { get; private set; } public UnityTestExecutionContext Context { get; private set; }
public Test Test { get; private set; } public Test Test { get; private set; }
public TestResult Result { get; protected set; } public TestResult Result { get; protected set; }
public WorkItemState State { get; private set; } public WorkItemState State { get; private set; }
public List<ITestAction> Actions { get; private set; } public List<ITestAction> Actions { get; private set; }
protected UnityWorkItem(Test test, WorkItemFactory factory) protected UnityWorkItem(Test test, WorkItemFactory factory)
{ {
m_Factory = factory; m_Factory = factory;
Test = test; Test = test;
Actions = new List<ITestAction>(); Actions = new List<ITestAction>();
Result = test.MakeTestResult(); Result = test.MakeTestResult();
State = WorkItemState.Ready; State = WorkItemState.Ready;
m_ExecuteTestStartEvent = ShouldExecuteStartEvent(); m_ExecuteTestStartEvent = ShouldExecuteStartEvent();
m_DontRunRestoringResult = ShouldRestore(test); m_DontRunRestoringResult = ShouldRestore(test);
} }
protected static bool ShouldRestore(ITest loadedTest) protected static bool ShouldRestore(ITest loadedTest)
{ {
return UnityWorkItemDataHolder.alreadyExecutedTests != null && return UnityWorkItemDataHolder.alreadyExecutedTests != null &&
UnityWorkItemDataHolder.alreadyExecutedTests.Contains(loadedTest.GetUniqueName()); UnityWorkItemDataHolder.alreadyExecutedTests.Contains(loadedTest.GetUniqueName());
} }
protected bool ShouldExecuteStartEvent() protected bool ShouldExecuteStartEvent()
{ {
return UnityWorkItemDataHolder.alreadyStartedTests != null && return UnityWorkItemDataHolder.alreadyStartedTests != null &&
UnityWorkItemDataHolder.alreadyStartedTests.All(x => x != Test.GetUniqueName()) && UnityWorkItemDataHolder.alreadyStartedTests.All(x => x != Test.GetUniqueName()) &&
!ShouldRestore(Test); !ShouldRestore(Test);
} }
protected abstract IEnumerable PerformWork(); protected abstract IEnumerable PerformWork();
public void InitializeContext(UnityTestExecutionContext context) public void InitializeContext(UnityTestExecutionContext context)
{ {
Context = context; Context = context;
if (Test is TestAssembly) if (Test is TestAssembly)
Actions.AddRange(ActionsHelper.GetActionsFromTestAssembly((TestAssembly)Test)); Actions.AddRange(ActionsHelper.GetActionsFromTestAssembly((TestAssembly)Test));
else if (Test is ParameterizedMethodSuite) else if (Test is ParameterizedMethodSuite)
Actions.AddRange(ActionsHelper.GetActionsFromTestMethodInfo(Test.Method)); Actions.AddRange(ActionsHelper.GetActionsFromTestMethodInfo(Test.Method));
else if (Test.TypeInfo != null) else if (Test.TypeInfo != null)
Actions.AddRange(ActionsHelper.GetActionsFromTypesAttributes(Test.TypeInfo.Type)); Actions.AddRange(ActionsHelper.GetActionsFromTypesAttributes(Test.TypeInfo.Type));
} }
public virtual IEnumerable Execute() public virtual IEnumerable Execute()
{ {
Context.CurrentTest = this.Test; Context.CurrentTest = this.Test;
Context.CurrentResult = this.Result; Context.CurrentResult = this.Result;
if (m_ExecuteTestStartEvent) if (m_ExecuteTestStartEvent)
{ {
Context.Listener.TestStarted(Test); Context.Listener.TestStarted(Test);
} }
Context.StartTime = DateTime.UtcNow; Context.StartTime = DateTime.UtcNow;
Context.StartTicks = Stopwatch.GetTimestamp(); Context.StartTicks = Stopwatch.GetTimestamp();
State = WorkItemState.Running; State = WorkItemState.Running;
return PerformWork(); return PerformWork();
} }
protected void WorkItemComplete() protected void WorkItemComplete()
{ {
State = WorkItemState.Complete; State = WorkItemState.Complete;
Result.StartTime = Context.StartTime; Result.StartTime = Context.StartTime;
Result.EndTime = DateTime.UtcNow; Result.EndTime = DateTime.UtcNow;
long tickCount = Stopwatch.GetTimestamp() - Context.StartTicks; long tickCount = Stopwatch.GetTimestamp() - Context.StartTicks;
double seconds = (double)tickCount / Stopwatch.Frequency; double seconds = (double)tickCount / Stopwatch.Frequency;
Result.Duration = seconds; Result.Duration = seconds;
//Result.AssertCount += Context.AssertCount; //Result.AssertCount += Context.AssertCount;
Context.Listener.TestFinished(Result); Context.Listener.TestFinished(Result);
if (Completed != null) if (Completed != null)
Completed(this, EventArgs.Empty); Completed(this, EventArgs.Empty);
Context.TestObject = null; Context.TestObject = null;
Test.Fixture = null; Test.Fixture = null;
} }
public virtual void Cancel(bool force) public virtual void Cancel(bool force)
{ {
Result.SetResult(ResultState.Cancelled, "Cancelled by user"); Result.SetResult(ResultState.Cancelled, "Cancelled by user");
Context.Listener.TestFinished(Result); Context.Listener.TestFinished(Result);
} }
} }
} }
fileFormatVersion: 2 fileFormatVersion: 2
guid: 79ced2556f0af814a840b86232613ff1 guid: 79ced2556f0af814a840b86232613ff1
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName: assetBundleName:
assetBundleVariant: assetBundleVariant:
using System.Collections.Generic; using System.Collections.Generic;
namespace UnityEngine.TestRunner.NUnitExtensions.Runner namespace UnityEngine.TestRunner.NUnitExtensions.Runner
{ {
internal class UnityWorkItemDataHolder internal class UnityWorkItemDataHolder
{ {
public static List<string> alreadyStartedTests = new List<string>(); public static List<string> alreadyStartedTests = new List<string>();
public static List<string> alreadyExecutedTests; public static List<string> alreadyExecutedTests;
} }
} }
fileFormatVersion: 2 fileFormatVersion: 2
guid: 5b3e90046c38f1d4dad2e0d5a79e871c guid: 5b3e90046c38f1d4dad2e0d5a79e871c
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName: assetBundleName:
assetBundleVariant: assetBundleVariant:
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment