Skip to content

循环与条件

DSL 提供 3 种控制流 action:repeat / forEach / ifExists

repeat — 固定次数循环

yaml
- repeat:
    times: 5
    steps:
      - scroll: down
      - wait: 500

典型用途:

  • 滚动加载列表(scroll N 次)
  • 批量点击
  • 压测(跑 N 遍同一个 flow 看稳定性)

forEach — 遍历

静态 list

yaml
- forEach:
    var: TAB
    values: [Home, Search, Profile, Settings]
    steps:
      - tap: "${TAB}"
      - wait: 1500
      - saveScreenshot: "tab-${TAB}"

文件驱动(CSV / JSON)

yaml
- forEach:
    var: U
    from: ./users.csv   # 相对 YAML 目录
    steps:
      - input: "${U.email}"
      - input: "${U.password}"
      - tap: Login

CSV 格式(第一行表头):

csv
email,password,expected_plan
alice@x.com,pw1,pro
bob@x.com,pw2,free

JSON 格式(array of string 或 object):

json
[
  { "email": "alice@x.com", "password": "pw1" },
  { "email": "bob@x.com", "password": "pw2" }
]

规则:

  • 每次迭代 ${var}${var.field} 替换成当前行
  • 迭代结束自动清理变量,不影响后续 step
  • valuesfrom 二选一

变量与 Include 的运行时机制。

ifExists — 条件分支

yaml
- ifExists:
    pattern: 欢迎回来      # 屏上存在这个文字?
    then:
      - tap: 进入
    else:
      - tap: 注册
      - input: "${EMAIL}"

典型用途:

  • 处理首次登录 vs 已登录
  • 弹窗可能出现也可能不出现(比 dismissModal 更精细)
  • A/B 版本不同 UI 路径

pattern子串匹配(不是正则);想用正则目前 ifExists 不支持,可以先 readText 存变量再手动判断。

组合:轮询 + 分支

yaml
# 等内容加载,然后根据结果走不同分支
- tap: 提交订单
- waitFor: { pattern: 处理中, timeoutMs: 30000 }
- waitAbsent: { pattern: 处理中, timeoutMs: 30000 }

- ifExists:
    pattern: 支付成功
    then:
      - saveScreenshot: paid-ok
      - assert: 订单号
    else:
      - readText: { label: 错误提示, into: ERR }
      - saveScreenshot: paid-fail
      - assertVisual: "显示支付失败原因 ${ERR}"

嵌套

repeat / forEach / ifExistssteps 里可以再嵌任意 step,包括彼此。

yaml
- forEach:
    var: USER
    from: ./users.csv
    steps:
      - input: "${USER.email}"
      - tap: Login
      - ifExists:
          pattern: 需要二次验证
          then:
            - readText: { regex: "(\\d{6})", into: OTP }
            - input: "${OTP}"
          else: []    # 没启用 2FA,跳过
      - assert: Dashboard
      - tap: Logout

失败处理

DSL 执行顺序式:某一步失败 → 后续 step 不跑,整个测试标记 FAIL

  • ifExiststhen / else 里如果某 step 失败,整个任务失败(不会回到外层继续)
  • forEach 某一轮失败,不会跑剩余迭代(早退出)
  • 想"失败容忍"或"重试"当前不支持,future 可能加 try / onFail

如果你的用例需要严格容错,在 AI solver(非 DSL)里更灵活。

不支持的控制流(未来)

特性为什么暂不支持临时方案
while 通用循环脆弱,容易死循环repeat + ifExists 早退
try/catchDSL 设计追求"简单 + 可审查"代码级 scripted solver 写 TS 实现
函数 / 自定义 step同上include 提取共用 steps
并行 steps单设备 UI 天然不能并行多设备并行 runner 级别已有

相关

Released under MIT License.