# 1. Test Assemblies and the Test Runner
Part of [[Unity Test Framework]]. Next: [[2. Edit Mode Tests and NUnit]].
> [!note] Verification status
> Test Runner menu path (**Window > General > Test Runner**) and the **Assets > Create > Testing > Test Assembly Folder** flow were checked against the Unity 6000.5 "Create a test assembly" page on 2026-11-10. Test Framework is a core package on 6000.5. **No project was opened to click through the window.** Code not compiled.
## 1.1 Why bother, in a class and in a shipped project
A test is a small program that arranges a situation, acts on production code, and asserts what should be true afterwards. In a teaching studio that means:
- Students can change a damage formula or an inventory stack rule and know immediately whether the old examples still hold.
- You can refactor a messy `Player` into a testable `Health` type without playing the whole scene after every edit.
- CI (the Build Automation tutorial that follows this one) can fail a pull request that breaks a rule, even if the scene still "looks fine."
Tests do **not** replace play-testing. They are terrible at "does the jump feel right?" and excellent at "does coyote time last 0.1 seconds, and can the player still jump for that window?"
## 1.2 Edit Mode vs Play Mode vs a Player
| Mode | What it can touch | Speed | When to use it |
|---|---|---|---|
| **Edit Mode** | Plain C#, `ScriptableObject.CreateInstance`, most Editor APIs, asset database (carefully) | Fast; no Play Mode domain reload | Pure logic, math, serialization, editor utilities |
| **Play Mode** (in Editor) | Scenes, `MonoBehaviour` lifecycle, physics, nav, audio, UI | Slower; enters Play Mode | Behaviour that only exists while playing |
| **Play Mode in a Player** | A standalone (or device) build that runs the same Play Mode tests | Slowest; the most honest | Platform-specific bugs, IL2CPP stripping, Quest/Android |
Start in Edit Mode whenever you can. If a test needs `Time.deltaTime`, a collider contact, or an Animator state, it belongs in Play Mode.
Unity decides the mode from the **test assembly**, not from an attribute on the method. An assembly that only references `nunit.framework.dll` and `UnityEngine.TestRunner`, and is set to **Editor** only, is an Edit Mode assembly. Adding a non-Editor platform (or "Any Platform") lets Play Mode tests in that assembly also run in a Player.
## 1.3 Create a test assembly
1. In the Project window, select the folder that should own the tests (a good default is a top-level `Assets/Tests/` folder, or `Assets/Inventory/Tests/` next to the code it covers).
2. Open **Window > General > Test Runner**.
3. Click **Create a new Test Assembly Folder in the active path**.
Or skip the window: **Assets > Create > Testing > Test Assembly Folder**.
Unity creates a folder (first one is named `Tests`) and an `.asmdef` that already references:
- `nunit.framework.dll`
- `UnityEngine.TestRunner`
- `UnityEditor.TestRunner` (Editor-only; required for Edit Mode)
That combination is what makes the assembly a **test assembly**. The Inspector's **Platforms** list defaults to **Editor** only. Leave that for Edit Mode tests. For Play Mode tests that must also run in a standalone Player, enable **Any Platform** or the platforms you care about (Windows, Android, …).
> [!warning] Do not "enable Play Mode tests for all assemblies"
> That project setting is deprecated. The Test Framework changelog (1.1.21) removed it from the Test Runner UI. Put tests in test assemblies.
Rename the folder and the `.asmdef` **Name** (in the Inspector, not only the filename) to something unique, such as `Studio.Inventory.Tests`. Assembly names must be unique in the project.
## 1.4 Recommended layout
Keep tests out of the player build by leaving them in test assemblies (Unity defines `UNITY_TEST_FRAMEWORK` and strips these from normal player builds). A layout that scales in class:
```
Assets/
Inventory/
Runtime/ # Studio.Inventory.asmdef — gameplay code
Tests/ # Studio.Inventory.Tests.asmdef — Edit Mode
Character/
Runtime/
Tests/
Tests/
PlayMode/ # Studio.PlayMode.Tests.asmdef — scene-level tests
Performance/ # optional, references the Performance testing API
```
Each tests asmdef **references the runtime asmdef** it is testing, plus the Test Runner references Unity already added. Do not put production gameplay code into a test assembly.
If you already use assembly definitions in production ([[Architecture and Code Patterns]]), tests are just one more asmdef with a test constraint. If you do not, adding the first test assembly is a good moment to put `Runtime` code in its own asmdef so tests can reference it without referencing everything.
## 1.5 The Test Runner window
**Window > General > Test Runner** has tabs for **EditMode** and **PlayMode** (and a path for running in a Player). You can:
- Run all, run a category, or run a selected test
- See duration and output for a suite
- Retry / repeat failed tests from the UI
- Build a Player that contains all or selected Play Mode tests
After you add your first `[Test]` method and let scripts compile, the tree fills in. If it doesn't, you are usually missing an asmdef reference or the file is not inside the test folder.
## 1.6 What this series will not do
- It will not install Test Framework from Package Manager. On 6000.5 it is already there as a core package.
- It will not use the deprecated "Play Mode tests in every assembly" switch.
- It will not treat UI Toolkit query APIs from the **UI Test Framework** core package as settled — that package is noted in [[7. Test Framework Pitfalls]], not used in the worked example.
## Official docs
- Create a test assembly: https://docs.unity.com/en-us/engine/6000.5/manual/scripting/test-framework-introduction/getting-started/workflow-create-test-assembly
- Running tests: https://docs.unity.com/en-us/engine/6000.5/manual/scripting/test-framework-introduction/running-tests
- Core packages: https://docs.unity.com/en-us/engine/6000.5/manual/packages-list/packages-all/pack-core