# Unity Test Framework Guide ## Overview Unity provides a built-in Test Framework based on NUnit for writing and running automated tests. It supports Edit Mode tests (run without playing) and Play Mode tests (run during gameplay simulation). ## Test Framework Setup ### Package Installation ```json // manifest.json - usually pre-installed { "dependencies": { "com.unity.test-framework": "1.6.0" } } ``` ### Project Structure ``` Assets/ ├── Scripts/ │ └── Runtime/ │ ├── Player/ │ │ └── PlayerController.cs │ └── Combat/ │ └── DamageCalculator.cs └── Tests/ ├── EditMode/ │ └── DamageCalculatorTests.cs └── PlayMode/ └── PlayerMovementTests.cs ``` ### Assembly Definitions Create `.asmdef` files for test assemblies: ```json // Tests/EditMode/EditModeTests.asmdef { "name": "EditModeTests", "references": ["GameAssembly"], "includePlatforms": ["Editor"], "defineConstraints": ["UNITY_INCLUDE_TESTS"] } // Tests/PlayMode/PlayModeTests.asmdef { "name": "PlayModeTests", "references": ["GameAssembly"], "includePlatforms": [], "defineConstraints": ["UNITY_INCLUDE_TESTS"] } ``` ## Edit Mode Tests Edit Mode tests run in the Editor without entering Play Mode. Best for testing pure logic. ### Basic Test Structure ```csharp using NUnit.Framework; [TestFixture] public class DamageCalculatorTests { private DamageCalculator _calculator; [SetUp] public void Setup() { _calculator = new DamageCalculator(); } [Test] public void Calculate_BaseDamage_ReturnsCorrectValue() { float result = _calculator.Calculate(100f, 1f); Assert.AreEqual(100f, result); } [Test] public void Calculate_CriticalHit_DoublesDamage() { float result = _calculator.Calculate(100f, multiplier: 2f); Assert.AreEqual(200f, result); } [TestCase(100f, 0.5f, 50f)] [TestCase(100f, 1.5f, 150f)] [TestCase(50f, 2f, 100f)] public void Calculate_Parameterized_ReturnsExpected( float base_, float mult, float expected) { Assert.AreEqual(expected, _calculator.Calculate(base_, mult)); } } ``` ### Testing ScriptableObjects ```csharp [Test] public void WeaponStats_DPS_CalculatesCorrectly() { var weapon = ScriptableObject.CreateInstance(); weapon.baseDamage = 10f; weapon.attacksPerSecond = 2f; Assert.AreEqual(20f, weapon.DPS); // Cleanup Object.DestroyImmediate(weapon); } ``` ## Play Mode Tests Play Mode tests run during gameplay simulation. Required for testing MonoBehaviours, physics, and runtime behavior. ### Basic Play Mode Test ```csharp using System.Collections; using NUnit.Framework; using UnityEngine; using UnityEngine.TestTools; public class PlayerMovementTests { private GameObject _player; private PlayerController _controller; [SetUp] public void Setup() { _player = new GameObject("Player"); _controller = _player.AddComponent(); _player.AddComponent(); _player.AddComponent(); } [TearDown] public void TearDown() { Object.Destroy(_player); } [UnityTest] public IEnumerator Move_WhenInputApplied_ChangesPosition() { Vector3 startPos = _player.transform.position; _controller.SetInput(Vector2.right); yield return new WaitForSeconds(0.5f); Assert.Greater(_player.transform.position.x, startPos.x); } [UnityTest] public IEnumerator Jump_WhenGrounded_BecomesAirborne() { // Setup ground var ground = GameObject.CreatePrimitive(PrimitiveType.Plane); _player.transform.position = Vector3.up; yield return new WaitForFixedUpdate(); _controller.Jump(); yield return new WaitForSeconds(0.1f); Assert.IsFalse(_controller.IsGrounded); Object.Destroy(ground); } } ``` ### Testing Coroutines ```csharp [UnityTest] public IEnumerator Attack_Cooldown_PreventsSpam() { _controller.Attack(); Assert.IsTrue(_controller.IsAttacking); _controller.Attack(); // Should be blocked Assert.AreEqual(1, _controller.AttackCount); yield return new WaitForSeconds(_controller.AttackCooldown + 0.1f); _controller.Attack(); Assert.AreEqual(2, _controller.AttackCount); } ``` ### Scene Testing ```csharp using UnityEngine.SceneManagement; [UnityTest] public IEnumerator MainMenu_StartButton_LoadsGameScene() { SceneManager.LoadScene("MainMenu"); yield return null; // Wait for scene load var startButton = GameObject.Find("StartButton") .GetComponent