If you’re knee-deep in a Unity project and pulling your hair out trying to set up unit testing, you’re not alone. The two biggest challenges are dealing with Assembly Definitions and Editor folders. Here’s a guide to overcome these issues and make your life easier.
The Problem
Unity, in its infinite wisdom, doesn’t allow writing tests on the default Assembly-CSharp and Assembly-CSharp-Editor assemblies. Frustrating, right?
To fix this, you need to add Assembly Definitions for both your game code and editor code. Here’s how:
-
Game Code:
- Add an
Assembly Definitionat the root of your project. - Update the dependencies in the Inspector until there are no compiler errors. Off to the races!
- Add an
-
Editor Code:
- Here’s where it gets tricky. In a big project, you’ll have lots of external dependencies and plugins, some with
Assembly Definitions, some without. - Without
Assembly Definitions, Unity sees theseEditorfolders as game code and tries to build them into your final game, which inevitably fails.
- Here’s where it gets tricky. In a big project, you’ll have lots of external dependencies and plugins, some with
The Solution
-
Create a Top-Level Editor Folder:
- At the top level of your project, create an
Editorfolder. - Add an
Assembly Definitioninside this folder. Name it similarly to your game codeAssembly Definitionbut with a.Editorpostfix (or whatever you prefer).
- At the top level of your project, create an
-
Link Editor Folders:
- For each
Editorfolder in your project, create anAssembly Definition Referenceand link it to the top-levelEditorfolderAssembly Definition. - This process can be incredibly tedious in a large project, so here’s a Python script to save you from hours of mind-numbing work:
- For each
import os
import json
import yaml
def get_guid_from_meta(meta_file_path):
with open(meta_file_path, 'r') as meta_file:
meta_content = yaml.safe_load(meta_file)
return meta_content.get('guid')
def create_reference_json(editor_path, source_file_name, guid):
json_content = {
"reference": "GUID:" + guid
}
asmref_file_name = os.path.splitext(source_file_name)[0] + '.asmref'
json_file_path = os.path.join(editor_path, asmref_file_name)
with open(json_file_path, 'w') as json_file:
json.dump(json_content, json_file, indent=4)
print(f"Created {json_file_path} with GUID reference.")
def copy_file_to_editor_folders(unity_project_path, source_file):
if not os.path.isdir(unity_project_path):
print(f"The project path {unity_project_path} does not exist.")
return
meta_file_path = source_file + '.meta'
if not os.path.isfile(meta_file_path):
print(f"The meta file {meta_file_path} does not exist.")
return
guid = get_guid_from_meta(meta_file_path)
source_file_name = os.path.basename(source_file)
for root, dirs, files in os.walk(unity_project_path):
if 'Editor' in dirs:
editor_path = os.path.join(root, 'Editor')
asmdef_exists = any(file.endswith('.asmdef') for file in os.listdir(editor_path))
if not asmdef_exists:
create_reference_json(editor_path, source_file_name, guid)
else:
print(f"A .asmdef file already exists in the folder {editor_path}.")
# Example usage
unity_project_path = r"PATH\TO\ASSETS\FOLDER"
source_file = r"PATH\TO\Editor.asmdef"
copy_file_to_editor_folders(unity_project_path, source_file)
This script requires pyyaml to run:
pip install pyyaml
- Set
unity_project_pathto your Unity project’s assets folder. - Set
source_fileto the path of yourEditorAssembly Definition.
The script will:
- Crawl your project for all
Editorfolders. - Check if an
Assembly Definitionis present. - Add an
Assembly Definition Referenceif none exists.
After setting this up, follow the Unity Testing Framework tutorial to start writing tests.
Additional Tips
Consider splitting your code with Assembly Definitions to create logical boundaries and improve maintainability. It might be a pain now, but your future self will thank you!
Happy testing!

Top comments (0)