# How to run your tests on real devices with e2e and TestMu AI

> Run your existing e2e tests on TestMu AI's cloud browsers, emulators, simulators and more than 50,000 real iOS and Android devices. Only the targets in e2e.config.ts change, the tests stay the same.

By Kacper Kapuściak. Published 2026-11-11. Canonical URL: https://e2e.com/blog/e2e-and-testmu

Your app starts crashing on some random Oppo device. There's this visual bug that only reproduces on a single version of Samsung One UI. Sure, you test your app on an emulator on your laptop, but the real world is really complicated. Physical devices differ from each other in many different ways. Different form factors don't help either (I'm looking at you iPhone Duo!). And you want to provide the best experience to all of them, right? Buying each of them whenever a single crash occurs on this type of device might not be feasible for everyone.

Luckily, you don't have to own a phone to test on it. TestMu AI gives you devices and browsers in the cloud. Add `@e2e-dev/testmu`, and you can run your [existing e2e tests](https://e2e.com/) on them without changing the test code. You only need to adjust the targets in `e2e.config.ts`.

[Video: e2e test running on a cloud TestMu AI browser](https://e2e.com/blog/videos/e2e-and-testmu-demo.mp4)

_e2e test running on a cloud TestMu AI browser. Simulators, emulators and physical mobile devices are also supported._

## What is TestMu AI?

TestMu AI, formerly LambdaTest, lets you run tests on Chrome, Edge, Android emulators and iOS simulators in the cloud. If you need a physical phone, it also offers more than 50,000 real iOS and Android devices, according to its own figures.

The [`@e2e-dev/testmu` package](https://e2e.com/docs/integrations/testmu) connects your tests to that cloud. Use `testmu()` for emulators, simulators and real phones, or `testmuBrowsers()` for hosted Chrome and Edge.

## What we're going to test

To show how it works, I'm using [a tiny Expo app](https://e2e.com/examples/with-expo). You type a name, tap **greet**, and the app says hello. Leave the name empty and it asks you to enter one first.

Here's a test that lets the agent figure out the UI:

```ts
test("the agent gets a greeting", async ({ app, agent, screen }) => {
  await app.open();

  await agent.act("get the app to greet {name}", { params: { name: "Grace" } });

  await expect(screen.getByTestId("greeting")).toHaveText("hello, Grace!");
  await agent.assert("the app greets Grace by name");
});
```

I didn't tell the agent which field to type into or which button to tap. It works that out from the screen. Then a locator checks the exact text, and a judge checks that the app really greets Grace.

The test knows nothing about TestMu AI. Let's keep it that way.

## How to run e2e tests on TestMu AI devices?

First, install the integration alongside the mobile engine:

```bash
npm install --save-dev e2e @e2e-dev/mobile @e2e-dev/testmu
```

Copy `LT_USERNAME` and `LT_ACCESS_KEY` from **Account Settings → Password & Security → Username and Access Key** in your TestMu AI account, and set them in your environment or as CI secrets.

Then add your targets to `e2e.config.ts`. Here are the two device targets from the example project:

```ts
const app = { bundleId: "dev.e2e.examples.expo" };

export default {
  targets: [
    {
      name: "testmu-android",
      engine: mobile({
        platform: "android",
        device: testmu({
          device: "Galaxy S22 Ultra 5G",
          osVersion: "14",
          app: "./android/app/build/outputs/apk/release/app-release.apk",
        }),
      }),
      app,
    },
    {
      name: "testmu-ios",
      engine: mobile({
        platform: "ios",
        device: testmu({
          device: "iPhone 16",
          osVersion: "18.0",
          app: "./build/with-expo.app.zip",
        }),
      }),
      app,
    },
  ],
} satisfies E2EConfig;
```

Each target tells TestMu AI which device to use and which build to install. Pass the build as `app` inside `testmu()`. Here, it's a local file, so e2e uploads it for you. You can also pass an HTTPS URL or an `lt://` app ID.

The build format depends on the device: `.apk` or `.aab` for Android, a zipped `.app` for an iOS simulator, and a signed `.ipa` for a real iPhone. And `bundleId` tells `app.open()` which app to launch once it's installed.

Both of these are virtual devices. Want a physical phone instead? Add `deviceType: "real"`:

```ts
testmu({ device: "iPhone 16", osVersion: "18", app: "./build/with-expo.ipa", deviceType: "real" });
```

One detail to watch: `osVersion` is now `"18"`, not `"18.0"`. Real and virtual devices have separate catalogs, and the names and versions need to match exactly. Copy them from the [capabilities generator](https://www.lambdatest.com/capabilities-generator) to save yourself a lot of trouble.

The tests are billed for the time a device is leased, including setup and time spent waiting between tests. Your TestMu plan limits how many sessions you can run at once, so make sure to keep `workers` times the number of TestMu AI targets within that limit. The [session limit docs](https://e2e.com/docs/integrations/testmu#limits) cover the details.

Now pick a target and run the tests:

```bash
npx e2e run --target testmu-android
```

You'll find the sessions on the TestMu AI dashboard. If a device test records video, you can open that recording straight from the e2e report.

The machine running e2e needs neither Xcode nor the Android SDK. A plain Linux CI runner can run your tests on real iPhones. You still need a Mac to build the iOS app, which you can do for example on [Expo Build](https://docs.expo.dev/build/introduction/), but running these tests can happen elsewhere.

You can also set `orientation`, `geoLocation`, `timezone`, `language` and `locale` for each target, so you could test your Hindi translation with a Hindi locale and an IP address that geolocates to India. This pairs perfectly with [e2e personas](https://e2e.com/docs/agents#one-flow-several-personas) where agents can behave as Hindi-speaking users.

## Try TestMu AI today

The same app can look quite different on a small Android phone and an unfolded foldable. That's where [agentic testing](https://e2e.com/blog/agentic-mobile-testing-with-e2e-and-agent-device) helps. In the greeting test, I told the agent to get the app to greet Grace. It looks at the screen and figures out where to type and tap, so the instruction can stay the same even when the layout changes.

Once the step passes, e2e records the actions and [replays them on later runs](https://e2e.com/docs/cache#how-a-replay-works) without another model call. Each target gets its own recording, so your Samsung Galaxy won't replay what the agent did on an iPhone. The `agent.assert` checks still call the model to check the result.

> "We partnered with e2e because we see testing the same way: agents that read the screen and adapt,
>   running on the devices real users actually hold. e2e brings the agent, and TestMu AI brings more
>   than 50,000 real devices plus emulators and simulators. Together, teams can cover their users'
>   hardware from any CI runner without writing a separate test for each phone."
>
> Mayank Bhola, co-founder and head of products at TestMu AI

Next time your app crashes on some random Oppo device, you don't have to go and buy one. Simply add it as a target and run your tests!

- TestMu AI: [testmuai.com](https://www.testmuai.com)
- e2e on TestMu AI: [e2e.com/docs/integrations/testmu](https://e2e.com/docs/integrations/testmu)
