-
Notifications
You must be signed in to change notification settings - Fork 0
Creating Your First Test
Step-by-step guide to creating and running your first UIAutomation test.
UIAutomation tests use Unity's standard NUnit test framework with async/await:
using System.Threading.Tasks;
using NUnit.Framework;
using UnityEngine.TestTools;
using static ODDGames.UIAutomation.ActionExecutor;
[TestFixture]
public class MyTests
{
[Test]
public async Task MyFirstTest()
{
await LoadScene("MainMenuScene");
await Click(Name("PlayButton"));
await WaitFor(Name("GameScene"), seconds: 5);
}
}The using static ODDGames.UIAutomation.ActionExecutor; directive imports all static members directly into your test class. This means you can write:
// With 'using static' - clean and readable
await Click(Name("Button"));
await TextInput(Adjacent("Username:"), "test");
await WaitFor(Text("Welcome"), seconds: 5);Instead of:
// Without 'using static' - verbose
await ActionExecutor.Click(ActionExecutor.Name("Button"));
await ActionExecutor.TextInput(ActionExecutor.Adjacent("Username:"), "test");
await ActionExecutor.WaitFor(ActionExecutor.Text("Welcome"), seconds: 5);The static import gives you direct access to:
-
Search helpers:
Name(),Text(),Type<T>(),Adjacent(),Near(),Path(),Tag(),Texture(),Any(),Reflect() -
Actions:
Click(),DoubleClick(),Hold(),TextInput(),Drag(),DragTo(),Swipe(),Scroll() -
Waits:
Wait(),WaitFor(),WaitFramerate() -
Finders:
Find<T>(),FindAll<T>(),ScrollTo() -
Scene:
LoadScene()
Create a new C# script in your project's Assets/Tests/PlayMode/ folder:
using System.Threading.Tasks;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using static ODDGames.UIAutomation.ActionExecutor;
[TestFixture]
public class MyFirstTests
{
[Test]
public async Task MyFirstTest()
{
Debug.Log("Test started!");
await Wait(seconds: 1);
Debug.Log("Test completed!");
}
}Ensure you have a test assembly definition:
- Create
Assets/Tests/PlayMode/Tests.asmdef - Configure it to reference:
ODDGames.UIAutomationUnityEngine.TestRunnernunit.framework
- Open Window > General > Test Runner
- Select PlayMode tab
- Click Run All or select your test and click Run Selected
Here's a simple test that navigates a menu:
[TestFixture]
public class NavigationTests
{
[Test]
public async Task UserCanAccessSettings()
{
await LoadScene("MainMenuScene");
// Click the Settings button
await Click(Name("SettingsButton"));
// Wait for Settings panel to appear
await WaitFor(Name("SettingsPanel"), seconds: 5);
// Click Back to return
await Click(Name("BackButton"));
// Verify we're back at main menu
await WaitFor(Name("MainMenu"), seconds: 5);
}
}Test that fills out a form:
[TestFixture]
public class FormTests
{
[Test]
public async Task UserCanSubmitContactForm()
{
await LoadScene("ContactScene");
// Navigate to form
await Click(Name("ContactUsButton"));
// Fill out fields using adjacent labels
await TextInput(Adjacent("Name:"), "John Doe");
await TextInput(Adjacent("Email:"), "john@example.com");
await TextInput(Adjacent("Message:"), "Hello world!");
// Submit
await Click(Name("SendButton"));
// Verify success
await WaitFor(Text("Message sent!"), seconds: 10);
}
}Use descriptive names that explain the scenario:
[Test]
public async Task Login_WithValidCredentials_ShowsMainMenu() { }
[Test]
public async Task Login_WithInvalidPassword_ShowsErrorMessage() { }Keep tests focused on a single user flow:
// Good - single focused scenarios
public async Task AddItemToCart_IncreasesCartCount() { }
public async Task RemoveItemFromCart_DecreasesCartCount() { }
public async Task Checkout_WithEmptyCart_ShowsWarning() { }
// Avoid - multiple scenarios in one test
public async Task CartTests() { } // Does too many thingsAlways wait for UI elements before interacting:
// Good
await Click(Name("OpenDialogButton"));
await WaitFor(Name("Dialog"), seconds: 5);
await Click(Name("ConfirmButton"));
// Risky - dialog might not be ready
await Click(Name("OpenDialogButton"));
await Click(Name("ConfirmButton")); // May fail if dialog hasn't appearedUse NUnit's setup attributes for common setup:
[TestFixture]
public class GameplayTests
{
[SetUp]
public void SetUp()
{
// Reset game state before each test
PlayerPrefs.DeleteAll();
}
[TearDown]
public void TearDown()
{
// Clean up after each test
}
[Test]
public async Task SomeTest()
{
await LoadScene("GameScene");
// Test code...
}
}Add logging to understand test flow:
[Test]
public async Task LoginTest()
{
Debug.Log("Starting login test");
await Click(Name("LoginButton"));
Debug.Log("Clicked login button");
await TextInput(Adjacent("Username:"), "testuser");
Debug.Log("Entered username");
// ...
}- Search Queries - Learn element finding strategies
- Test Actions - All available test actions
- Best Practices - Writing maintainable tests
Basic Filters
Proximity
Hierarchy
Spatial
Ordering
Modifiers
Combining
Reflection
- Click Actions
- Text Input
- Drag Actions
- Gesture Input
- Wait and Find
- Assertions
- GameObject Manipulation