PlaymodeLauncher.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using NUnit.Framework.Interfaces;
  5. using NUnit.Framework.Internal.Filters;
  6. using UnityEditor.TestTools.TestRunner.Api;
  7. using UnityEngine;
  8. using UnityEngine.SceneManagement;
  9. using UnityEngine.TestRunner.Utils;
  10. using UnityEngine.TestTools.TestRunner;
  11. using UnityEngine.TestTools.TestRunner.Callbacks;
  12. namespace UnityEditor.TestTools.TestRunner
  13. {
  14. internal class PlaymodeLauncher : RuntimeTestLauncherBase
  15. {
  16. public static bool IsRunning;
  17. private Scene m_Scene;
  18. private bool m_IsTestSetupPerformed;
  19. private readonly PlaymodeTestsControllerSettings m_Settings;
  20. private ITestFilter testFilter;
  21. [SerializeField]
  22. private List<Type> m_EventHandlers = new List<Type>();
  23. public PlaymodeLauncher(PlaymodeTestsControllerSettings settings)
  24. {
  25. m_Settings = settings;
  26. }
  27. public override void Run()
  28. {
  29. IsRunning = true;
  30. ConsoleWindow.SetConsoleErrorPause(false);
  31. Application.runInBackground = true;
  32. var sceneName = CreateSceneName();
  33. m_Scene = CreateBootstrapScene(sceneName, runner =>
  34. {
  35. runner.AddEventHandlerMonoBehaviour<PlayModeRunnerCallback>();
  36. runner.AddEventHandlerScriptableObject<TestRunnerCallback>();
  37. runner.AddEventHandlerScriptableObject<CallbacksDelegatorListener>();
  38. runner.AddEventHandlerScriptableObject<TestRunCallbackListener>();
  39. foreach (var eventHandler in m_EventHandlers)
  40. {
  41. var obj = ScriptableObject.CreateInstance(eventHandler);
  42. runner.AddEventHandlerScriptableObject(obj as ITestRunnerListener);
  43. }
  44. runner.settings = m_Settings;
  45. });
  46. if (m_Settings.sceneBased)
  47. {
  48. var newListOfScenes =
  49. new List<EditorBuildSettingsScene> {new EditorBuildSettingsScene(sceneName, true)};
  50. newListOfScenes.AddRange(EditorBuildSettings.scenes);
  51. EditorBuildSettings.scenes = newListOfScenes.ToArray();
  52. }
  53. EditorApplication.update += UpdateCallback;
  54. }
  55. public void UpdateCallback()
  56. {
  57. if (m_IsTestSetupPerformed)
  58. {
  59. if (m_Scene.IsValid())
  60. SceneManager.SetActiveScene(m_Scene);
  61. EditorApplication.update -= UpdateCallback;
  62. EditorApplication.isPlaying = true;
  63. }
  64. else
  65. {
  66. testFilter = m_Settings.BuildNUnitFilter();
  67. var runner = LoadTests(testFilter);
  68. var exceptionThrown = ExecutePreBuildSetupMethods(runner.LoadedTest, testFilter);
  69. if (exceptionThrown)
  70. {
  71. EditorApplication.update -= UpdateCallback;
  72. IsRunning = false;
  73. var controller = PlaymodeTestsController.GetController();
  74. ReopenOriginalScene(controller);
  75. AssetDatabase.DeleteAsset(controller.settings.bootstrapScene);
  76. CallbacksDelegator.instance.RunFailed("Run Failed: One or more errors in a prebuild setup. See the editor log for details.");
  77. return;
  78. }
  79. m_IsTestSetupPerformed = true;
  80. }
  81. }
  82. [InitializeOnLoad]
  83. public class BackgroundWatcher
  84. {
  85. static BackgroundWatcher()
  86. {
  87. EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
  88. }
  89. private static void OnPlayModeStateChanged(PlayModeStateChange state)
  90. {
  91. if (!PlaymodeTestsController.IsControllerOnScene())
  92. return;
  93. var runner = PlaymodeTestsController.GetController();
  94. if (runner == null)
  95. return;
  96. if (state == PlayModeStateChange.ExitingPlayMode)
  97. {
  98. AssetDatabase.DeleteAsset(runner.settings.bootstrapScene);
  99. ExecutePostBuildCleanupMethods(runner.m_Runner.LoadedTest, runner.settings.BuildNUnitFilter(), Application.platform);
  100. IsRunning = false;
  101. }
  102. else if (state == PlayModeStateChange.EnteredEditMode)
  103. {
  104. //reopen the original scene once we exit playmode
  105. ReopenOriginalScene(runner);
  106. }
  107. }
  108. }
  109. protected static void ReopenOriginalScene(PlaymodeTestsController runner)
  110. {
  111. ReopenOriginalScene(runner.settings.originalScene);
  112. }
  113. public void AddEventHandler<T>() where T : ScriptableObject, ITestRunnerListener
  114. {
  115. m_EventHandlers.Add(typeof(T));
  116. }
  117. }
  118. }