A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Linq;
5using UnityEngine.SceneManagement;
6using UnityEngine.TestRunner.NUnitExtensions;
7using UnityEngine.TestRunner.NUnitExtensions.Runner;
8using UnityEngine.TestTools.NUnitExtensions;
9using UnityEngine.TestTools.Utils;
10
11namespace UnityEngine.TestTools.TestRunner
12{
13 [Serializable]
14 [AddComponentMenu("")]
15 internal class PlaymodeTestsController : MonoBehaviour
16 {
17 private IEnumerator m_TestSteps;
18
19 public static PlaymodeTestsController ActiveController { get; set; }
20 public Exception RaisedException { get; set; }
21
22 [SerializeField]
23 private List<string> m_AssembliesWithTests;
24 public List<string> AssembliesWithTests
25 {
26 get
27 {
28 return m_AssembliesWithTests;
29 }
30 set
31 {
32 m_AssembliesWithTests = value;
33 }
34 }
35
36 [SerializeField]
37 internal TestStartedEvent testStartedEvent = new TestStartedEvent();
38 [SerializeField]
39 internal TestFinishedEvent testFinishedEvent = new TestFinishedEvent();
40 [SerializeField]
41 internal RunStartedEvent runStartedEvent = new RunStartedEvent();
42 [SerializeField]
43 internal RunFinishedEvent runFinishedEvent = new RunFinishedEvent();
44
45 //DO NOT change this string, third party code is using this string to identify the test runner game object.
46 internal const string kPlaymodeTestControllerName = "Code-based tests runner";
47
48 [SerializeField]
49 public PlaymodeTestsControllerSettings settings = new PlaymodeTestsControllerSettings();
50 [NonSerialized]
51 public bool RunInfrastructureHasRegistered = false;
52
53 internal UnityTestAssemblyRunner m_Runner;
54
55 public IEnumerator Start()
56 {
57 UnityTestExecutionContext.CurrentContext = new UnityTestExecutionContext()
58 {
59 FeatureFlags = settings.featureFlags,
60 RetryCount = settings.retryCount,
61 RepeatCount = settings.repeatCount,
62 Automated = settings.automated
63 };
64 ActiveController = this;
65 //Skip 2 frame because Unity.
66 yield return null;
67 yield return null;
68
69 if (Application.isEditor && !RunInfrastructureHasRegistered)
70 {
71 yield return null;
72 }
73
74 StartCoroutine(Run());
75 }
76
77 internal static bool IsControllerOnScene()
78 {
79 return GameObject.Find(kPlaymodeTestControllerName) != null;
80 }
81
82 internal static PlaymodeTestsController GetController()
83 {
84 return GameObject.Find(kPlaymodeTestControllerName).GetComponent<PlaymodeTestsController>();
85 }
86
87 public IEnumerator TestRunnerCoroutine()
88 {
89 while (true)
90 {
91 try
92 {
93 if (!m_TestSteps.MoveNext())
94 {
95 break;
96 }
97 }
98 catch (Exception e)
99 {
100 RaisedException = e;
101 throw;
102 }
103
104 yield return m_TestSteps.Current;
105 }
106
107 if (m_Runner.IsTestComplete)
108 {
109 runFinishedEvent.Invoke(m_Runner.Result);
110
111 yield return null;
112 }
113 }
114
115 public IEnumerator Run()
116 {
117 if (!RunInfrastructureHasRegistered)
118 {
119 // Wait for the infrastructure to be ready
120 yield return null;
121 }
122
123 CoroutineTestWorkItem.monoBehaviourCoroutineRunner = this;
124 gameObject.hideFlags |= HideFlags.DontSave;
125
126 if (settings.sceneBased)
127 {
128 SceneManager.LoadScene(1, LoadSceneMode.Additive);
129 yield return null;
130 }
131
132 var testListUtil = new PlayerTestAssemblyProvider(new AssemblyLoadProxy(), m_AssembliesWithTests);
133 m_Runner = new UnityTestAssemblyRunner(new UnityTestAssemblyBuilder(settings.orderedTestNames, settings.randomOrderSeed), new PlaymodeWorkItemFactory(), UnityTestExecutionContext.CurrentContext);
134
135 var loadedTests = m_Runner.Load(testListUtil.GetUserAssemblies().Select(a => a.Assembly).ToArray(), TestPlatform.PlayMode, UnityTestAssemblyBuilder.GetNUnitTestBuilderSettings(TestPlatform.PlayMode));
136 loadedTests.ParseForNameDuplicates();
137 runStartedEvent.Invoke(m_Runner.LoadedTest);
138
139 var testListenerWrapper = new TestListenerWrapper(testStartedEvent, testFinishedEvent);
140 m_TestSteps = m_Runner.Run(testListenerWrapper, settings.BuildNUnitFilter()).GetEnumerator();
141
142 yield return TestRunnerCoroutine();
143 }
144
145 public void Cleanup()
146 {
147 if (m_Runner != null)
148 {
149 m_Runner.StopRun();
150 m_Runner = null;
151 }
152 if (Application.isEditor)
153 {
154 if (Application.isPlaying)
155 {
156 Destroy(gameObject);
157 }
158 else
159 {
160 DestroyImmediate(gameObject);
161 }
162 }
163 }
164 }
165}