Show HN: Finalrun – 使用英语和视觉进行移动应用规范驱动测试
Show HN: Finalrun – Spec-driven testing using English and vision for mobile apps

原始链接: https://github.com/final-run/finalrun-agent

## FinalRun:AI驱动的移动应用测试 FinalRun 是一款 CLI 工具,利用 AI 自动化 Android 和 iOS 移动应用测试。你可以在应用仓库中用 YAML 文件定义测试,FinalRun 会执行这些测试,并提供本地运行工件供检查。 **安装:** 安装过程简单,通过 shell 脚本 (`curl -fsSL https://raw.githubusercontent.com/final-run/finalrun-agent/main/scripts/install.sh | bash`) 完成,该脚本会处理 Node.js、CLI 和平台工具。 **工作流程:** 1. 在你的应用仓库中创建一个 `.finalrun/` 目录。 2. 将 YAML 测试规范添加到 `.finalrun/tests/`。 3. 在 `.env` 文件中配置你的 AI 提供商密钥(OpenAI、Google 或 Anthropic)。 4. 使用 `finalrun check` 进行验证。 5. 使用 `finalrun test` 运行测试,或使用 `finalrun suite` 运行套件。 **主要特性:** 环境变量通过 `.env` 文件管理(密钥不应提交到版本控制)。本地报告服务器 (`finalrun start-server`) 允许轻松检查结果。`finalrun doctor` 验证主机是否已准备好进行本地运行。 **了解更多:** [https://www.youtube.com/watch?v=q6CFoN-ohT4](https://www.youtube.com/watch?v=q6CFoN-ohT4)

## Finalrun:基于规范的移动测试 Ashish004开源了Finalrun,这是一种新的移动应用测试方法,旨在克服选择器脆弱和测试不同步的问题。Finalrun利用基于视觉的代理,能够理解纯英文指令,并与Android和iOS应用交互,而无需依赖像XPath等易碎的标识符。 其关键创新在于*测试的定义方式*。 Finalrun不采用外部的、手动维护的测试,也不采用从PRD一次性生成的测试,而是直接从代码库生成测试,使其与开发紧密相关,并确保同步。 该系统具有基于代码库上下文的测试生成、基于YAML的测试流程以及基于视觉的执行引擎。 演示展示了一个由AI构建的功能被Finalrun立即测试,验证其功能。 资源:[GitHub仓库](https://github.com/final-run/finalrun-agent),[演示](https://youtu.be/rJCw3p0PHr4),[基准测试](https://finalrun.app/benchmark/)。
相关文章

原文

FinalRun logo

npm version License: Apache-2.0

finalrun.app  •  Blog  •  Cloud Device Waitlist  •  Join Slack Community

FinalRun on X   FinalRun on GitHub   FinalRun on LinkedIn

finalrun-agent is an AI-driven CLI for mobile app testing. You define repo-local tests in YAML, run them against Android or iOS targets, and inspect local run artifacts from the terminal.

Run the installer to set up everything — Node.js, the CLI, skills, and platform tools:

curl -fsSL https://raw.githubusercontent.com/final-run/finalrun-agent/main/scripts/install.sh | bash

The installer checks for Node.js (installs via nvm if missing), installs the finalrun CLI globally, adds FinalRun skills for Claude Code / Codex, and walks you through Android and iOS tool setup.

The package installs the finalrun command and also exposes finalrun-agent as an alias.

During global installation, FinalRun stages its native driver assets under ~/.finalrun/assets/<version>/. Run artifacts are stored separately under ~/.finalrun/workspaces/<workspace-hash>/artifacts. In your app repo, .finalrun/ holds YAML specs, environment binding files (.finalrun/env/*.yaml), and config.

Secret values and API keys belong in workspace-root .env files (see Important: Environment variables and .env files), not in YAML.

Watch the FinalRun demo

Watch the demo on YouTube: https://www.youtube.com/watch?v=q6CFoN-ohT4

  1. Run the install script (see above) to set up the CLI and platform tools.
  2. Create a .finalrun/ workspace in the mobile app repo you want to test.
  3. Add at least one YAML spec under .finalrun/tests/.
  4. Configure the AI provider key you want to use.
  5. Validate the workspace with finalrun check.
  6. Run a test with finalrun test.

Example workspace layout (workspace root is the directory that contains .finalrun/):

.env                 # optional; shared defaults (do not commit — see .gitignore below)
.env.dev             # optional; values when using env name "dev" (do not commit)
.finalrun/
  config.yaml
  tests/
    smoke.yaml
    auth/
      login.yaml
  suites/
    smoke.yaml
  env/
    dev.yaml

Minimal test spec:

name: login_smoke
description: Verify that a user can log in and reach the home screen.

steps:
  - Launch the app.
  - Enter ${secrets.email} on the login screen.
  - Enter ${secrets.password} on the password screen.
  - Verify the home screen is visible.

Optional environment file:

secrets:
  email: ${TEST_USER_EMAIL}
  password: ${TEST_USER_PASSWORD}

variables:
  locale: en-US

Optional workspace config:

env: dev
model: google/gemini-3-flash-preview

finalrun check reads env from .finalrun/config.yaml when --env is omitted. finalrun test reads both env and model from config when the corresponding CLI flags are omitted. Explicit CLI flags always win over config.

Validate the workspace:

Check local host readiness for Android or iOS runs:

Run a test:

finalrun test smoke.yaml --env dev --platform android --model google/gemini-3-flash-preview

Run a suite manifest:

finalrun suite smoke.yaml --env dev --platform ios --model google/gemini-3-flash-preview

Inspect or serve reports from anywhere:

finalrun runs --workspace /path/to/mobile-app
finalrun start-server --workspace /path/to/mobile-app
finalrun server-status --workspace /path/to/mobile-app
finalrun stop-server --workspace /path/to/mobile-app

Environment variables and .env files

Important

Store real secrets and API keys only in workspace-root .env and .env.<name> files (the same folder that contains .finalrun/), not in .finalrun/env/*.yaml (that file only lists placeholder names like ${MY_VAR}). Add .env and .env.* to your .gitignore so those files are never committed.

  • Workspace root is the folder that contains .finalrun/. FinalRun finds it by walking up from your shell’s current directory, so dotenv paths are anchored to that root (not to cwd when you run from a subfolder).
  • Workspace root — dotenv (secrets and provider keys):
    • .env — optional; values merged for all runs (see load order below).
    • .env.<name> — optional; used when that environment is active (e.g. .env.dev for dev from --env dev or env: dev in .finalrun/config.yaml). The name matches .finalrun/env/<name>.yaml, not the filename alone.
  • .finalrun/env/<name>.yaml — bindings only: declares secrets as placeholders like ${TEST_USER_EMAIL} and variables as plain values. The CLI resolves each secrets placeholder from the shell environment and from workspace-root .env / .env.<name> (see below). Do not put real secrets inside this YAML.

For a resolved environment name N, the CLI loads variables from .env.N, then fills missing keys from .env, then applies process.env (which wins if the same name is set in both a file and the environment).

That single workspace-root dotenv setup is used for:

  • Resolving ${secrets.*} references defined in .finalrun/env/*.yaml.
  • Reading AI provider API keys (OPENAI_API_KEY, GOOGLE_API_KEY, ANTHROPIC_API_KEY) for finalrun test and finalrun suite.

When no FinalRun environment is in use (env-free workspace), the CLI does not require a .env.N file for YAML bindings; you can still use process.env or .env for keys if applicable.

Git: keep secrets out of the repo

Do not commit .env files. Add the following to your app repository’s .gitignore (or equivalent):

That ignores .env, .env.dev, .env.staging, and similar. The finalrun-agent monorepo uses the same pattern in its root .gitignore.

FinalRun specs are plain YAML files stored under .finalrun/tests/.

  • name: stable identifier for the scenario
  • description: short human-readable summary
  • steps: ordered natural-language steps executed by the agent

Environment placeholders are supported:

Suite manifests live under .finalrun/suites/ and list YAML files, directories, or globs that resolve under .finalrun/tests/.

name: auth_smoke
description: Covers the authentication smoke scenarios.
tests:
  - auth/login.yaml
  - auth/logout.yaml

In standard usage:

  • finalrun test auth/login.yaml resolves auth/login.yaml from .finalrun/tests/
  • finalrun suite auth_smoke.yaml resolves auth_smoke.yaml from .finalrun/suites/

Explicit .finalrun/tests/... and .finalrun/suites/... paths still work for compatibility when you want them.

finalrun check

  • Validates the .finalrun workspace, environment bindings, selectors, and suite manifests.
  • Uses .finalrun/config.yaml env as the default when --env is omitted.

finalrun test

  • Executes one or more YAML specs from .finalrun/tests.
  • Requires a model from --model <provider/model> or .finalrun/config.yaml.
  • Supports --env, --platform, --app, --suite, and --api-key, with CLI flags taking precedence over config.

finalrun suite

  • Executes a suite manifest from .finalrun/suites.
  • Requires a model from --model <provider/model> or .finalrun/config.yaml.
  • Supports --env, --platform, --app, and --api-key, with CLI flags taking precedence over config.

finalrun test --suite <path> remains supported as a compatibility path, but finalrun suite <path> is the preferred standard.

finalrun doctor

  • Checks host readiness for local Android and iOS runs.

finalrun runs

  • Lists local reports from the workspace-scoped artifact store at ~/.finalrun/workspaces/<workspace-hash>/artifacts.
  • Supports --workspace <path> so you can inspect a workspace from anywhere.

finalrun start-server

  • Starts or reuses the local report UI for a workspace.
  • Supports --workspace <path>, --port <n>, and --dev.

finalrun server-status

  • Shows the current local report server status for a workspace.
  • Supports --workspace <path>.

finalrun stop-server

  • Stops the current local report server for a workspace.
  • Supports --workspace <path>.

finalrun report serve

  • Removed as a breaking CLI change. Use finalrun start-server instead.

See command help for full options:

finalrun --help
finalrun test --help
finalrun suite --help

Tip: The install script (curl -fsSL .../install.sh | bash) handles most of these automatically. The details below are for reference.

Using FinalRun has two layers of setup:

  • finalrun check requires the CLI, a .finalrun/ workspace, and any needed config or secrets.
  • Local finalrun test and finalrun suite runs additionally require host tooling for the target platform.
  • finalrun doctor is the source of truth for local host readiness.
  • Node.js >=20
  • npm
  • Install the published CLI: npm install -g @finalrun/finalrun-agent
  • Run from a repository that contains .finalrun/
  • At minimum, .finalrun/tests/ must exist
  • For finalrun test and finalrun suite: a configured model from --model <provider/model> or .finalrun/config.yaml
  • For finalrun test and finalrun suite: the matching provider API key in process.env, .env, or .env.<name>

finalrun check does not require Android or iOS host tools.

Required for Android local runs

  • adb available through ANDROID_HOME, ANDROID_SDK_ROOT, or PATH
  • emulator on PATH; the current Android preflight requires it to discover and boot Android Virtual Devices
  • scrcpy on PATH; FinalRun uses it for Android screen recording during local runs and treats it as required
  • Bundled FinalRun Android driver assets present; the published CLI installs them automatically

Required for iOS local runs

  • macOS
  • Xcode command line tools with xcrun
  • xcrun simctl
  • unzip
  • /bin/bash
  • plutil
  • Bundled FinalRun iOS driver archives present; the published CLI installs them automatically
  • ffmpeg compresses iOS recordings after capture
  • applesimutils enables simulator permission helpers
  • lsof, ps, and kill help with stale iOS driver cleanup

Verify local host readiness with:

finalrun doctor
finalrun doctor --platform android
finalrun doctor --platform ios

If you're developing from this repo instead of using the published package, build the native driver artifacts with:

FinalRun requires a provider/model value from --model <provider/model> or .finalrun/config.yaml. It currently supports exactly openai, google, and anthropic, and resolves API keys in this order:

  • openai/...: OPENAI_API_KEY
  • google/...: GOOGLE_API_KEY
  • anthropic/...: ANTHROPIC_API_KEY

Keys are read from process.env and from workspace-root .env / .env.<name> (same rules as in Important: Environment variables and .env files). You can still pass --api-key to override.

Examples:

finalrun test smoke.yaml --platform android --model google/gemini-3-flash-preview
finalrun suite smoke.yaml --platform ios --model anthropic/claude-sonnet-4-6

Contributor setup, monorepo structure, build commands, and testing expectations live in CONTRIBUTING.md.

For source development in this monorepo, install workspace dependencies first:

If you use git worktrees, do this once per fresh worktree before running npm run build, npm run test, npm run dev:cli, or any local finalrun-dev wrapper that executes the TypeScript sources directly.

Project policies:

联系我们 contact @ memedata.com