TesterArmyTesterArmy
  • Pricing
Sign inGet started
HomeBlogE2E Testing for Expo Apps: Automated Runs on Every EAS Build

E2E Testing for Expo Apps: Automated Runs on Every EAS Build

How to run e2e tests on Expo apps: build an iOS Simulator app with EAS, hand it to an AI testing agent, and get pass/fail checks with recordings on every pull request. No Detox, no macOS runners.

Oskar Kwasniewski
Oskar KwasniewskiCTO
May 27, 20268 min read
E2E Testing for Expo Apps: Automated Runs on Every EAS Build

How e2e testing works for Expo apps

End-to-end testing an Expo app means running the real app binary, in a real simulator, through the flows your users actually perform: onboarding, login, the core loop. Historically that meant Detox or Maestro plus your own simulator infrastructure, which is exactly the part most Expo teams never get around to standing up. CI needs macOS runners for iOS simulators, the tooling needs native build configuration, and the tests need maintenance every time the UI shifts.

The setup in this post takes a different path: EAS builds the iOS Simulator app, which it already does well, and TesterArmy takes the artifact from there. The agent installs the build in a cloud simulator and runs your saved test flows against it, described in plain English rather than test code. Runs happen on every pull request, and results come back as GitHub checks with recordings and screenshots. There is no simulator fleet to maintain and no test framework to configure. One honest boundary to know up front: runs execute on simulators and emulators, which covers UI and flow regressions well, and does not replace on-device testing for hardware-specific behavior.

More on the setup for plain React Native projects (without EAS) is in React Native e2e testing without Detox, and the product page for this stack is Expo app testing.

Most Expo projects already use EAS as the place where native builds happen. It builds the app, stores the artifact, and can run workflows around that build.

That makes it a good place to add mobile QA. TesterArmy can take the iOS Simulator build from EAS, install it in a cloud simulator, and run your saved mobile tests against it.

You do not have to maintain a macOS runner, keep simulators warm, clean up uploaded artifacts, or write your own polling loop. For JavaScript-only changes, you can also use Expo Repack later and avoid a full native rebuild when the native runtime did not change.

Let's wire it up.

What EAS gives us

EAS already owns the native build step, so we should not duplicate that work somewhere else.

For TesterArmy, the important detail is the artifact type. We need an iOS Simulator .app build, not an .ipa.

An .ipa is meant for physical devices. A simulator run needs a simulator app bundle.

In EAS, the profile looks like this:

eas.json

Once EAS produces that .app, the workflow can upload it to TesterArmy and start a saved mobile test group.

What TesterArmy handles

The EAS workflow should stay simple. It only needs to orchestrate five things:

  1. Build the iOS Simulator app.
  2. Download the .app artifact.
  3. Upload the app to TesterArmy.
  4. Run the selected mobile test group.
  5. Delete the temporary app upload when the run finishes.

TesterArmy handles the rest:

  • Cloud simulator provisioning
  • App installation
  • Agent-driven mobile test execution
  • Screenshots, videos, and run artifacts
  • Result polling
  • GitHub checks and PR comments

That split is the whole integration. EAS gives us a build. TesterArmy runs it.

The required values

The workflow needs three values from TesterArmy.

Environment variableWhat it points to
TESTERARMY_API_KEYAPI key from Profile -> API Keys
TESTERARMY_PROJECT_IDProject ID from Project Settings
TESTERARMY_GROUP_IDGroup ID for the mobile tests you want to run

Keep TESTERARMY_API_KEY as an EAS secret or sensitive environment variable. Do not expose it through EXPO_PUBLIC_*, and do not commit it.

The project ID and group ID are not sensitive in the same way, but keeping all three values in the EAS environment makes the workflow easier to reuse across projects.

Adding the workflow

The basic workflow has three jobs.

First, build the simulator app:

.eas/workflows/testerarmy-mobile-tests.yml

Next, download the EAS artifact and upload it to TesterArmy:

.eas/workflows/testerarmy-mobile-tests.yml

Finally, run the saved test group with the uploaded app ID:

.eas/workflows/testerarmy-mobile-tests.yml

The full copy-paste version is in the Expo EAS docs.

Getting PR feedback

When this runs on a pull request, TesterArmy can create a GitHub check and leave a PR comment. Reviewers get the normal pass/fail signal, plus links to the run details, screenshots, videos, and logs.

To enable that, connect your TesterArmy project to the GitHub repository from the project Integrations tab.

After that, pass the commit SHA and PR number from the EAS workflow:

On push events, TesterArmy attaches the check to the commit. On pull requests, it can attach the check and the PR comment.

Using Expo Repack

The basic workflow runs a full simulator build every time. Start there. It is slower, but it removes a lot of variables while you are setting up the integration.

Once that is stable, you can make the workflow faster with EAS fingerprint and Expo Repack. This is useful when a pull request changes JavaScript only and the native runtime is still compatible.

The optimized workflow calculates the native runtime fingerprint, looks for a compatible simulator build, and repacks it with the current JavaScript bundle when the native layer did not change.

You still test the code from the branch, but you do not pay for a full native rebuild on every PR.

That workflow variant is included in the Expo EAS docs. Treat it as an optimization, not the first thing to debug.

Common mistakes

The most common issue is uploading the wrong artifact.

TesterArmy needs an iOS Simulator .app build. If the workflow uploads an .ipa, the run cannot install it in the simulator.

The second issue is running a group that does not contain mobile tests. Before adding EAS, run the mobile test manually from the dashboard once. Check that the app upload works, the test passes, and the test is in the group you plan to call from CI.

The third issue is missing GitHub integration. Tests still run without it, but PR comments and commit checks need the TesterArmy project to be connected to the repository.

That's a wrap

Expo EAS already knows how to build your app. TesterArmy just needs the simulator artifact.

The setup is: create an iOS Simulator build profile, add the EAS workflow, configure the three environment variables, and run the saved test group on every PR.

If you want the exact copy-paste setup, start with the Expo EAS integration docs. If you still need to create your first mobile test, start with App Uploads.

Frequently asked questions

Can you run e2e tests on Expo apps without Detox? Yes. Build an iOS Simulator app with EAS and run it with an agent-based platform like TesterArmy. Detox requires native build integration and test code in your repo; the agent approach needs the .app artifact and plain-English flow descriptions. The practical walkthrough is in our React Native guide.

Do I need an .ipa or an .app build for testing? For simulator runs you need an iOS Simulator .app bundle, produced by an EAS profile with the simulator flag. An .ipa targets physical devices and will not install in a simulator.

Does this work with Expo Repack for JS-only changes? Yes. Once the basic workflow is stable, Repack lets you skip full native rebuilds when only JavaScript changed, which makes the PR loop substantially faster. The post covers when it is safe to use.

What does the pull request actually see? A GitHub check plus a PR comment with pass/fail per flow, links to the run, screenshots, and a full video recording of the simulator session.

ON THIS PAGE

  • How e2e testing works for Expo apps
  • What EAS gives us
  • What TesterArmy handles
  • The required values
  • Adding the workflow
  • Getting PR feedback
  • Using Expo Repack
  • Common mistakes
  • That's a wrap
  • Frequently asked questions

SHARE THIS ARTICLE

  • X

Check other TesterArmy insights

August 26, 2026

Introducing unbox-ai: See Where Your Agent's Tokens Actually Go

We built unbox-ai to debug our own QA agent's traces. One command opens a token treemap and latency waterfall; the same binary is a read-only trace explorer your coding agent can use. Now it's open source.

Read article
August 20, 2026

Introducing the Issues Tab: One Row Per Bug, No Matter How Many Runs Found It

Agent-found bugs now land in one deduplicated list instead of scattered run reports. Every issue carries expected vs actual, repro steps, and a replay of the exact moment it broke - and leaves the list as a Linear ticket, a prompt for your coding agent, or resolved.

Read article
August 18, 2026

We Benchmarked 10 Vision Models on Clicking What They See

All ten models answered every visual understanding question correctly. Grounding the click is where the field splits, and where GPT-5.6 Luna won on accuracy, precision, and cost.

Read article
Contact us

Let's connect

Contact usGet a demo
XLinkedInDiscord
TesterArmyTesterArmy

AI-powered QA testing for modern teams. Ship faster with confidence.

SOC 2 Type 2 badge
GDPR badge

© 2026 TesterArmy, Inc.

Solutions
  • AI app testingAI app testing
  • EcommerceEcommerce
  • Expo app testingExpo app testing
  • MobileMobile
  • Production monitoringProduction monitoring
  • React Native testingReact Native testing
  • WebWeb
  • WordPress testingWordPress testing
Quick links
  • HomeHome
  • DemoDemo
  • FeaturesFeatures
  • How it worksHow it works
  • FAQFAQ
  • PricingPricing
  • Get a demoGet a demo
  • About usAbout us
  • Contact usContact us
Resources
  • DocumentationDocumentation
  • BlogBlog
  • API referenceAPI reference
  • Getting startedGetting started
Legal
  • Privacy policyPrivacy policy
  • Terms of serviceTerms of service
TesterArmyTesterArmy
  • Pricing
Sign inGet started
Quick links
  • HomeHome
  • DemoDemo
  • FeaturesFeatures
  • How it worksHow it works
  • FAQFAQ
  • PricingPricing
  • Get a demoGet a demo
  • About usAbout us
  • Contact usContact us