Нет описания
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

UnityLogCheckDelegatingCommand.cs 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Reflection;
  6. using NUnit.Framework.Internal;
  7. using NUnit.Framework.Internal.Commands;
  8. using UnityEngine.TestTools;
  9. using UnityEngine.TestTools.Logging;
  10. using UnityEngine.TestTools.TestRunner;
  11. namespace UnityEngine.TestRunner.NUnitExtensions.Runner
  12. {
  13. class UnityLogCheckDelegatingCommand : DelegatingTestCommand, IEnumerableTestMethodCommand
  14. {
  15. static Dictionary<object, bool?> s_AttributeCache = new Dictionary<object, bool?>();
  16. public UnityLogCheckDelegatingCommand(TestCommand innerCommand)
  17. : base(innerCommand) {}
  18. public override TestResult Execute(ITestExecutionContext context)
  19. {
  20. using (var logScope = new LogScope())
  21. {
  22. if (ExecuteAndCheckLog(logScope, context.CurrentResult, () => innerCommand.Execute(context)))
  23. PostTestValidation(logScope, innerCommand, context.CurrentResult);
  24. }
  25. return context.CurrentResult;
  26. }
  27. public IEnumerable ExecuteEnumerable(ITestExecutionContext context)
  28. {
  29. if (!(innerCommand is IEnumerableTestMethodCommand enumerableTestMethodCommand))
  30. {
  31. Execute(context);
  32. yield break;
  33. }
  34. using (var logScope = new LogScope())
  35. {
  36. IEnumerable executeEnumerable = null;
  37. if (!ExecuteAndCheckLog(logScope, context.CurrentResult,
  38. () => executeEnumerable = enumerableTestMethodCommand.ExecuteEnumerable(context)))
  39. yield break;
  40. foreach (var step in executeEnumerable)
  41. {
  42. // do not check expected logs here - we want to permit expecting and receiving messages to run
  43. // across frames. (but we do always want to catch a fail immediately.)
  44. if (!CheckFailingLogs(logScope, context.CurrentResult))
  45. yield break;
  46. yield return step;
  47. }
  48. if (!CheckLogs(context.CurrentResult, logScope))
  49. yield break;
  50. PostTestValidation(logScope, innerCommand, context.CurrentResult);
  51. }
  52. }
  53. static bool CaptureException(TestResult result, Action action)
  54. {
  55. try
  56. {
  57. action();
  58. return true;
  59. }
  60. catch (Exception e)
  61. {
  62. result.RecordException(e);
  63. return false;
  64. }
  65. }
  66. static bool ExecuteAndCheckLog(LogScope logScope, TestResult result, Action action)
  67. => CaptureException(result, action) && CheckLogs(result, logScope);
  68. static void PostTestValidation(LogScope logScope, TestCommand command, TestResult result)
  69. {
  70. if (MustExpect(command.Test.Method.MethodInfo))
  71. CaptureException(result, logScope.NoUnexpectedReceived);
  72. }
  73. static bool CheckLogs(TestResult result, LogScope logScope)
  74. {
  75. try
  76. {
  77. logScope.EvaluateLogScope(true);
  78. }
  79. catch (Exception e)
  80. {
  81. result.RecordException(e);
  82. return false;
  83. }
  84. return true;
  85. }
  86. static bool CheckFailingLogs(LogScope logScope, TestResult result)
  87. {
  88. try
  89. {
  90. logScope.EvaluateLogScope(false);
  91. }
  92. catch (Exception e)
  93. {
  94. result.RecordException(e);
  95. return false;
  96. }
  97. return true;
  98. }
  99. static bool MustExpect(MemberInfo method)
  100. {
  101. // method
  102. var methodAttr = method.GetCustomAttributes<TestMustExpectAllLogsAttribute>(true).FirstOrDefault();
  103. if (methodAttr != null)
  104. return methodAttr.MustExpect;
  105. // fixture
  106. var fixture = method.DeclaringType;
  107. if (!s_AttributeCache.TryGetValue(fixture, out var mustExpect))
  108. {
  109. var fixtureAttr = fixture.GetCustomAttributes<TestMustExpectAllLogsAttribute>(true).FirstOrDefault();
  110. mustExpect = s_AttributeCache[fixture] = fixtureAttr?.MustExpect;
  111. }
  112. if (mustExpect != null)
  113. return mustExpect.Value;
  114. // assembly
  115. var assembly = fixture.Assembly;
  116. if (!s_AttributeCache.TryGetValue(assembly, out mustExpect))
  117. {
  118. var assemblyAttr = assembly.GetCustomAttributes<TestMustExpectAllLogsAttribute>().FirstOrDefault();
  119. mustExpect = s_AttributeCache[assembly] = assemblyAttr?.MustExpect;
  120. }
  121. return mustExpect == true;
  122. }
  123. }
  124. }