-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
Add CreateScene and LoadScene attribute
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// Copyright (c) 2023 Koji Hasegawa. | ||
// This software is released under the MIT License. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using TestHelper.Attributes; | ||
using TestHelper.Editor; | ||
using UnityEditor; | ||
using UnityEditor.TestTools; | ||
|
||
[assembly: TestPlayerBuildModifier(typeof(TemporaryBuildScenesUsingInTest))] | ||
|
||
namespace TestHelper.Editor | ||
{ | ||
/// <summary> | ||
/// Temporarily build scenes specified by <c>LoadSceneAttribute</c> when running play mode tests on standalone player. | ||
/// </summary> | ||
public class TemporaryBuildScenesUsingInTest : ITestPlayerBuildModifier | ||
{ | ||
private static IEnumerable<LoadSceneAttribute> FindLoadSceneAttributesOnAssemblies() | ||
{ | ||
var assemblies = AppDomain.CurrentDomain.GetAssemblies(); | ||
foreach (var attribute in assemblies | ||
.Select(assembly => assembly.GetCustomAttributes(typeof(LoadSceneAttribute), false)) | ||
.SelectMany(attributes => attributes)) | ||
{ | ||
yield return attribute as LoadSceneAttribute; | ||
} | ||
} | ||
|
||
private static IEnumerable<LoadSceneAttribute> FindLoadSceneAttributesOnTypes() | ||
{ | ||
var symbols = TypeCache.GetTypesWithAttribute<LoadSceneAttribute>(); | ||
foreach (var attribute in symbols | ||
.Select(symbol => symbol.GetCustomAttributes(typeof(LoadSceneAttribute), false)) | ||
.SelectMany(attributes => attributes)) | ||
{ | ||
yield return attribute as LoadSceneAttribute; | ||
} | ||
} | ||
|
||
private static IEnumerable<LoadSceneAttribute> FindLoadSceneAttributesOnMethods() | ||
{ | ||
var symbols = TypeCache.GetMethodsWithAttribute<LoadSceneAttribute>(); | ||
foreach (var attribute in symbols | ||
.Select(symbol => symbol.GetCustomAttributes(typeof(LoadSceneAttribute), false)) | ||
.SelectMany(attributes => attributes)) | ||
{ | ||
yield return attribute as LoadSceneAttribute; | ||
} | ||
} | ||
|
||
internal static IEnumerable<string> GetScenesUsingInTest() | ||
{ | ||
var attributes = FindLoadSceneAttributesOnAssemblies() | ||
.Concat(FindLoadSceneAttributesOnTypes()) | ||
.Concat(FindLoadSceneAttributesOnMethods()); | ||
foreach (var attribute in attributes) | ||
{ | ||
if (attribute.ScenePath.ToLower().EndsWith(".unity")) | ||
{ | ||
yield return attribute.ScenePath; | ||
} | ||
else | ||
{ | ||
foreach (var guid in AssetDatabase.FindAssets("t:SceneAsset", new[] { attribute.ScenePath })) | ||
{ | ||
yield return AssetDatabase.GUIDToAssetPath(guid); | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Add temporary scenes to build when running play mode tests on standalone player. | ||
/// </summary> | ||
/// <remarks> | ||
/// Required Unity Test Framework package v1.1.13 or higher is to use this script. | ||
/// For details, see the <see href="https://forum.unity.com/threads/testplayerbuildmodifier-not-working.844447/">report in forum</see>. | ||
/// </remarks> | ||
public BuildPlayerOptions ModifyOptions(BuildPlayerOptions playerOptions) | ||
{ | ||
var scenesInBuild = new List<string>(playerOptions.scenes); | ||
foreach (var scenePath in GetScenesUsingInTest()) | ||
{ | ||
if (!scenesInBuild.Contains(scenePath)) | ||
{ | ||
scenesInBuild.Add(scenePath); | ||
} | ||
} | ||
|
||
playerOptions.scenes = scenesInBuild.ToArray(); | ||
return playerOptions; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// Copyright (c) 2023 Koji Hasegawa. | ||
// This software is released under the MIT License. | ||
|
||
using System; | ||
using System.Collections; | ||
using NUnit.Framework; | ||
using NUnit.Framework.Interfaces; | ||
using UnityEngine; | ||
using UnityEngine.SceneManagement; | ||
using UnityEngine.TestTools; | ||
#if UNITY_EDITOR | ||
using UnityEditor; | ||
using UnityEditor.SceneManagement; | ||
#endif | ||
|
||
// ReSharper disable InvalidXmlDocComment | ||
|
||
namespace TestHelper.Attributes | ||
{ | ||
/// <summary> | ||
/// Load scene before running test. | ||
/// | ||
/// It has the following benefits: | ||
/// - Can be used when running play mode tests in-editor and on-player | ||
/// - Can be specified scenes that are not in "Scenes in Build" | ||
/// | ||
/// Notes: | ||
/// - Load scene run after <c>OneTimeSetUp</c> and before <c>SetUp</c> | ||
/// - For the process of including a Scene not in "Scenes in Build" to a build for player, see: <see cref="TestHelper.Editor.TemporaryBuildScenesUsingInTest"/> | ||
/// </summary> | ||
[AttributeUsage(AttributeTargets.Method)] | ||
public class LoadSceneAttribute : NUnitAttribute, IOuterUnityTestAction | ||
{ | ||
internal string ScenePath { get; private set; } | ||
|
||
/// <summary> | ||
/// Load scene before running test. | ||
/// </summary> | ||
/// <param name="path">Scene file path. | ||
/// The path starts with `Assets/` or `Packages/`. | ||
/// And package name using `name` instead of `displayName`, when scenes in the package. | ||
/// (e.g., `Packages/com.nowsprinting.test-helper/Tests/Scenes/Scene.unity`) | ||
/// </param> | ||
public LoadSceneAttribute(string path) | ||
{ | ||
ScenePath = path; | ||
} | ||
|
||
/// <inheritdoc /> | ||
public IEnumerator BeforeTest(ITest test) | ||
{ | ||
AsyncOperation loadSceneAsync = null; | ||
#if UNITY_EDITOR | ||
if (EditorApplication.isPlaying) | ||
{ | ||
// Use EditorSceneManager at run on Unity-editor | ||
loadSceneAsync = EditorSceneManager.LoadSceneAsyncInPlayMode( | ||
ScenePath, | ||
new LoadSceneParameters(LoadSceneMode.Single)); | ||
} | ||
else | ||
{ | ||
EditorSceneManager.OpenScene(ScenePath); | ||
} | ||
#else | ||
// Use ITestPlayerBuildModifier to change the "Scenes in Build" list before run on player | ||
loadSceneAsync = SceneManager.LoadSceneAsync(ScenePath); | ||
#endif | ||
yield return loadSceneAsync; | ||
} | ||
|
||
/// <inheritdoc /> | ||
public IEnumerator AfterTest(ITest test) | ||
{ | ||
yield return null; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Copyright (c) 2023 Koji Hasegawa. | ||
// This software is released under the MIT License. | ||
|
||
using NUnit.Framework; | ||
using TestHelper.Attributes; | ||
using UnityEngine; | ||
|
||
namespace TestHelper.Editor | ||
{ | ||
[TestFixture] | ||
public class LoadSceneAttributeTest | ||
{ | ||
private const string TestScene = "Packages/com.nowsprinting.test-helper/Tests/Scenes/NotInScenesInBuild.unity"; | ||
private const string ObjectName = "CubeInNotInScenesInBuild"; | ||
|
||
[Test] | ||
[LoadScene(TestScene)] | ||
public void Attach_AlreadyLoadedSceneNotInBuild() | ||
{ | ||
var cube = GameObject.Find(ObjectName); | ||
Assert.That(cube, Is.Not.Null); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Copyright (c) 2023 Koji Hasegawa. | ||
// This software is released under the MIT License. | ||
|
||
using NUnit.Framework; | ||
|
||
namespace TestHelper.Editor | ||
{ | ||
[TestFixture] | ||
public class TemporaryBuildScenesUsingInTestTest | ||
{ | ||
[Test] | ||
public void GetScenesUsingInTest_AttachedToMethod_ReturnScenesSpecifiedByAttribute() | ||
{ | ||
var actual = TemporaryBuildScenesUsingInTest.GetScenesUsingInTest(); | ||
Assert.That(actual, | ||
Does.Contain("Packages/com.nowsprinting.test-helper/Tests/Scenes/NotInScenesInBuild.unity")); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Copyright (c) 2023 Koji Hasegawa. | ||
// This software is released under the MIT License. | ||
|
||
using System.Collections; | ||
using System.Threading.Tasks; | ||
using NUnit.Framework; | ||
using UnityEngine; | ||
using UnityEngine.TestTools; | ||
|
||
namespace TestHelper.Attributes | ||
{ | ||
[TestFixture] | ||
public class LoadSceneAttributeTest | ||
{ | ||
private const string TestScene = "Packages/com.nowsprinting.test-helper/Tests/Scenes/NotInScenesInBuild.unity"; | ||
private const string ObjectName = "CubeInNotInScenesInBuild"; | ||
|
||
[Test] | ||
[LoadScene(TestScene)] | ||
public void Attach_AlreadyLoadedSceneNotInBuild() | ||
{ | ||
var cube = GameObject.Find(ObjectName); | ||
Assert.That(cube, Is.Not.Null); | ||
|
||
Object.Destroy(cube); // For not giving false negatives in subsequent tests. | ||
} | ||
|
||
[Test] | ||
[LoadScene(TestScene)] | ||
public async Task AttachToAsyncTest_AlreadyLoadedSceneNotInBuild() | ||
{ | ||
var cube = GameObject.Find(ObjectName); | ||
Assert.That(cube, Is.Not.Null); | ||
|
||
Object.Destroy(cube); // For not giving false negatives in subsequent tests. | ||
await Task.Yield(); | ||
} | ||
|
||
[UnityTest] | ||
[LoadScene(TestScene)] | ||
public IEnumerator AttachToUnityTest_AlreadyLoadedSceneNotInBuild() | ||
{ | ||
var cube = GameObject.Find(ObjectName); | ||
Assert.That(cube, Is.Not.Null); | ||
|
||
Object.Destroy(cube); // For not giving false negatives in subsequent tests. | ||
yield return null; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.