Integrate with Vitest
We recommend Vitest for writing JavaScript and TypeScript tests on Android, iOS, HarmonyOS, and desktop. Vitest organizes test cases, runs lifecycle hooks, and aggregates test results, while Midscene Agents connect to devices, interact with the UI, and perform assertions.
Before you begin
- Runtime: Install Node.js
^20.19.0 || ^22.12.0 || >=24.0.0and pnpm. Use an existing project or runpnpm initto create one (skip ifpackage.jsonalready exists). - Model configuration and verification: Complete model configuration and model verification, then save the configuration in the project's
.envfile or shell environment. - Platform environment: Complete the environment setup for Android, iOS, HarmonyOS, or desktop, including device connections and required permissions.
- (Optional) Try Playground first: Run an action and an assertion against your target interface in the Playground for your platform to verify screenshots, interactions, and model behavior.
1. Install dependencies
2. Configure Vitest
Create vitest.config.ts. If your project already uses Vitest for unit tests, you can save this configuration separately as vitest.device.config.ts and pass --config vitest.device.config.ts when running device tests, leaving your existing test configuration untouched.
Because model calls and device connections take longer than standard unit tests, adjust testTimeout and hookTimeout to fit your test cases. When running against a single shared device, disable file parallelism (fileParallelism: false) and run tests sequentially (sequence.concurrent: false), and avoid test.concurrent or describe.concurrent. For details, see the Vitest documentation on fileParallelism, testTimeout, and hookTimeout.
3. Write a test
Create e2e/settings.test.ts, initializing a new Agent for each test in beforeEach and destroying it in afterEach:
If multiple devices are connected, pass a device ID to agentFromAdbDevice(deviceId). See the Android SDK guide for connection options.
dotenv/config loads model settings from the project's .env file (settings in the Playground are not automatically shared with test runs).
When an aiAssert check fails, it throws an error, causing Vitest to mark the test as failed before running afterEach to clean up the Agent. You can also extract data from the screen with methods like aiQuery and pass the result to Vitest's expect. For more interaction and extraction methods, see the Agent API reference.
4. Run the test and view the report
Vitest prints the pass or fail status of each test in the terminal, while the Midscene SDK generates an execution report for each Agent under midscene_run/report/ by default and prints the report path. Open the generated HTML file in a browser to inspect step-by-step screenshots, AI execution details, and assertion results.
Unlike Playwright Test, Vitest integration uses the SDK's built-in report generation directly and does not require a custom reporter. Vitest test results and Midscene Agent reports are generated separately; to merge or further process report files, see Process report files.
Common methods
In practice, you typically perform actions with aiAct or direct interaction methods and then verify the outcome with aiAssert—completing an action does not guarantee that the expected UI state was reached. For full parameter and return value details, see the Agent API reference.
Lifecycle and exclusive device access
- Isolate Agents per test: Create a new Agent for each test case. Each Device instance belongs to a single Agent, and
agent.destroy()cleans up the associated Device as well—do not reuse a destroyed instance in subsequent tests. - Manage application state explicitly: Destroying an Agent does not reset app data or close the app. Each test should explicitly prepare the required initial screen and data, and clean up state as needed so tests can be retried or run individually.
- Avoid device contention across processes: Vitest's sequential settings only apply to the current test runner process; other local processes, CI jobs, or manual input can still contend for the same device. To run tests in parallel, assign a dedicated device or desktop session to each worker and explicitly specify its connection target in code.
For complete working projects, see the Vitest examples for Android, iOS, HarmonyOS, and desktop.

