This skill should be used when the user asks about "tests", "unit tests", "EditMode tests", "PlayMode tests", "Test Runner", "test coverage", "NUnit", "Assert", "test fixtures", "writing tests", "running tests", or discusses Unity testing patterns and practices.
Provides Unity testing expertise for EditMode and PlayMode tests, including test structure, NUnit assertions, and execution via MCP. Triggers when users discuss tests, TDD, or need help writing/running Unity tests.
/plugin marketplace add jwmyers/vui-vux-plugins/plugin install zero-day-dev@vui-vuxThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Expert knowledge of Unity testing patterns, EditMode/PlayMode tests, and test-driven development for the Zero-Day Attack project.
Run without entering Play mode - fast iteration:
| Property | Value |
|---|---|
| Location | Assets/Tests/Editor/ |
| Assembly | *.Tests.Editor.asmdef |
| Speed | Fast (no scene loading) |
| Use For | Pure logic, data validation, calculations |
Run in simulated Play mode - test runtime behavior:
| Property | Value |
|---|---|
| Location | Assets/Tests/Runtime/ |
| Assembly | *.Tests.Runtime.asmdef |
| Speed | Slower (scene setup required) |
| Use For | MonoBehaviour, scene interactions, integration |
Assets/Tests/
├── Editor/
│ ├── BoardLayoutConfigTests.cs # LayoutConfig validation
│ └── TileDatabaseTests.cs # Database integrity
└── Runtime/
├── CoordinateConversionTests.cs # Grid-to-world conversion
└── GameInitializationTests.cs # Startup and state
using NUnit.Framework;
using ZeroDayAttack.Config;
namespace ZeroDayAttack.Tests.Editor
{
[TestFixture]
public class LayoutConfigTests
{
[Test]
public void GridSize_ShouldBeFive()
{
Assert.AreEqual(5, LayoutConfig.GridSize);
}
[Test]
public void ScreenDimensions_ShouldMatch1920x1080()
{
// At 100 PPU: 1920/100 = 19.2, 1080/100 = 10.8
Assert.AreEqual(19.2f, LayoutConfig.ScreenWidth, 0.001f);
Assert.AreEqual(10.8f, LayoutConfig.ScreenHeight, 0.001f);
}
[Test]
public void CameraOrthoSize_ShouldBeHalfHeight()
{
float expectedOrtho = LayoutConfig.ScreenHeight / 2f;
Assert.AreEqual(expectedOrtho, LayoutConfig.CameraOrthoSize, 0.001f);
}
}
}
using NUnit.Framework;
using UnityEngine;
using ZeroDayAttack.Core.Data;
namespace ZeroDayAttack.Tests.Editor
{
[TestFixture]
public class TileDatabaseTests
{
private TileDatabase database;
[OneTimeSetUp]
public void LoadDatabase()
{
database = Resources.Load<TileDatabase>("TileDatabase");
}
[Test]
public void Database_ShouldLoad()
{
Assert.IsNotNull(database, "TileDatabase not found in Resources");
}
[Test]
public void Database_ShouldHave25Tiles()
{
Assert.AreEqual(25, database.Tiles.Count);
}
[Test]
public void AllTiles_ShouldHaveSprites()
{
foreach (var tile in database.Tiles)
{
Assert.IsNotNull(tile.TileSprite,
$"Tile {tile.TileId} missing sprite");
}
}
}
}
using System.Collections;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using ZeroDayAttack.View;
namespace ZeroDayAttack.Tests.Runtime
{
[TestFixture]
public class TileManagerTests
{
private TileManager tileManager;
[UnitySetUp]
public IEnumerator SetUp()
{
// Create test object
var go = new GameObject("TileManager");
tileManager = go.AddComponent<TileManager>();
yield return null; // Wait one frame
}
[UnityTearDown]
public IEnumerator TearDown()
{
if (tileManager != null)
{
Object.Destroy(tileManager.gameObject);
}
yield return null;
}
[UnityTest]
public IEnumerator Instance_ShouldBeSet()
{
yield return null;
Assert.IsNotNull(TileManager.Instance);
}
[UnityTest]
public IEnumerator GridToWorld_CenterTile_ShouldBeAtOrigin()
{
yield return null;
var worldPos = tileManager.GetWorldPosition(2, 2);
Assert.AreEqual(0f, worldPos.x, 0.001f);
Assert.AreEqual(0f, worldPos.y, 0.001f);
}
}
}
using UnityEngine.SceneManagement;
[UnityTest]
public IEnumerator GameplayScene_ShouldLoad()
{
SceneManager.LoadScene("GameplayScene");
yield return null; // Wait for load
var gameManager = GameObject.FindObjectOfType<GameManager>();
Assert.IsNotNull(gameManager);
}
Assert.AreEqual(expected, actual);
Assert.AreEqual(expected, actual, delta); // For floats
Assert.AreNotEqual(notExpected, actual);
Assert.IsTrue(condition);
Assert.IsFalse(condition);
Assert.IsNull(obj);
Assert.IsNotNull(obj);
Assert.Contains(item, collection);
Assert.IsEmpty(collection);
Assert.IsNotEmpty(collection);
CollectionAssert.AreEqual(expected, actual);
CollectionAssert.AreEquivalent(expected, actual); // Order-independent
Assert.Throws<ArgumentException>(() => {
SomeMethod(invalidArg);
});
Assert.DoesNotThrow(() => {
SomeMethod(validArg);
});
{
"testMode": "EditMode"
}
{
"testMode": "EditMode",
"testClass": "LayoutConfigTests"
}
{
"testMode": "EditMode",
"testMethod": "ZeroDayAttack.Tests.Editor.LayoutConfigTests.GridSize_ShouldBeFive"
}
{
"testMode": "EditMode",
"includePassingTests": false, // Only show failures
"includeMessages": true, // Include assertion messages
"includeStacktrace": true, // Include stack traces
"includeLogs": true // Include console logs
}
Method_Scenario_ExpectedResult[Test] public void GridToWorld_CenterTile_ReturnsOrigin() { }
[Test] public void PlaceTile_InvalidPosition_ThrowsException() { }
[Test] public void MoveToken_ValidPath_UpdatesPosition() { }
public class GameManagerTests { } // Tests for GameManager
public class TileValidationTests { } // Tests for tile validation logic
public class PathFindingTests { } // Tests for path algorithms
Organize tests with categories:
[Test]
[Category("FastTests")]
public void QuickCalculation_Test() { }
[Test]
[Category("Integration")]
public void SceneSetup_Test() { }
Run by category:
{
"testMode": "EditMode",
"testCategory": "FastTests"
}
[Test]
public void PathSegment_RotateBy90_UpdatesNodes()
{
// Arrange
var segment = new PathSegment(EdgeNode.Left, EdgeNode.Top, PathColor.Blue);
// Act
var rotated = segment.Rotate(90);
// Assert
Assert.AreEqual(EdgeNode.Top, rotated.From);
Assert.AreEqual(EdgeNode.Right, rotated.To);
}
// Good: Focused tests
[Test] public void Tile_HasCorrectWidth() { }
[Test] public void Tile_HasCorrectHeight() { }
// OK for related properties
[Test]
public void Tile_HasCorrectDimensions()
{
Assert.AreEqual(2.0f, tile.Width);
Assert.AreEqual(2.0f, tile.Height);
}
Each test should be independent:
[SetUp] for common initialization[TearDown] for cleanupPrefer EditMode tests when possible:
Tests LayoutConfig constants:
Tests TileDatabase integrity:
Tests TileManager coordinate conversion:
Tests game startup:
For test examples:
Window > General > Test Runner
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.