diff --git a/Runtime/Attributes/FocusGameViewAttribute.cs b/Runtime/Attributes/FocusGameViewAttribute.cs index 9d888f2..68c3af9 100644 --- a/Runtime/Attributes/FocusGameViewAttribute.cs +++ b/Runtime/Attributes/FocusGameViewAttribute.cs @@ -5,39 +5,21 @@ using NUnit.Framework; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; -using UnityEngine; -#if UNITY_EDITOR -using System.Reflection; -using UnityEditor; -#endif +using TestHelper.RuntimeInternals; namespace TestHelper.Attributes { /// /// Focus GameView or SimulatorWindow before run test. - /// /// Example usage: Tests that use InputEventTrace of the Input System package (com.unity.inputsystem). /// [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] public class FocusGameViewAttribute : NUnitAttribute, IApplyToContext { - private static Type s_gameView; - /// public void ApplyToContext(ITestExecutionContext context) { -#if UNITY_EDITOR - if (s_gameView == null) - { - var assembly = Assembly.Load("UnityEditor.dll"); - var viewClass = Application.isBatchMode ? "UnityEditor.GameView" : "UnityEditor.PlayModeView"; - // Note: Freezes when getting SimulatorWindow in batchmode - - s_gameView = assembly.GetType(viewClass); - } - - EditorWindow.GetWindow(s_gameView, false, null, true); -#endif + GameViewControlHelper.Focus(); } } } diff --git a/Runtime/Attributes/GameViewResolutionAttribute.cs b/Runtime/Attributes/GameViewResolutionAttribute.cs index e840979..a27f329 100644 --- a/Runtime/Attributes/GameViewResolutionAttribute.cs +++ b/Runtime/Attributes/GameViewResolutionAttribute.cs @@ -5,11 +5,7 @@ using NUnit.Framework; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; -using UnityEngine; -#if UNITY_EDITOR -using TestHelper.Wrappers.UnityEditor; -using UnityEditor; -#endif +using TestHelper.RuntimeInternals; namespace TestHelper.Attributes { @@ -48,63 +44,7 @@ public GameViewResolutionAttribute(GameViewResolution resolution) /// public void ApplyToContext(ITestExecutionContext context) { -#if UNITY_2022_2_OR_NEWER - SetResolutionUsingPlayModeWindow(); -#else - SetResolution(); -#endif - } - - // ReSharper disable once UnusedMember.Local - private void SetResolutionUsingPlayModeWindow() - { -#if UNITY_EDITOR && UNITY_2022_2_OR_NEWER - PlayModeWindow.SetViewType(PlayModeWindow.PlayModeViewTypes.GameView); - PlayModeWindow.SetCustomRenderingResolution(_width, _height, _name); -#endif - } - - // ReSharper disable once UnusedMember.Local - private void SetResolution() - { -#if UNITY_EDITOR - var gameViewSizes = GameViewSizesWrapper.CreateInstance(); - if (gameViewSizes == null) - { - Debug.LogError("GameViewSizes instance creation failed."); - return; - } - - var gameViewSizeGroup = gameViewSizes.CurrentGroup(); - if (gameViewSizeGroup == null) - { - Debug.LogError("GameViewSizeGroup instance creation failed."); - return; - } - - var gameViewSize = GameViewSizeWrapper.CreateInstance((int)_width, (int)_height, _name); - if (gameViewSize == null) - { - Debug.LogError("GameViewSize instance creation failed."); - return; - } - - var index = gameViewSizeGroup.IndexOf(gameViewSize); - if (index == -1) - { - gameViewSizeGroup.AddCustomSize(gameViewSize); - index = gameViewSizeGroup.IndexOf(gameViewSize); - } - - var gameView = GameViewWrapper.GetWindow(); - if (gameView == null) - { - Debug.LogError("GameView instance creation failed."); - return; - } - - gameView.SelectedSizeIndex(index); -#endif + GameViewControlHelper.SetResolution(_width, _height, _name); } } } diff --git a/Runtime/TestHelper.asmdef b/Runtime/TestHelper.asmdef index 77b9774..8e6475b 100644 --- a/Runtime/TestHelper.asmdef +++ b/Runtime/TestHelper.asmdef @@ -3,7 +3,8 @@ "rootNamespace": "TestHelper", "references": [ "UnityEngine.TestRunner", - "UnityEditor.TestRunner" + "UnityEditor.TestRunner", + "TestHelper.RuntimeInternals" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Runtime/Utils/ScreenshotHelper.cs b/Runtime/Utils/ScreenshotHelper.cs index 8d37cd2..af80b63 100644 --- a/Runtime/Utils/ScreenshotHelper.cs +++ b/Runtime/Utils/ScreenshotHelper.cs @@ -2,8 +2,6 @@ // This software is released under the MIT License. using System.Collections; -using System.IO; -using System.Threading; using NUnit.Framework; using UnityEngine; @@ -14,11 +12,6 @@ namespace TestHelper.Utils /// public static class ScreenshotHelper { - private static string DefaultDirectoryPath() - { - return Path.Combine(Application.persistentDataPath, "TestHelper", "Screenshots"); - } - private static string DefaultFilename() { return $"{TestContext.CurrentTestExecutionContext.CurrentTest.Name}.png" @@ -52,45 +45,13 @@ public static IEnumerator TakeScreenshot( ScreenCapture.StereoScreenCaptureMode stereoCaptureMode = ScreenCapture.StereoScreenCaptureMode.LeftEye ) { - if (superSize != 1 && stereoCaptureMode != ScreenCapture.StereoScreenCaptureMode.LeftEye) - { - Debug.LogError("superSize and stereoCaptureMode cannot be specified at the same time."); - yield break; - } - - if (Thread.CurrentThread.ManagedThreadId != 1) - { - Debug.LogError("Must be called from the main thread."); - yield break; - // Note: This is not the case since it is a coroutine. - } - - if (Application.isEditor && directory != null) - { - directory = Path.GetFullPath(directory); - } - else - { - directory = DefaultDirectoryPath(); // Not apply specific directory when running on player - } - - Directory.CreateDirectory(directory); - if (filename == null) { filename = DefaultFilename(); } - yield return new WaitForEndOfFrame(); // Required to take screenshots - - var texture = superSize != 1 - ? ScreenCapture.CaptureScreenshotAsTexture(superSize) - : ScreenCapture.CaptureScreenshotAsTexture(stereoCaptureMode); - - var path = Path.Combine(directory, filename); - var bytes = texture.EncodeToPNG(); - File.WriteAllBytes(path, bytes); - Debug.Log($"Save screenshot to {path}"); + yield return RuntimeInternals.ScreenshotHelper.TakeScreenshot( + directory, filename, superSize, stereoCaptureMode); } } } diff --git a/RuntimeInternals.meta b/RuntimeInternals.meta new file mode 100644 index 0000000..121a4cd --- /dev/null +++ b/RuntimeInternals.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6fb31dcab2b6c40f5ba4874a00f6f6e2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/RuntimeInternals/AssemblyInfo.cs b/RuntimeInternals/AssemblyInfo.cs new file mode 100644 index 0000000..c599367 --- /dev/null +++ b/RuntimeInternals/AssemblyInfo.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2023 Koji Hasegawa. +// This software is released under the MIT License. + +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly: AssemblyTitle("Internal implementation for the TestHelper package")] +[assembly: AssemblyDescription( + @"This assembly can be used from the runtime code because it does not depend on test-framework. +This assembly is named ""Internal"", however, the included classes are public.")] + +[assembly: InternalsVisibleTo("TestHelper.RuntimeInternals.Tests")] diff --git a/RuntimeInternals/AssemblyInfo.cs.meta b/RuntimeInternals/AssemblyInfo.cs.meta new file mode 100644 index 0000000..68b5ae9 --- /dev/null +++ b/RuntimeInternals/AssemblyInfo.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 24e5470434d94de7bfb9452cc643305d +timeCreated: 1698660444 \ No newline at end of file diff --git a/RuntimeInternals/GameViewControlHelper.cs b/RuntimeInternals/GameViewControlHelper.cs new file mode 100644 index 0000000..bd7c10d --- /dev/null +++ b/RuntimeInternals/GameViewControlHelper.cs @@ -0,0 +1,106 @@ +// Copyright (c) 2023 Koji Hasegawa. +// This software is released under the MIT License. + +using System; +using System.Reflection; +using TestHelper.RuntimeInternals.Wrappers.UnityEditor; +using UnityEditor; +using UnityEngine; + +namespace TestHelper.RuntimeInternals +{ + /// + /// GameView control helper. + /// This class can be used from the runtime code because it does not depend on test-framework. + /// + public static class GameViewControlHelper + { + private static Type s_gameView; + + /// + /// Focus GameView or SimulatorWindow. + /// + public static void Focus() + { +#if UNITY_EDITOR + if (s_gameView == null) + { + var assembly = Assembly.Load("UnityEditor.dll"); + var viewClass = Application.isBatchMode ? "UnityEditor.GameView" : "UnityEditor.PlayModeView"; + // Note: Freezes when getting SimulatorWindow in batchmode + + s_gameView = assembly.GetType(viewClass); + } + + EditorWindow.GetWindow(s_gameView, false, null, true); +#endif + } + + /// + /// Set GameView resolution. + /// + /// GameView width [px] + /// GameView height [px] + /// GameViewSize name + public static void SetResolution(uint width, uint height, string name) + { +#if UNITY_2022_2_OR_NEWER + SetResolutionUsingPlayModeWindow(width, height, name); +#else + SetResolutionUsingReflection(width, height, name); +#endif + } + + // ReSharper disable once UnusedMember.Local + private static void SetResolutionUsingPlayModeWindow(uint width, uint height, string name) + { +#if UNITY_EDITOR && UNITY_2022_2_OR_NEWER + PlayModeWindow.SetViewType(PlayModeWindow.PlayModeViewTypes.GameView); + PlayModeWindow.SetCustomRenderingResolution(width, height, name); +#endif + } + + // ReSharper disable once UnusedMember.Local + private static void SetResolutionUsingReflection(uint width, uint height, string name) + { +#if UNITY_EDITOR + var gameViewSizes = GameViewSizesWrapper.CreateInstance(); + if (gameViewSizes == null) + { + Debug.LogError("GameViewSizes instance creation failed."); + return; + } + + var gameViewSizeGroup = gameViewSizes.CurrentGroup(); + if (gameViewSizeGroup == null) + { + Debug.LogError("GameViewSizeGroup instance creation failed."); + return; + } + + var gameViewSize = GameViewSizeWrapper.CreateInstance((int)width, (int)height, name); + if (gameViewSize == null) + { + Debug.LogError("GameViewSize instance creation failed."); + return; + } + + var index = gameViewSizeGroup.IndexOf(gameViewSize); + if (index == -1) + { + gameViewSizeGroup.AddCustomSize(gameViewSize); + index = gameViewSizeGroup.IndexOf(gameViewSize); + } + + var gameView = GameViewWrapper.GetWindow(); + if (gameView == null) + { + Debug.LogError("GameView instance creation failed."); + return; + } + + gameView.SelectedSizeIndex(index); +#endif + } + } +} diff --git a/RuntimeInternals/GameViewControlHelper.cs.meta b/RuntimeInternals/GameViewControlHelper.cs.meta new file mode 100644 index 0000000..9ffcbc2 --- /dev/null +++ b/RuntimeInternals/GameViewControlHelper.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: dca258adc30341ee8273440832719a07 +timeCreated: 1698664634 \ No newline at end of file diff --git a/RuntimeInternals/ScreenshotHelper.cs b/RuntimeInternals/ScreenshotHelper.cs new file mode 100644 index 0000000..abff0db --- /dev/null +++ b/RuntimeInternals/ScreenshotHelper.cs @@ -0,0 +1,94 @@ +// Copyright (c) 2023 Koji Hasegawa. +// This software is released under the MIT License. + +using System.Collections; +using System.IO; +using System.Runtime.CompilerServices; +using System.Threading; +using UnityEngine; + +namespace TestHelper.RuntimeInternals +{ + /// + /// Helper class for taking a screenshots. + /// This class can be used from the runtime code because it does not depend on test-framework. + /// + public static class ScreenshotHelper + { + private static string DefaultDirectoryPath() + { + return Path.Combine(Application.persistentDataPath, "TestHelper", "Screenshots"); + } + + /// + /// Take a screenshot and save it to file. + /// Default save path is $"{Application.persistentDataPath}/TestHelper/Screenshots/{CurrentTest.Name}.png". + /// + /// + /// Limitations: + /// - Do not call from Edit Mode tests. + /// - Must be called from main thread. + /// - GameView must be visible. Use FocusGameViewAttribute or GameViewResolutionAttribute if running on batch mode. + /// - Files with the same name will be overwritten. Please specify filename argument when calling over twice in one method. + ///
+ /// Using ScreenCapture.CaptureScreenshotAsTexture internally. + ///
+ /// Directory to save screenshots relative to project path. Only effective in Editor. + /// Filename to store screenshot. + /// The factor to increase resolution with. + /// The eye texture to capture when stereo rendering is enabled. + public static IEnumerator TakeScreenshot( + string directory = null, + [CallerMemberName] string filename = null, + int superSize = 1, + ScreenCapture.StereoScreenCaptureMode stereoCaptureMode = ScreenCapture.StereoScreenCaptureMode.LeftEye + ) + { + if (superSize != 1 && stereoCaptureMode != ScreenCapture.StereoScreenCaptureMode.LeftEye) + { + Debug.LogError("superSize and stereoCaptureMode cannot be specified at the same time."); + yield break; + } + + if (filename == null) + { + Debug.LogError("filename must be specified."); + yield break; + } + + if (Thread.CurrentThread.ManagedThreadId != 1) + { + Debug.LogError("Must be called from the main thread."); + yield break; + // Note: This is not the case since it is a coroutine. + } + + if (Application.isEditor && directory != null) + { + directory = Path.GetFullPath(directory); + } + else + { + directory = DefaultDirectoryPath(); // Not apply specific directory when running on player + } + + Directory.CreateDirectory(directory); + + if (!filename.EndsWith(".png")) + { + filename += ".png"; + } + + yield return new WaitForEndOfFrame(); // Required to take screenshots + + var texture = superSize != 1 + ? ScreenCapture.CaptureScreenshotAsTexture(superSize) + : ScreenCapture.CaptureScreenshotAsTexture(stereoCaptureMode); + + var path = Path.Combine(directory, filename); + var bytes = texture.EncodeToPNG(); + File.WriteAllBytes(path, bytes); + Debug.Log($"Save screenshot to {path}"); + } + } +} diff --git a/RuntimeInternals/ScreenshotHelper.cs.meta b/RuntimeInternals/ScreenshotHelper.cs.meta new file mode 100644 index 0000000..241f849 --- /dev/null +++ b/RuntimeInternals/ScreenshotHelper.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4ad549007fda4cfcb2a6a10256cfafef +timeCreated: 1698662890 \ No newline at end of file diff --git a/RuntimeInternals/TestHelper.RuntimeInternals.asmdef b/RuntimeInternals/TestHelper.RuntimeInternals.asmdef new file mode 100644 index 0000000..8807558 --- /dev/null +++ b/RuntimeInternals/TestHelper.RuntimeInternals.asmdef @@ -0,0 +1,14 @@ +{ + "name": "TestHelper.RuntimeInternals", + "rootNamespace": "TestHelper", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": false, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/RuntimeInternals/TestHelper.RuntimeInternals.asmdef.meta b/RuntimeInternals/TestHelper.RuntimeInternals.asmdef.meta new file mode 100644 index 0000000..8c6c097 --- /dev/null +++ b/RuntimeInternals/TestHelper.RuntimeInternals.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e0490a17b54a045cdb67886da745d5ef +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Wrappers.meta b/RuntimeInternals/Wrappers.meta similarity index 100% rename from Runtime/Wrappers.meta rename to RuntimeInternals/Wrappers.meta diff --git a/Runtime/Wrappers/UnityEditor.meta b/RuntimeInternals/Wrappers/UnityEditor.meta similarity index 100% rename from Runtime/Wrappers/UnityEditor.meta rename to RuntimeInternals/Wrappers/UnityEditor.meta diff --git a/Runtime/Wrappers/UnityEditor/GameViewSizeGroupWrapper.cs b/RuntimeInternals/Wrappers/UnityEditor/GameViewSizeGroupWrapper.cs similarity index 93% rename from Runtime/Wrappers/UnityEditor/GameViewSizeGroupWrapper.cs rename to RuntimeInternals/Wrappers/UnityEditor/GameViewSizeGroupWrapper.cs index 16ecbee..a276ee0 100644 --- a/Runtime/Wrappers/UnityEditor/GameViewSizeGroupWrapper.cs +++ b/RuntimeInternals/Wrappers/UnityEditor/GameViewSizeGroupWrapper.cs @@ -6,10 +6,11 @@ using System.Reflection; using UnityEngine; -namespace TestHelper.Wrappers.UnityEditor +namespace TestHelper.RuntimeInternals.Wrappers.UnityEditor { /// - /// Wrapper for UnityEditor.GameViewSizeGroup. + /// Wrapper class for UnityEditor.GameViewSizeGroup. + /// This class can be used from the runtime code because it does not depend on test-framework. /// public class GameViewSizeGroupWrapper { diff --git a/Runtime/Wrappers/UnityEditor/GameViewSizeGroupWrapper.cs.meta b/RuntimeInternals/Wrappers/UnityEditor/GameViewSizeGroupWrapper.cs.meta similarity index 100% rename from Runtime/Wrappers/UnityEditor/GameViewSizeGroupWrapper.cs.meta rename to RuntimeInternals/Wrappers/UnityEditor/GameViewSizeGroupWrapper.cs.meta diff --git a/Runtime/Wrappers/UnityEditor/GameViewSizeWrapper.cs b/RuntimeInternals/Wrappers/UnityEditor/GameViewSizeWrapper.cs similarity index 95% rename from Runtime/Wrappers/UnityEditor/GameViewSizeWrapper.cs rename to RuntimeInternals/Wrappers/UnityEditor/GameViewSizeWrapper.cs index 5f977d0..eb2a652 100644 --- a/Runtime/Wrappers/UnityEditor/GameViewSizeWrapper.cs +++ b/RuntimeInternals/Wrappers/UnityEditor/GameViewSizeWrapper.cs @@ -6,10 +6,11 @@ using System.Reflection; using UnityEngine; -namespace TestHelper.Wrappers.UnityEditor +namespace TestHelper.RuntimeInternals.Wrappers.UnityEditor { /// - /// Wrapper for UnityEditor.GameViewSize. + /// Wrapper class for UnityEditor.GameViewSize. + /// This class can be used from the runtime code because it does not depend on test-framework. /// public class GameViewSizeWrapper { diff --git a/Runtime/Wrappers/UnityEditor/GameViewSizeWrapper.cs.meta b/RuntimeInternals/Wrappers/UnityEditor/GameViewSizeWrapper.cs.meta similarity index 100% rename from Runtime/Wrappers/UnityEditor/GameViewSizeWrapper.cs.meta rename to RuntimeInternals/Wrappers/UnityEditor/GameViewSizeWrapper.cs.meta diff --git a/Runtime/Wrappers/UnityEditor/GameViewSizesWrapper.cs b/RuntimeInternals/Wrappers/UnityEditor/GameViewSizesWrapper.cs similarity index 89% rename from Runtime/Wrappers/UnityEditor/GameViewSizesWrapper.cs rename to RuntimeInternals/Wrappers/UnityEditor/GameViewSizesWrapper.cs index 3fa0016..24c92b5 100644 --- a/Runtime/Wrappers/UnityEditor/GameViewSizesWrapper.cs +++ b/RuntimeInternals/Wrappers/UnityEditor/GameViewSizesWrapper.cs @@ -7,10 +7,11 @@ using UnityEditor; using UnityEngine; -namespace TestHelper.Wrappers.UnityEditor +namespace TestHelper.RuntimeInternals.Wrappers.UnityEditor { /// - /// Wrapper for UnityEditor.GameViewSizes. + /// Wrapper class for UnityEditor.GameViewSizes. + /// This class can be used from the runtime code because it does not depend on test-framework. /// public class GameViewSizesWrapper { diff --git a/Runtime/Wrappers/UnityEditor/GameViewSizesWrapper.cs.meta b/RuntimeInternals/Wrappers/UnityEditor/GameViewSizesWrapper.cs.meta similarity index 100% rename from Runtime/Wrappers/UnityEditor/GameViewSizesWrapper.cs.meta rename to RuntimeInternals/Wrappers/UnityEditor/GameViewSizesWrapper.cs.meta diff --git a/Runtime/Wrappers/UnityEditor/GameViewWrapper.cs b/RuntimeInternals/Wrappers/UnityEditor/GameViewWrapper.cs similarity index 88% rename from Runtime/Wrappers/UnityEditor/GameViewWrapper.cs rename to RuntimeInternals/Wrappers/UnityEditor/GameViewWrapper.cs index fd6a6a8..cca6004 100644 --- a/Runtime/Wrappers/UnityEditor/GameViewWrapper.cs +++ b/RuntimeInternals/Wrappers/UnityEditor/GameViewWrapper.cs @@ -7,8 +7,12 @@ using UnityEditor; using UnityEngine; -namespace TestHelper.Wrappers.UnityEditor +namespace TestHelper.RuntimeInternals.Wrappers.UnityEditor { + /// + /// Wrapper class for UnityEditor.GameView. + /// This class can be used from the runtime code because it does not depend on test-framework. + /// public class GameViewWrapper { private static readonly Assembly s_editorAssembly = Assembly.Load("UnityEditor.dll"); diff --git a/Runtime/Wrappers/UnityEditor/GameViewWrapper.cs.meta b/RuntimeInternals/Wrappers/UnityEditor/GameViewWrapper.cs.meta similarity index 100% rename from Runtime/Wrappers/UnityEditor/GameViewWrapper.cs.meta rename to RuntimeInternals/Wrappers/UnityEditor/GameViewWrapper.cs.meta diff --git a/Tests/Runtime/Attributes/TakeScreenshotAttributeTest.cs b/Tests/Runtime/Attributes/TakeScreenshotAttributeTest.cs index 77f2f98..664ad2c 100644 --- a/Tests/Runtime/Attributes/TakeScreenshotAttributeTest.cs +++ b/Tests/Runtime/Attributes/TakeScreenshotAttributeTest.cs @@ -37,6 +37,16 @@ public void SetUp() [TakeScreenshot] public void Attach_TakeScreenshotAndSaveToDefaultPath() { + var path = Path.Combine( + _defaultOutputDirectory, + $"{nameof(Attach_TakeScreenshotAndSaveToDefaultPath)}.png"); + if (File.Exists(path)) + { + File.Delete(path); + } + + Assume.That(path, Does.Not.Exist); + // Take screenshot after running the test. } @@ -54,6 +64,16 @@ public void Attach_TakeScreenshotAndSaveToDefaultPath_AfterRunningTest_ExistFile [TakeScreenshot] public async Task AttachToAsyncTest_TakeScreenshotAndSaveToDefaultPath() { + var path = Path.Combine( + _defaultOutputDirectory, + $"{nameof(AttachToAsyncTest_TakeScreenshotAndSaveToDefaultPath)}.png"); + if (File.Exists(path)) + { + File.Delete(path); + } + + Assume.That(path, Does.Not.Exist); + await Task.Yield(); // Take screenshot after running the test. } @@ -72,6 +92,16 @@ public void AttachToAsyncTest_TakeScreenshotAndSaveToDefaultPath_AfterRunningTes [TakeScreenshot] public IEnumerator AttachToUnityTest_TakeScreenshotAndSaveToDefaultPath() { + var path = Path.Combine( + _defaultOutputDirectory, + $"{nameof(AttachToUnityTest_TakeScreenshotAndSaveToDefaultPath)}.png"); + if (File.Exists(path)) + { + File.Delete(path); + } + + Assume.That(path, Does.Not.Exist); + yield return null; // Take screenshot after running the test. } @@ -90,6 +120,16 @@ public void AttachToUnityTest_TakeScreenshotAndSaveToDefaultPath_AfterRunningTes [TakeScreenshot(filename: nameof(AttachWithFilename_TakeScreenshotAndSaveToSpecifyPath) + ".png")] public void AttachWithFilename_TakeScreenshotAndSaveToSpecifyPath() { + var path = Path.Combine( + _defaultOutputDirectory, + $"{nameof(AttachWithFilename_TakeScreenshotAndSaveToSpecifyPath)}.png"); + if (File.Exists(path)) + { + File.Delete(path); + } + + Assume.That(path, Does.Not.Exist); + // Take screenshot after running the test. } diff --git a/Tests/Runtime/Utils/ScreenshotHelperTest.cs b/Tests/Runtime/Utils/ScreenshotHelperTest.cs index 625108b..ce4de37 100644 --- a/Tests/Runtime/Utils/ScreenshotHelperTest.cs +++ b/Tests/Runtime/Utils/ScreenshotHelperTest.cs @@ -37,9 +37,15 @@ public void SetUp() [LoadScene(TestScene)] public IEnumerator TakeScreenshot_SaveToDefaultPath() { - yield return ScreenshotHelper.TakeScreenshot(); - var path = Path.Combine(_defaultOutputDirectory, $"{nameof(TakeScreenshot_SaveToDefaultPath)}.png"); + if (File.Exists(path)) + { + File.Delete(path); + } + + Assume.That(path, Does.Not.Exist); + + yield return ScreenshotHelper.TakeScreenshot(); Assert.That(path, Does.Exist); Assert.That(File.ReadAllBytes(path), Has.Length.GreaterThan(FileSizeThreshold)); } @@ -50,10 +56,16 @@ public IEnumerator TakeScreenshot_SaveToDefaultPath() public IEnumerator TakeScreenshot_SpecifyDirectoryInEditor_SaveToSpecifyPath() { const string RelativePath = "Logs/Screenshots"; - yield return ScreenshotHelper.TakeScreenshot(directory: RelativePath); - var path = Path.Combine(Path.GetFullPath(RelativePath), $"{nameof(TakeScreenshot_SpecifyDirectoryInEditor_SaveToSpecifyPath)}.png"); + if (File.Exists(path)) + { + File.Delete(path); + } + + Assume.That(path, Does.Not.Exist); + + yield return ScreenshotHelper.TakeScreenshot(directory: RelativePath); Assert.That(path, Does.Exist); } @@ -64,10 +76,16 @@ public IEnumerator TakeScreenshot_SpecifyDirectoryInEditor_SaveToSpecifyPath() public IEnumerator TakeScreenshot_SpecifyDirectoryOnPlayer_SaveToDefaultPath() { const string RelativePath = "Logs/Screenshots"; - yield return ScreenshotHelper.TakeScreenshot(directory: RelativePath); - var path = Path.Combine(_defaultOutputDirectory, $"{nameof(TakeScreenshot_SpecifyDirectoryOnPlayer_SaveToDefaultPath)}.png"); + if (File.Exists(path)) + { + File.Delete(path); + } + + Assume.That(path, Does.Not.Exist); + + yield return ScreenshotHelper.TakeScreenshot(directory: RelativePath); Assert.That(path, Does.Exist); } @@ -78,24 +96,46 @@ public IEnumerator TakeScreenshot_SpecifyFilename_SaveToSpecifyPath() const string Filename1 = "SpecifyFilename1.png"; const string Filename2 = "SpecifyFilename2.png"; + var path1 = Path.Combine(_defaultOutputDirectory, Filename1); + if (File.Exists(path1)) + { + File.Delete(path1); + } + + var path2 = Path.Combine(_defaultOutputDirectory, Filename2); + if (File.Exists(path2)) + { + File.Delete(path2); + } + + Assume.That(path1, Does.Not.Exist); + Assume.That(path2, Does.Not.Exist); + _text.text = Filename1; yield return ScreenshotHelper.TakeScreenshot(filename: Filename1); _text.text = Filename2; yield return ScreenshotHelper.TakeScreenshot(filename: Filename2); - Assert.That(Path.Combine(_defaultOutputDirectory, Filename1), Does.Exist); - Assert.That(Path.Combine(_defaultOutputDirectory, Filename2), Does.Exist); + // Verify after calling twice + Assert.That(path1, Does.Exist); + Assert.That(path2, Does.Exist); } [UnityTest] [LoadScene(TestScene)] public IEnumerator TakeScreenshot_SpecifySuperSize_SaveSuperSizeFile() { - yield return ScreenshotHelper.TakeScreenshot(superSize: 2); - var path = Path.Combine(_defaultOutputDirectory, $"{nameof(TakeScreenshot_SpecifySuperSize_SaveSuperSizeFile)}.png"); + if (File.Exists(path)) + { + File.Delete(path); + } + + Assume.That(path, Does.Not.Exist); + + yield return ScreenshotHelper.TakeScreenshot(superSize: 2); Assert.That(path, Does.Exist); // Please visually check the file. } @@ -104,11 +144,17 @@ public IEnumerator TakeScreenshot_SpecifySuperSize_SaveSuperSizeFile() [LoadScene(TestScene)] public IEnumerator TakeScreenshot_SpecifyStereoCaptureMode_SaveStereoFile() { - yield return ScreenshotHelper.TakeScreenshot( - stereoCaptureMode: ScreenCapture.StereoScreenCaptureMode.BothEyes); - var path = Path.Combine(_defaultOutputDirectory, $"{nameof(TakeScreenshot_SpecifyStereoCaptureMode_SaveStereoFile)}.png"); + if (File.Exists(path)) + { + File.Delete(path); + } + + Assume.That(path, Does.Not.Exist); + + yield return ScreenshotHelper.TakeScreenshot( + stereoCaptureMode: ScreenCapture.StereoScreenCaptureMode.BothEyes); Assert.That(path, Does.Exist); // Require stereo rendering settings. // See: https://docs.unity3d.com/Manual/SinglePassStereoRendering.html @@ -129,10 +175,16 @@ public IEnumerator TakeScreenshot_Parameterized_SaveAllFiles( [Values(0, 1)] int i, [Values(2, 3)] int j) { - yield return ScreenshotHelper.TakeScreenshot(); - var path = Path.Combine(_defaultOutputDirectory, $"{nameof(TakeScreenshot_Parameterized_SaveAllFiles)}_{i}-{j}_.png"); + if (File.Exists(path)) + { + File.Delete(path); + } + + Assume.That(path, Does.Not.Exist); + + yield return ScreenshotHelper.TakeScreenshot(); Assert.That(path, Does.Exist); } } diff --git a/Tests/RuntimeInternals.meta b/Tests/RuntimeInternals.meta new file mode 100644 index 0000000..5421c7b --- /dev/null +++ b/Tests/RuntimeInternals.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8594f743c83114170a2ad5bb2e8854a3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/RuntimeInternals/ScreenshotHelperTest.cs b/Tests/RuntimeInternals/ScreenshotHelperTest.cs new file mode 100644 index 0000000..d7c7657 --- /dev/null +++ b/Tests/RuntimeInternals/ScreenshotHelperTest.cs @@ -0,0 +1,54 @@ +// Copyright (c) 2023 Koji Hasegawa. +// This software is released under the MIT License. + +using System.Collections; +using System.IO; +using NUnit.Framework; +using TestHelper.Attributes; +using UnityEngine; +using UnityEngine.TestTools; +using UnityEngine.UI; + +namespace TestHelper.RuntimeInternals +{ + [TestFixture] + [GameViewResolution(GameViewResolution.VGA)] + public class ScreenshotHelperTest + { + private const string TestScene = "Packages/com.nowsprinting.test-helper/Tests/Scenes/ScreenshotTest.unity"; + private const int FileSizeThreshold = 5441; // VGA size solid color file size + + private readonly string _defaultOutputDirectory = + Path.Combine(Application.persistentDataPath, "TestHelper", "Screenshots"); + + private Text _text; + + [SetUp] + public void SetUp() + { + var textObject = GameObject.Find("Text"); + Assume.That(textObject, Is.Not.Null); + + _text = textObject.GetComponent(); + _text.text = TestContext.CurrentTestExecutionContext.CurrentTest.Name; + } + + [UnityTest] + [LoadScene(TestScene)] + public IEnumerator TakeScreenshot_SaveToDefaultPath() + { + var path = Path.Combine(_defaultOutputDirectory, $"{nameof(TakeScreenshot_SaveToDefaultPath)}.png"); + if (File.Exists(path)) + { + File.Delete(path); + } + + Assume.That(path, Does.Not.Exist); + + yield return ScreenshotHelper.TakeScreenshot(); // default filename is member name when internal + + Assert.That(path, Does.Exist); + Assert.That(File.ReadAllBytes(path), Has.Length.GreaterThan(FileSizeThreshold)); + } + } +} diff --git a/Tests/RuntimeInternals/ScreenshotHelperTest.cs.meta b/Tests/RuntimeInternals/ScreenshotHelperTest.cs.meta new file mode 100644 index 0000000..ed47ab1 --- /dev/null +++ b/Tests/RuntimeInternals/ScreenshotHelperTest.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1c4b99ec57cb4813b47bb0d5e7e7b714 +timeCreated: 1698664017 \ No newline at end of file diff --git a/Tests/RuntimeInternals/TestHelper.RuntimeInternals.Tests.asmdef b/Tests/RuntimeInternals/TestHelper.RuntimeInternals.Tests.asmdef new file mode 100644 index 0000000..6f39dd9 --- /dev/null +++ b/Tests/RuntimeInternals/TestHelper.RuntimeInternals.Tests.asmdef @@ -0,0 +1,23 @@ +{ + "name": "TestHelper.RuntimeInternals.Tests", + "rootNamespace": "TestHelper", + "references": [ + "UnityEngine.TestRunner", + "UnityEditor.TestRunner", + "TestHelper", + "TestHelper.RuntimeInternals" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "nunit.framework.dll" + ], + "autoReferenced": false, + "defineConstraints": [ + "UNITY_INCLUDE_TESTS" + ], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Tests/RuntimeInternals/TestHelper.RuntimeInternals.Tests.asmdef.meta b/Tests/RuntimeInternals/TestHelper.RuntimeInternals.Tests.asmdef.meta new file mode 100644 index 0000000..a426da4 --- /dev/null +++ b/Tests/RuntimeInternals/TestHelper.RuntimeInternals.Tests.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: de7d8f45001604680a2c3f70f9b68804 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Runtime/Wrappers.meta b/Tests/RuntimeInternals/Wrappers.meta similarity index 100% rename from Tests/Runtime/Wrappers.meta rename to Tests/RuntimeInternals/Wrappers.meta diff --git a/Tests/Runtime/Wrappers/UnityEditor.meta b/Tests/RuntimeInternals/Wrappers/UnityEditor.meta similarity index 100% rename from Tests/Runtime/Wrappers/UnityEditor.meta rename to Tests/RuntimeInternals/Wrappers/UnityEditor.meta diff --git a/Tests/Runtime/Wrappers/UnityEditor/GameViewSizeGroupWrapperTest.cs b/Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewSizeGroupWrapperTest.cs similarity index 97% rename from Tests/Runtime/Wrappers/UnityEditor/GameViewSizeGroupWrapperTest.cs rename to Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewSizeGroupWrapperTest.cs index 4581cb0..6b90bd5 100644 --- a/Tests/Runtime/Wrappers/UnityEditor/GameViewSizeGroupWrapperTest.cs +++ b/Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewSizeGroupWrapperTest.cs @@ -4,7 +4,7 @@ #if UNITY_EDITOR using NUnit.Framework; -namespace TestHelper.Wrappers.UnityEditor +namespace TestHelper.RuntimeInternals.Wrappers.UnityEditor { [TestFixture] public class GameViewSizeGroupWrapperTest diff --git a/Tests/Runtime/Wrappers/UnityEditor/GameViewSizeGroupWrapperTest.cs.meta b/Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewSizeGroupWrapperTest.cs.meta similarity index 100% rename from Tests/Runtime/Wrappers/UnityEditor/GameViewSizeGroupWrapperTest.cs.meta rename to Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewSizeGroupWrapperTest.cs.meta diff --git a/Tests/Runtime/Wrappers/UnityEditor/GameViewSizeWrapperTest.cs b/Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewSizeWrapperTest.cs similarity index 97% rename from Tests/Runtime/Wrappers/UnityEditor/GameViewSizeWrapperTest.cs rename to Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewSizeWrapperTest.cs index 25ef389..03d1f23 100644 --- a/Tests/Runtime/Wrappers/UnityEditor/GameViewSizeWrapperTest.cs +++ b/Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewSizeWrapperTest.cs @@ -7,7 +7,7 @@ using System.Reflection; using NUnit.Framework; -namespace TestHelper.Wrappers.UnityEditor +namespace TestHelper.RuntimeInternals.Wrappers.UnityEditor { [TestFixture] [SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure")] diff --git a/Tests/Runtime/Wrappers/UnityEditor/GameViewSizeWrapperTest.cs.meta b/Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewSizeWrapperTest.cs.meta similarity index 100% rename from Tests/Runtime/Wrappers/UnityEditor/GameViewSizeWrapperTest.cs.meta rename to Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewSizeWrapperTest.cs.meta diff --git a/Tests/Runtime/Wrappers/UnityEditor/GameViewSizesWrapperTest.cs b/Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewSizesWrapperTest.cs similarity index 91% rename from Tests/Runtime/Wrappers/UnityEditor/GameViewSizesWrapperTest.cs rename to Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewSizesWrapperTest.cs index 3e616a3..2859072 100644 --- a/Tests/Runtime/Wrappers/UnityEditor/GameViewSizesWrapperTest.cs +++ b/Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewSizesWrapperTest.cs @@ -4,7 +4,7 @@ #if UNITY_EDITOR using NUnit.Framework; -namespace TestHelper.Wrappers.UnityEditor +namespace TestHelper.RuntimeInternals.Wrappers.UnityEditor { [TestFixture] public class GameViewSizesWrapperTest diff --git a/Tests/Runtime/Wrappers/UnityEditor/GameViewSizesWrapperTest.cs.meta b/Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewSizesWrapperTest.cs.meta similarity index 100% rename from Tests/Runtime/Wrappers/UnityEditor/GameViewSizesWrapperTest.cs.meta rename to Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewSizesWrapperTest.cs.meta diff --git a/Tests/Runtime/Wrappers/UnityEditor/GameViewWrapperTest.cs b/Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewWrapperTest.cs similarity index 92% rename from Tests/Runtime/Wrappers/UnityEditor/GameViewWrapperTest.cs rename to Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewWrapperTest.cs index 10ada67..bc5b3a6 100644 --- a/Tests/Runtime/Wrappers/UnityEditor/GameViewWrapperTest.cs +++ b/Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewWrapperTest.cs @@ -4,7 +4,7 @@ #if UNITY_EDITOR using NUnit.Framework; -namespace TestHelper.Wrappers.UnityEditor +namespace TestHelper.RuntimeInternals.Wrappers.UnityEditor { [TestFixture] public class GameViewWrapperTest diff --git a/Tests/Runtime/Wrappers/UnityEditor/GameViewWrapperTest.cs.meta b/Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewWrapperTest.cs.meta similarity index 100% rename from Tests/Runtime/Wrappers/UnityEditor/GameViewWrapperTest.cs.meta rename to Tests/RuntimeInternals/Wrappers/UnityEditor/GameViewWrapperTest.cs.meta