暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

EnumerableTestMethodCommand.cs 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. using System;
  2. using System.Collections;
  3. using NUnit.Framework.Interfaces;
  4. using NUnit.Framework.Internal;
  5. using NUnit.Framework.Internal.Commands;
  6. using Unity.Profiling;
  7. using UnityEngine.TestRunner.NUnitExtensions.Runner;
  8. using UnityEngine.TestTools.TestRunner;
  9. namespace UnityEngine.TestTools
  10. {
  11. internal class EnumerableTestMethodCommand : TestCommand, IEnumerableTestMethodCommand
  12. {
  13. private readonly TestMethod testMethod;
  14. public EnumerableTestMethodCommand(TestMethod testMethod)
  15. : base(testMethod)
  16. {
  17. this.testMethod = testMethod;
  18. }
  19. public IEnumerable ExecuteEnumerable(ITestExecutionContext context)
  20. {
  21. var unityContext = (UnityTestExecutionContext) context;
  22. yield return null;
  23. IEnumerator currentExecutingTestEnumerator;
  24. try
  25. {
  26. currentExecutingTestEnumerator = new TestEnumeratorWrapper(testMethod).GetEnumerator(context);
  27. }
  28. catch (Exception ex)
  29. {
  30. context.CurrentResult.RecordException(ex);
  31. yield break;
  32. }
  33. if (currentExecutingTestEnumerator != null)
  34. {
  35. var testEnumeraterYieldInstruction = new TestEnumerator(context, currentExecutingTestEnumerator);
  36. yield return testEnumeraterYieldInstruction;
  37. var enumerator = testEnumeraterYieldInstruction.Execute();
  38. var executingEnumerator = ExecuteEnumerableAndRecordExceptions(enumerator, new EnumeratorContext(context), unityContext);
  39. while (AdvanceEnumerator(executingEnumerator))
  40. {
  41. yield return executingEnumerator.Current;
  42. }
  43. }
  44. else
  45. {
  46. if (context.CurrentResult.ResultState != ResultState.Ignored)
  47. {
  48. context.CurrentResult.SetResult(ResultState.Success);
  49. }
  50. }
  51. }
  52. private bool AdvanceEnumerator(IEnumerator enumerator)
  53. {
  54. using (new ProfilerMarker(testMethod.MethodName).Auto())
  55. return enumerator.MoveNext();
  56. }
  57. private IEnumerator ExecuteEnumerableAndRecordExceptions(IEnumerator enumerator, EnumeratorContext context, UnityTestExecutionContext unityContext)
  58. {
  59. while (true)
  60. {
  61. if (context.ExceptionWasRecorded)
  62. {
  63. break;
  64. }
  65. try
  66. {
  67. if (!enumerator.MoveNext())
  68. {
  69. break;
  70. }
  71. if (unityContext.TestMode == TestPlatform.PlayMode && enumerator.Current is IEditModeTestYieldInstruction)
  72. {
  73. throw new Exception($"PlayMode test are not allowed to yield {enumerator.Current.GetType().Name}");
  74. }
  75. }
  76. catch (Exception ex)
  77. {
  78. context.RecordExceptionWithHint(ex);
  79. break;
  80. }
  81. if (enumerator.Current is IEnumerator nestedEnumerator)
  82. {
  83. yield return ExecuteEnumerableAndRecordExceptions(nestedEnumerator, context, unityContext);
  84. }
  85. else
  86. {
  87. yield return enumerator.Current;
  88. }
  89. }
  90. }
  91. private class EnumeratorContext
  92. {
  93. private readonly ITestExecutionContext m_Context;
  94. public EnumeratorContext(ITestExecutionContext context)
  95. {
  96. m_Context = context;
  97. }
  98. public bool ExceptionWasRecorded
  99. {
  100. get;
  101. private set;
  102. }
  103. public void RecordExceptionWithHint(Exception ex)
  104. {
  105. if (ExceptionWasRecorded)
  106. {
  107. return;
  108. }
  109. m_Context.CurrentResult.RecordException(ex);
  110. ExceptionWasRecorded = true;
  111. }
  112. }
  113. public override TestResult Execute(ITestExecutionContext context)
  114. {
  115. throw new NotImplementedException("Use ExecuteEnumerable");
  116. }
  117. }
  118. }