Skip to main content

AltTester® for Unreal Engine

This page walks you through running AltTester-driven C# tests against an Unreal Engine game on Sauce Labs real devices. For background on what AltTester® is and how it talks to Sauce, see the AltTester® overview.

There are two ways to connect your tests to the game running on a Sauce real device:

  • Sauce Connect Proxy tunnel (recommended) — run AltTester® Desktop locally and let the tunnel forward localhost to the device.
  • Public VM — host AltTester® Desktop on a publicly reachable virtual machine.

This page follows the Sauce Connect path and summarizes the VM alternative at the end.

Prerequisites​

  • An active Sauce Labs account.
  • An Unreal Engine project that you can build for Android or iOS.
  • AltTester® Unreal SDK 1.1 or later — download the AltTester® Plugin from the AltTester® website. See the Get Started guide for full instructions.
  • AltTester-Driver 2.3 or later — .NET NuGet package AltTester-Driver. The same package is used for Unity and Unreal tests.
  • Appium.WebDriver 8 or later — .NET NuGet package Appium.WebDriver.
  • AltTester® Desktop, installed locally and listening on its default port 13000. Can be downloaded from the AltTester® website.
  • Sauce Connect Proxy client installed and available in your PATH (the sc command). See Sauce Connect.

Instrument Your Unreal Build​

  1. Download the AltTester® Unreal SDK from the AltTester® website
  2. Set up the AltTester® Unreal SDK in your project following the AltTester® documentation
  3. Open the project in Unreal Editor. The editor regenerates project files and prompts to rebuild any missing modules — accept the rebuild.
  4. In Edit → Plugins, confirm the AltTester® plugin is listed and enabled. Restart the editor if prompted.
  5. Configure the AltTester® connection settings:
    • Sauce Connect path (recommended): keep the default settings — host 127.0.0.1, port 13000. The tunnel forwards localhost from the device to your machine.
    • Public VM path: enter the VM's reachable IP address instead.
  6. In Project Settings → Platforms, ensure the appropriate network permissions are configured for your target platform (Android: INTERNET permission; iOS: appropriate network entitlement).
  7. Package the project for your target platform (Android .apk or iOS .ipa) via File → Package Project.
  8. Smoke-test the instrumented build locally by launching it on a USB-connected device and connecting AltTester® Desktop. Confirm the widget tree and actors appear in the desktop client.

Upload the Build to Sauce Labs​

Upload your instrumented .apk or .ipa to Sauce Labs App Storage. See App Storage for the upload UI and API options. Note the filename — you'll reference it in capabilities as storage:filename=<your-build.apk>.

Set Up Your C# Test Project​

In an empty .NET project:

dotnet new nunit -n MyGameTests
cd MyGameTests
dotnet add package AltTester-Driver
dotnet add package Appium.WebDriver

The same AltTester-Driver NuGet package is used for Unity and Unreal tests, under the shared AltTester.AltTesterSDK.Driver namespace.

Confirm the installed versions match (or exceed) the floors listed in Prerequisites.

Set Environment Variables​

Keep credentials out of your test code:

export SAUCE_USERNAME="<your-username>"
export SAUCE_ACCESS_KEY="<your-access-key>"
export SAUCE_APP_URL="storage:filename=<your-game.apk>"
export SAUCE_REGION="eu-central-1"

For other data centers, set SAUCE_REGION to us-west-1 or us-east-4.

Start the Sauce Connect Tunnel​

Start AltTester® Desktop locally, then launch the tunnel:

sc run --username $SAUCE_USERNAME --access-key $SAUCE_ACCESS_KEY \
--region $SAUCE_REGION --tunnel-name alttester-tunnel \
--proxy-localhost allow
--proxy-localhost allow is required

Without this flag, the cloud device cannot reach the AltTester® Server running on your machine, and the AltDriver connection will time out even though the Appium session starts normally.

Configure Appium Capabilities​

The following examples show W3C capabilities for an Android and an iOS Unreal Engine game. Replace the placeholder values (<...>) with your target device and platform version.

var sauceUsername = Environment.GetEnvironmentVariable("SAUCE_USERNAME");
var sauceAccessKey = Environment.GetEnvironmentVariable("SAUCE_ACCESS_KEY");
var sauceRegion = Environment.GetEnvironmentVariable("SAUCE_REGION");

var capabilities = new AppiumOptions();
capabilities.PlatformName = "Android";
capabilities.App = Environment.GetEnvironmentVariable("SAUCE_APP_URL");
capabilities.DeviceName = "Google Pixel.*";
capabilities.AutomationName = "UiAutomator2";
capabilities.AddAdditionalAppiumOption("appium:autoGrantPermissions", true);

var sauceOptions = new Dictionary<string, object>
{
{ "username", sauceUsername },
{ "accessKey", sauceAccessKey },
{ "tunnelName", "alttester-tunnel" },
{ "tunnelOwner", sauceUsername },
{ "appiumVersion", "stable" },
{ "name", "AltTester® Unreal sample test" },
};
capabilities.AddAdditionalAppiumOption("sauce:options", sauceOptions);

var sauceUrl = new Uri($"https://ondemand.{sauceRegion}.saucelabs.com:443/wd/hub");
var driver = new AndroidDriver(sauceUrl, capabilities);
iOS WebDriverAgent change

Starting with appium3-2026-01, iOS sessions on Sauce Labs real devices use the official Appium WebDriverAgent instead of the Sauce Labs fork (SauceWebDriverAgent). Setting sauce:options.appiumVersion to stable will pick up this image once it becomes the default. Some XCUITest endpoints may behave differently — see Appium Testing with Real Devices for details.

Connect the AltTester® Driver​

After the Appium session starts and the game has launched, connect the AltTester® C# driver. Because the Sauce Connect tunnel forwards localhost, the driver connects with its default host and port — no custom IP needed:

using AltTester.AltTesterSDK.Driver;

// After driver = new AndroidDriver(...) or new IOSDriver(...)
// and after waiting for the game's initial loading screen to finish:
var altDriver = new AltDriver();
Unreal cold starts

Unreal Engine cold starts (shader compilation and asset loading) can take noticeably longer than a typical mobile app launch. If the first connection fails, increase the AltDriver connect timeout — for example new AltDriver(connectTimeout: 10) — or wrap the connection in retry logic.

Sample Test​

Unreal tests use the same AltDriver API as Unity tests but locate UMG widgets and actors using Unreal-flavored names and class suffixes (for example, W_* for widget Blueprints, *_C for compiled Blueprint classes). The following sample loads a level, taps a main-menu button, and confirms the next level loaded.

using NUnit.Framework;
using AltTester.AltTesterSDK.Driver;

[TestFixture]
public class GameSmokeTest
{
private AltDriver _altDriver;

private const string MainMenuLevel = "L_MainMenu";
private const string GameplayLevel = "L_Gameplay";
private const string StartButton = "W_StartGameButton";

[SetUp]
public void SetUp()
{
// Appium session setup elided — see "Configure Appium Capabilities" above.
_altDriver = new AltDriver();
}

[Test]
public void StartGameAndReachGameplayLevel()
{
_altDriver.LoadScene(MainMenuLevel);

var startButton = _altDriver.WaitForObject(By.NAME, StartButton);
startButton.Tap();

_altDriver.WaitForCurrentSceneToBe(GameplayLevel);
}

[TearDown]
public void TearDown()
{
_altDriver?.Stop();
}
}

For more complex locator patterns — finding widgets by path, by displayed text, or by Blueprint class — see AltTester®'s Unreal example tests for current syntax.

Run It​

With AltTester® Desktop running locally and the tunnel active:

dotnet test

View Results​

Open the Sauce Labs dashboard and find your job under Automated → Test Results. Each job has a session video, Appium logs, device logs, and screenshots — use these to debug failures the same way you would for any Appium test.

Alternative: Public VM​

If you can't run Sauce Connect, host AltTester® Desktop on a publicly reachable VM instead:

  1. Create a VM (Windows recommended) and install AltTester® Desktop on it, listening on port 13000.

  2. Add an inbound network rule: protocol TCP, port 13000, source Any. Make sure the OS firewall does not block the port.

  3. Package your Unreal build with the VM's IP address as the AltTester® host (instead of the default 127.0.0.1).

  4. In your tests, connect AltDriver to the same IP:

    var altDriver = new AltDriver(
    host: Environment.GetEnvironmentVariable("HOST_ALT_SERVER"),
    connectTimeout: 3000
    );
  5. On iOS, the game may show a popup asking for permission to connect to devices on the local network. Dismiss it via Appium before connecting the AltDriver:

    driver.FindElement(OpenQA.Selenium.By.Id("Allow")).Click();
  6. If your test suite is long-running, issue a lightweight Appium call in your teardown (for example, reading the device orientation) so the Appium session doesn't idle out between tests.

Troubleshooting​

  • Tunnel missing --proxy-localhost allow: the most common failure. The Appium session starts and the game launches, but AltDriver times out — restart the tunnel with the flag included.
  • Slow cold start: shader compilation and asset loading on first launch can outlast the default AltDriver connect timeout. Increase it (new AltDriver(connectTimeout: 10)) or add retry logic around the connection.
  • Port or tunnel mismatch: the AltTester® host/port configured in your Unreal project must match what your test connects to. With Sauce Connect, both ends use the defaults (127.0.0.1:13000).
  • Plugin not loaded: if AltDriver cannot connect, confirm the AltTester® plugin is enabled in Edit → Plugins and that the packaged build includes the plugin (some Unreal packaging options strip optional modules — check Project Settings → Packaging).
  • Locators not finding widgets: Unreal UMG widget Blueprints often produce class names with a _C suffix at runtime (W_StartGameButton_C rather than W_StartGameButton). Use By.PATH with contains() when in doubt, or inspect the live widget tree in AltTester® Desktop to see the exact names.
  • Wrong data center: the sauceUrl and the data center where your account lives must match. Check the upper-right corner of the Sauce Labs dashboard for your account's region.
  • iOS XCUITest behavior differences: on appium3-2026-01 and later, the official Appium WebDriverAgent is used. Some endpoints may behave differently than on older images that used SauceWebDriverAgent. See Appium real-devices for details.

References​

See Also​