Getting started¶
This page takes you from nothing to a passing test. The guide's examples are in Python; for Kotlin, follow Kotlin + JUnit 5 after step 1.
Before you start
- An Android device or emulator with API 26 or newer, visible to
adb devices. - Linux x86-64 or macOS on Apple silicon for the native
tapbinary, or any OS with JDK 17+ for the JVM build. - Python 3.10+ and pytest, or a Gradle project with JUnit 5 for Kotlin.
Everything in one download
The Download page has one zip per platform with the server, both clients,
tap-agent, Tap Studio and these docs, plus an install.sh that sets it all up. With it,
Gradle reads Tap from a local Maven repository and needs no GitHub token. The steps below
install each part on its own instead.
1. The server¶
The server is a single executable that owns ADB and the devices for the whole machine. Pick one:
- Download
tap-0.0.2-linux-x86_64(Linux) ortap-0.0.2-macos-aarch64(macOS on Apple silicon) from the latest release. -
Rename it to
tapand make it executable:mv tap-0.0.2-linux-x86_64 tap && chmod +x tap ./tap version
The examples below write tap; use ./tap, or put the file in a directory on your PATH.
tap-<version>-jvm.zip from the same release; needs a JDK 17+.
unzip tap-0.0.2-jvm.zip && export PATH="$PWD/tap-0.0.2/bin:$PATH"
tap version
./gradlew :host:daemon:installDist
export PATH="$PWD/host/daemon/build/install/tap/bin:$PATH"
Start it once; like the ADB server it stays up until tap stop, shared by every test process on
the machine. It binds loopback only. The on-device driver is bundled inside the executable and
installed on each device the first time a session opens.
tap start # prints: started 127.0.0.1:PORT pid=PID (or "running …" if it already is)
tap status
Clients never start the server themselves; if none is running they fail with run tap start.
Test runners can start and stop it for you: see The tap server.
2. Install the Python client¶
pip install https://github.com/NoamCohen48/tap/releases/download/client-python/v0.0.2/tap_e2e-0.0.2-py3-none-any.whl
The package tap-e2e (imported as tap_e2e) registers a pytest plugin that provides attached
devices as fixtures.
3. Write a test¶
from tap_e2e import res, text
def test_opens_the_home_screen(tap_device):
app = tap_device.app("com.shop")
app.install("build/outputs/apk/debug/shop-debug.apk")
app.cold_launch() # resolves the launcher activity, waits for its window
app.wait(text("Welcome")).visible() # only com.shop's nodes count
app.element(res("search")).set_text("socks")
TAP_SERIALS=emulator-5554 pytest
tap_device is a device attached for this test and detached after it. When the test fails, the
plugin saves a screenshot, the hierarchy dump, the device info and the driver log under
tap-artifacts/<nodeid>/.
Next¶
- Selectors, Elements and text and Waits cover what you will use in every test.
- Python + pytest has the plugin's options and using the client from a script; Kotlin + JUnit 5 is the same for Kotlin.
- tap-agent lets Claude Code or another coding agent drive a device through the same server, Tap Studio records steps from your browser, and tap-watcher shows your tests' actions and the device's screen while they run.