mcpField
Q
qa-team

qa-team

github.com/rysweet测试与质量7654 次安装22 周前更新
代码仓库

关于 qa-team

qa-team 是用于编写声明式外部视角测试的技能,通过用户可见交互验证应用行为。它借助 gadugi-agentic-test 支持 CLI、TUI、Web 和 Electron 场景,也涵盖实现对比与发布差异记录。

主要功能

  1. 01基于 YAML 的行为场景
  2. 02支持 CLI、TUI、Web 和 Electron 测试
  3. 03由 Agent 执行动作并验证结果
  4. 04采集证据并生成报告
  5. 05支持实现对比和影子模式

适用场景

  1. 01变更后检查关键用户流程
  2. 02跨应用类型测试用户行为
  3. 03比较旧版与替代实现
  4. 04记录发布差异而不阻断运行

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/rysweet/amplihack --skill qa-team

安装后在 Claude Code 中输入/qa-team确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
examples/cli/
calculator-basic.yaml
cli-error-handling.yaml
cli-interactive-session.yaml
examples/custom-agents/
custom-comprehension-agent.yaml
custom-reporter-integration.yaml
examples/electron/
electron-ipc-testing.yaml
electron-menu-testing.yaml
multi-window-coordination.yaml
single-window-basic.yaml
examples/tui/
file-manager-navigation.yaml
tui-form-validation.yaml
tui-performance-monitoring.yaml
examples/web/
dashboard-smoke-test.yaml
web-authentication-flow.yaml
web-visual-regression.yaml
scripts/
check-freshness.py
tests/
test_skill_examples.py

详细介绍

QA Team 技能

用途 [LEVEL 1]

此技能可帮助你创建智能体式外部测试,从外部用户的视角验证应用行为,而无需了解任何内部实现。借助 gadugi-agentic-test 框架,你可以编写声明式 YAML 场景,由 AI 智能体执行、观察和验证。

核心原则:测试描述应该发生什么,而非如何实现。智能体会自行确定执行细节。

何时使用此技能 [LEVEL 1]

最适合的场景
  • 冒烟测试:快速验证关键用户流程是否正常
  • 行为驱动测试:从用户视角验证功能
  • 跨平台测试:CLI、TUI、Web、Electron 使用相同的测试逻辑
  • 重构安全保障:实现发生变化时,测试仍然有效
  • AI 驱动测试:让智能体处理复杂交互
  • 将文档作为测试:YAML 场景也可作为可执行规范
在以下情况下使用此技能
  • 启动新项目并定义预期行为
  • 重构代码,需要不会因内部变更而失效的测试
  • 测试面向用户的应用(CLI 工具、TUI、Web 应用、桌面应用)
  • 编写可自动验证的验收标准
  • 需要非开发人员也能阅读和理解的测试
  • 希望发现关键用户工作流中的回归问题
  • 测试复杂的多步骤交互
在以下情况下不要使用此技能
  • 需要测试内部函数(请改用 test-gap-analyzer)
  • 测试性能或负载特征
  • 需要精确的计时或并发控制
  • 测试非交互式批处理流程
  • 实现细节比行为更重要

核心概念 [LEVEL 1]

由外而内的测试理念

传统的由内而外测试:

# Tightly coupled to implementation
def test_calculator_add():
    calc = Calculator()
    result = calc.add(2, 3)
    assert result == 5
    assert calc.history == [(2, 3, 5)]  # Knows internal state

智能体式由外而内测试:

# Implementation-agnostic behavior verification
scenario:
  name: "Calculator Addition"
  steps:
    - action: launch
      target: "./calculator"
    - action: send_input
      value: "add 2 3"
    - action: verify_output
      contains: "Result: 5"

优势:

  • 重构后测试依然有效(内部变更不会导致测试失效)
  • 非开发人员也能阅读(YAML 是声明式的)
  • 与平台无关(CLI/TUI/Web/Electron 使用相同结构)
  • AI 智能体处理复杂事项(导航、计时、截图)
Gadugi Agentic Test 框架 [LEVEL 2]

Gadugi-agentic-test 是一个 Python 框架,可以:

  1. 解析 YAML 测试场景及其声明式步骤
  2. 分派给专用智能体(CLI、TUI、Web、Electron 智能体)
  3. 执行操作(启动、输入、点击、等待、验证)
  4. 收集证据(截图、日志、输出捕获)
  5. 根据预期结果验证结果
  6. 生成报告并附带证据记录

架构:

YAML Scenario → Scenario Loader → Agent Dispatcher → Execution Engine
                                          ↓
                     [CLI Agent, TUI Agent, Web Agent, Electron Agent]
                                          ↓
                           Observers → Comprehension Agent
                                          ↓
                                   Evidence Report
渐进式披露级别 [LEVEL 1]

此技能通过四个级别教授测试:

  • Level 1:基础 - 基本的单操作测试、简单验证
  • Level 2:中级 - 多步骤流程、条件逻辑、错误处理
  • Level 3:高级 - 自定义智能体、视觉回归、性能验证
  • Level 4:一致性与影子测试 - 并排 A/B 对比、可观测的远程运行、发布差异记录

每个示例都标注了级别。请从 Level 1 开始,并根据需要逐步深入。

并排一致性与 A/B 验证 [LEVEL 2]

QA Team 是原先名为 outside-in-testing 的主要技能的新名称。你可以用它处理标准的由外而内场景,也可以用于一致性测试循环:从外部用户的观察角度,对比旧版实现与替代实现,或对比方案 A 与方案 B。

在以下一致性测试场景中使用 QA Team
  • 将 Python 迁移到 Rust、将旧 CLI 替换为新 CLI,或验证 v1 到 v2 的行为变化
  • 在切换默认版本之前验证重写版本
  • 使用相同的用户场景对比分支 A 与分支 B
  • 在成对的虚拟 TTY 中运行可观测的并排会话
  • 以影子模式记录发布差异,但不因此判定运行失败
建议的对等验证循环
  1. 首先定义双方共用的面向用户场景。
  2. 在隔离的沙盒中运行两种实现。
  3. 比较 stdout、stderr、退出代码、JSON 输出和文件系统副作用。
  4. 需要使用成对的 tmux 窗格进行调试时,请在 --observable 模式下重新运行。
  5. 必须在 azlin 等远程环境中进行对等验证时,请使用 --ssh-target <host>。
  6. 在推出期间使用 --shadow-mode --shadow-log <file> 记录差异,不阻止执行。
可复用的命令模式

如果仓库已有对等验证工具,请扩展它,而不是另建一套。一个不错的基线是:

python tests/parity/validate_cli_parity.py \
  --scenario tests/parity/scenarios/feature.yaml \
  --python-repo /path/to/legacy-repo \
  --rust-binary /path/to/new-binary \
  --observable

远程对等验证:

python tests/parity/validate_cli_parity.py \
  --ssh-target azlin \
  --scenario tests/parity/scenarios/feature.yaml \
  --python-repo /remote/path/to/legacy-repo \
  --rust-binary /remote/path/to/new-binary

推出期间记录影子日志:

python tests/parity/validate_cli_parity.py \
  --scenario tests/parity/scenarios/feature.yaml \
  --python-repo /path/to/legacy-repo \
  --rust-binary /path/to/new-binary \
  --shadow-mode \
  --shadow-log /tmp/feature-shadow.jsonl

快速入门 [LEVEL 1]

安装

前置条件(用于编译原生模块):

# macOS
xcode-select --install

# Ubuntu/Debian
sudo apt-get install -y build-essential python3

# Windows: Install Visual Studio Build Tools with "Desktop development with C++"

安装框架:

# Install globally for CLI access
npm install -g @gadugi/agentic-test

# Or install locally in your project
npm install @gadugi/agentic-test

# Verify installation
gadugi-test --version
第一个测试(CLI 示例)

创建 test-hello.yaml:

scenario:
  name: "Hello World CLI Test"
  description: "Verify CLI prints greeting"
  type: cli

  prerequisites:
    - "./hello-world executable exists"

  steps:
    - action: launch
      target: "./hello-world"

    - action: verify_output
      contains: "Hello, World!"

    - action: verify_exit_code
      expected: 0

运行测试:

gadugi-test run test-hello.yaml

输出:

✓ Scenario: Hello World CLI Test
  ✓ Step 1: Launched ./hello-world
  ✓ Step 2: Output contains "Hello, World!"
  ✓ Step 3: Exit code is 0

PASSED (3/3 steps successful)
Evidence saved to: ./evidence/test-hello-20250116-093045/
了解 YAML 结构 [LEVEL 1]

每个测试场景的结构如下:

scenario:
  name: "Descriptive test name"
  description: "What this test verifies"
  type: cli | tui | web | electron

  # Optional metadata
  tags: [smoke, critical, auth]
  timeout: 30s

  # What must be true before test runs
  prerequisites:
    - "Condition 1"
    - "Condition 2"

  # The test steps (executed sequentially)
  steps:
    - action: action_name
      parameter1: value1
      parameter2: value2

    - action: verify_something
      expected: value

  # Optional cleanup
  cleanup:
    - action: stop_application

应用类型和 Agent [LEVEL 2]

CLI 应用 [LEVEL 1]

用例:命令行工具、脚本、构建工具、包管理器

支持的操作:

  • launch - 启动 CLI 程序
  • send_input - 通过 stdin 发送文本或命令
  • send_signal - 发送操作系统信号(SIGINT、SIGTERM)
  • wait_for_output - 等待 stdout/stderr 中出现指定文本
  • verify_output - 检查 stdout/stderr 是否包含或匹配预期文本
  • verify_exit_code - 验证进程退出代码
  • capture_output - 保存输出以供稍后验证

示例(参见 examples/cli/calculator-basic.yaml):

scenario:
  name: "CLI Calculator Basic Operations"
  type: cli

  steps:
    - action: launch
      target: "./calculator"
      args: ["--mode", "interactive"]

    - action: send_input
      value: "add 5 3\n"

    - action: verify_output
      contains: "Result: 8"
      timeout: 2s

    - action: send_input
      value: "multiply 4 7\n"

    - action: verify_output
      contains: "Result: 28"

    - action: send_input
      value: "exit\n"

    - action: verify_exit_code
      expected: 0
TUI 应用 [LEVEL 1]

用例:终端用户界面(htop、vim、tmux、自定义仪表板 TUI)

支持的操作:

  • launch - 启动 TUI 应用
  • send_keypress - 发送键盘输入(方向键、回车、ctrl+c 等)
  • wait_for_screen - 等待屏幕上出现指定文本
  • verify_screen - 检查屏幕内容是否符合预期
  • capture_screenshot - 保存终端屏幕截图(ANSI 图案)
  • navigate_menu - 浏览菜单结构
  • fill_form - 填写 TUI 表单字段

示例(参见 examples/tui/file-manager-navigation.yaml):

scenario:
  name: "TUI File Manager Navigation"
  type: tui

  steps:
    - action: launch
      target: "./file-manager"

    - action: wait_for_screen
      contains: "File Manager v1.0"
      timeout: 3s

    - action: send_keypress
      value: "down"
      times: 3

    - action: verify_screen
      contains: "> documents/"
      description: "Third item should be selected"

    - action: send_keypress
      value: "enter"

    - action: wait_for_screen
      contains: "documents/"
      timeout: 2s

    - action: capture_screenshot
      save_as: "documents-view.txt"
Web 应用 [LEVEL 1]

用例:Web 应用、仪表板、SPA、管理面板

支持的操作:

  • navigate - 访问 URL
  • click - 根据选择器或文本点击元素
  • type - 在输入字段中输入文本
  • wait_for_element - 等待元素出现
  • verify_element - 检查元素是否存在或包含指定文本
  • verify_url - 验证当前 URL
  • screenshot - 截取浏览器屏幕
  • scroll - 滚动页面或元素

示例(参见 examples/web/dashboard-smoke-test.yaml):

scenario:
  name: "Dashboard Smoke Test"
  type: web

  steps:
    - action: navigate
      url: "http://localhost:3000/dashboard"

    - action: wait_for_element
      selector: "h1.dashboard-title"
      timeout: 5s

    - action: verify_element
      selector: "h1.dashboard-title"
      contains: "Analytics Dashboard"

    - action: verify_element
      selector: ".widget-stats"
      count: 4
      description: "Should have 4 stat widgets"

    - action: click
      selector: "button.refresh-data"

    - action: wait_for_element
      selector: ".loading-spinner"
      disappears: true
      timeout: 10s

    - action: screenshot
      save_as: "dashboard-loaded.png"
Electron 应用 [LEVEL 2]

用例:使用 Electron 构建的桌面应用(VS Code、Slack、Discord 克隆版)

支持的操作:

  • launch - 启动 Electron 应用
  • window_action - 与窗口交互(聚焦、最小化、关闭)
  • menu_click - 点击应用菜单项
  • dialog_action - 处理原生对话框(打开文件、保存、确认)
  • ipc_send - 向主进程发送 IPC 消息
  • verify_window - 检查窗口状态和属性
  • 所有 Web 操作(因为 Electron 使用 Chromium)

示例(参见 examples/electron/single-window-basic.yaml):

scenario:
  name: "Electron Single Window Test"
  type: electron

  steps:
    - action: launch
      target: "./dist/my-app"
      wait_for_window: true
      timeout: 10s

    - action: verify_window
      title: "My Application"
      visible: true

    - action: menu_click
      path: ["File", "New Document"]

    - action: wait_for_element
      selector: ".document-editor"

    - action: type
      selector: ".document-editor"
      value: "Hello from test"

    - action: menu_click
      path: ["File", "Save"]

    - action: dialog_action
      type: save_file
      filename: "test-document.txt"

    - action: verify_window
      title_contains: "test-document.txt"

测试场景剖析 [LEVEL 2]

元数据部分
scenario:
  name: "Clear descriptive name"
  description: "Detailed explanation of what this test verifies"
  type: cli | tui | web | electron

  # Optional fields
  tags: [smoke, regression, auth, payment]
  priority: high | medium | low
  timeout: 60s # Overall scenario timeout
  retry_on_failure: 2 # Retry count

  # Environment requirements
  environment:
    variables:
      API_URL: "http://localhost:8080"
      DEBUG: "true"
    files:
      - "./config.json must exist"
前置条件

前置条件是测试运行前必须满足的条件。框架会在执行前验证这些条件。

prerequisites:
  - "./application binary exists"
  - "Port 8080 is available"
  - "Database is running"
  - "User account [email protected] exists"
  - "File ./test-data.json exists"

如果前置条件未满足,则跳过测试(而不是将其判定为失败)。

步骤

步骤按顺序执行。每个步骤包含:

  • action:必填——要执行的操作
  • Parameters:操作专属参数
  • description:可选——面向用户的说明
  • timeout:可选——步骤专属超时时间
  • continue_on_failure:可选——步骤失败时不将场景判定为失败
steps:
  # Simple action
  - action: launch
    target: "./app"

  # Action with multiple parameters
  - action: verify_output
    contains: "Success"
    timeout: 5s
    description: "App should print success message"

  # Continue even if this fails
  - action: click
    selector: ".optional-button"
    continue_on_failure: true
验证操作 [LEVEL 1]

验证操作用于检查预期结果。如果未达到预期,它们会使测试失败。

常见验证:

# CLI: Check output contains text
- action: verify_output
  contains: "Expected text"

# CLI: Check output matches regex
- action: verify_output
  matches: "Result: \\d+"

# CLI: Check exit code
- action: verify_exit_code
  expected: 0

# Web/TUI: Check element exists
- action: verify_element
  selector: ".success-message"

# Web/TUI: Check element contains text
- action: verify_element
  selector: "h1"
  contains: "Welcome"

# Web: Check URL
- action: verify_url
  equals: "http://localhost:3000/dashboard"

# Web: Check element count
- action: verify_element
  selector: ".list-item"
  count: 5

# Electron: Check window state
- action: verify_window
  title: "My App"
  visible: true
  focused: true
清理部分

清理操作会在所有步骤完成后运行(无论成功还是失败)。可用于执行拆卸操作。

cleanup:
  - action: stop_application
    force: true

  - action: delete_file
    path: "./temp-test-data.json"

  - action: reset_database
    connection: "test_db"

高级模式 [LEVEL 2]

条件逻辑

根据条件执行步骤:

steps:
  - action: launch
    target: "./app"

  - action: verify_output
    contains: "Login required"
    id: login_check

  # Only run if login_check passed
  - action: send_input
    value: "login admin password123\n"
    condition: login_check.passed
变量与模板 [LEVEL 2]

定义变量并在整个场景中使用:

scenario:
  name: "Test with Variables"
  type: cli

  variables:
    username: "testuser"
    api_url: "http://localhost:8080"

  steps:
    - action: launch
      target: "./app"
      args: ["--api", "${api_url}"]

    - action: send_input
      value: "login ${username}\n"

    - action: verify_output
      contains: "Welcome, ${username}!"
循环与重复 [LEVEL 2]

多次重复操作:

steps:
  - action: launch
    target: "./app"

  # Repeat action N times
  - action: send_keypress
    value: "down"
    times: 5

  # Loop over list
  - action: send_input
    value: "${item}\n"
    for_each:
      - "apple"
      - "banana"
      - "cherry"
错误处理 [LEVEL 2]

妥善处理预期错误:

steps:
  - action: send_input
    value: "invalid command\n"

  # Verify error message appears
  - action: verify_output
    contains: "Error: Unknown command"
    expected_failure: true

  # App should still be running
  - action: verify_running
    expected: true
多步骤工作流 [LEVEL 2]

包含多个阶段的复杂场景:

scenario:
  name: "E-commerce Purchase Flow"
  type: web

  steps:
    # Phase 1: Authentication
    - action: navigate
      url: "http://localhost:3000/login"

    - action: type
      selector: "#username"
      value: "[email protected]"

    - action: type
      selector: "#password"
      value: "password123"

    - action: click
      selector: "button[type=submit]"

    - action: wait_for_url
      contains: "/dashboard"

    # Phase 2: Product Selection
    - action: navigate
      url: "http://localhost:3000/products"

    - action: click
      text: "Add to Cart"
      nth: 1

    - action: verify_element
      selector: ".cart-badge"
      contains: "1"

    # Phase 3: Checkout
    - action: click
      selector: ".cart-icon"

    - action: click
      text: "Proceed to Checkout"

    - action: fill_form
      fields:
        "#shipping-address": "123 Test St"
        "#city": "Testville"
        "#zip": "12345"

    - action: click
      selector: "#place-order"

    - action: wait_for_element
      selector: ".order-confirmation"
      timeout: 10s

    - action: verify_element
      selector: ".order-number"
      exists: true

第 3 级:高级主题 [LEVEL 3]

自定义理解 Agent

该框架使用 AI Agent 解读应用输出,并判断测试是否通过。你可以为这些 Agent 定制特定领域的逻辑。

默认理解 Agent:

  • 观察原始输出(文本、HTML、截图)
  • 运用通用推理验证预期
  • 返回通过/失败结果及说明

自定义理解 Agent(参见 examples/custom-agents/custom-comprehension-agent.yaml):

scenario:
  name: "Financial Dashboard Test with Custom Agent"
  type: web

  # Define custom comprehension logic
  comprehension_agent:
    model: "gpt-4"
    system_prompt: |
      You are a financial data validator. When verifying dashboard content:
      1. All monetary values must use proper formatting ($1,234.56)
      2. Percentages must include % symbol
      3. Dates must be in MM/DD/YYYY format
      4. Negative values must be red
      5. Chart data must be logically consistent

      Be strict about formatting and data consistency.

    examples:
      - input: "Total Revenue: 45000"
        output: "FAIL - Missing currency symbol and comma separator"
      - input: "Total Revenue: $45,000.00"
        output: "PASS - Correctly formatted"

  steps:
    - action: navigate
      url: "http://localhost:3000/financial-dashboard"

    - action: verify_element
      selector: ".revenue-widget"
      use_custom_comprehension: true
      description: "Revenue should be properly formatted"
视觉回归测试 [LEVEL 3]

将截图与基准图像进行比较:

scenario:
  name: "Visual Regression - Homepage"
  type: web

  steps:
    - action: navigate
      url: "http://localhost:3000"

    - action: wait_for_element
      selector: ".page-loaded"

    - action: screenshot
      save_as: "homepage.png"

    - action: visual_compare
      screenshot: "homepage.png"
      baseline: "./baselines/homepage-baseline.png"
      threshold: 0.05 # 5% difference allowed
      highlight_differences: true
性能验证 [LEVEL 3]

测量并验证性能指标:

scenario:
  name: "Performance - Dashboard Load Time"
  type: web

  performance:
    metrics:
      - page_load_time
      - first_contentful_paint
      - time_to_interactive

  steps:
    - action: navigate
      url: "http://localhost:3000/dashboard"
      measure_timing: true

    - action: verify_performance
      metric: page_load_time
      less_than: 3000 # 3 seconds

    - action: verify_performance
      metric: first_contentful_paint
      less_than: 1500 # 1.5 seconds
多窗口协调(Electron)[LEVEL 3]

测试包含多个窗口的应用:

scenario:
  name: "Multi-Window Chat Application"
  type: electron

  steps:
    - action: launch
      target: "./chat-app"

    - action: menu_click
      path: ["Window", "New Chat"]

    - action: verify_window
      count: 2

    - action: window_action
      window: 1
      action: focus

    - action: type
      selector: ".message-input"
      value: "Hello from window 1"

    - action: click
      selector: ".send-button"

    - action: window_action
      window: 2
      action: focus

    - action: wait_for_element
      selector: ".message"
      contains: "Hello from window 1"
      timeout: 5s
IPC 测试(Electron)[LEVEL 3]

测试渲染进程与主进程之间的进程间通信:

scenario:
  name: "Electron IPC Communication"
  type: electron

  steps:
    - action: launch
      target: "./my-app"

    - action: ipc_send
      channel: "get-system-info"

    - action: ipc_expect
      channel: "system-info-reply"
      timeout: 3s

    - action: verify_ipc_payload
      contains:
        platform: "darwin"
        arch: "x64"
自定义报告器 [LEVEL 3]

生成自定义测试报告:

scenario:
  name: "Test with Custom Reporting"
  type: cli

  reporting:
    format: custom
    template: "./report-template.html"
    include:
      - screenshots
      - logs
      - timing_data
      - video_recording

    email:
      enabled: true
      recipients: ["[email protected]"]
      on_failure_only: true

  steps:
    # ... test steps ...

框架集成 [LEVEL 2]

运行测试

单个测试:

gadugi-test run test-scenario.yaml

多个测试:

gadugi-test run tests/*.yaml

使用选项:

gadugi-test run test.yaml \
  --verbose \
  --evidence-dir ./test-evidence \
  --retry 2 \
  --timeout 60s
CI/CD 集成

GitHub Actions(.github/workflows/agentic-tests.yml):

name: Agentic Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Install gadugi-agentic-test
        run: npm install -g @gadugi/agentic-test

      - name: Run tests
        run: gadugi-test run tests/agentic/*.yaml

      - name: Upload evidence
        if: always()
        uses: actions/upload-artifact@v3
        with:
          name: test-evidence
          path: ./evidence/
证据收集

该框架会自动收集证据,以便调试:

evidence/
  scenario-name-20250116-093045/
    ├── scenario.yaml          # Original test scenario
    ├── execution-log.json     # Detailed execution log
    ├── screenshots/           # All captured screenshots
    │   ├── step-1.png
    │   ├── step-3.png
    │   └── step-5.png
    ├── output-captures/       # CLI/TUI output
    │   ├── stdout.txt
    │   └── stderr.txt
    ├── timing.json            # Performance metrics
    └── report.html            # Human-readable report

最佳实践 [LEVEL 2]

1. 从简单开始,逐步增加复杂度

从基本的冒烟测试开始,然后逐步添加细节:

# Level 1: Basic smoke test
steps:
  - action: launch
    target: "./app"
  - action: verify_output
    contains: "Ready"

# Level 2: Add interaction
steps:
  - action: launch
    target: "./app"
  - action: send_input
    value: "command\n"
  - action: verify_output
    contains: "Success"

# Level 3: Add error handling and edge cases
steps:
  - action: launch
    target: "./app"
  - action: send_input
    value: "invalid\n"
  - action: verify_output
    contains: "Error"
  - action: send_input
    value: "command\n"
  - action: verify_output
    contains: "Success"
2. 使用描述性名称和说明
# Bad
scenario:
  name: "Test 1"
  steps:
    - action: click
      selector: "button"

# Good
scenario:
  name: "User Login Flow - Valid Credentials"
  description: "Verifies user can log in with valid email and password"
  steps:
    - action: click
      selector: "button[type=submit]"
      description: "Submit login form"
3. 仅验证关键路径

不要测试每个微小细节。应关注面向用户的行为:

# Bad - Tests implementation details
- action: verify_element
  selector: ".internal-cache-status"
  contains: "initialized"

# Good - Tests user-visible behavior
- action: verify_element
  selector: ".welcome-message"
  contains: "Welcome back"
4. 使用前置条件处理测试依赖
scenario:
  name: "User Profile Edit"

  prerequisites:
    - "User [email protected] exists"
    - "User is logged in"
    - "Database is seeded with test data"

  steps:
    # Test assumes prerequisites are met
    - action: navigate
      url: "/profile"
5. 保持测试独立

每个测试都应自行设置状态并进行清理:

scenario:
  name: "Create Document"

  steps:
    # Create test user (don't assume exists)
    - action: api_call
      endpoint: "/api/users"
      method: POST
      data: { email: "[email protected]" }

    # Run test
    - action: navigate
      url: "/documents/new"
    # ... test steps ...

  cleanup:
    # Remove test user
    - action: api_call
      endpoint: "/api/users/[email protected]"
      method: DELETE
6. 使用标签进行组织
scenario:
  name: "Critical Payment Flow"
  tags: [smoke, critical, payment, e2e]
  # Run with: gadugi-test run --tags critical
7. 有策略地设置超时
steps:
  # Quick operations - short timeout
  - action: click
    selector: "button"
    timeout: 2s

  # Network operations - longer timeout
  - action: wait_for_element
    selector: ".data-loaded"
    timeout: 10s

  # Complex operations - generous timeout
  - action: verify_element
    selector: ".report-generated"
    timeout: 60s

测试策略 [LEVEL 2]

冒烟测试

用于验证关键功能正常运行的最小化测试:

scenario:
  name: "Smoke Test - Application Starts"
  tags: [smoke]

  steps:
    - action: launch
      target: "./app"
    - action: verify_output
      contains: "Ready"
      timeout: 5s

每次提交前运行:gadugi-test run --tags smoke

理想路径测试

测试理想的用户旅程:

scenario:
  name: "Happy Path - User Registration"

  steps:
    - action: navigate
      url: "/register"
    - action: type
      selector: "#email"
      value: "[email protected]"
    - action: type
      selector: "#password"
      value: "SecurePass123!"
    - action: click
      selector: "button[type=submit]"
    - action: wait_for_url
      contains: "/welcome"
错误路径测试

验证错误处理:

scenario:
  name: "Error Path - Invalid Login"

  steps:
    - action: navigate
      url: "/login"
    - action: type
      selector: "#email"
      value: "[email protected]"
    - action: type
      selector: "#password"
      value: "wrongpassword"
    - action: click
      selector: "button[type=submit]"
    - action: verify_element
      selector: ".error-message"
      contains: "Invalid credentials"
回归测试

防止错误再次出现:

scenario:
  name: "Regression - Issue #123 Password Reset"
  tags: [regression, bug-123]
  description: "Verifies password reset email is sent (was broken in v1.2)"

  steps:
    - action: navigate
      url: "/forgot-password"
    - action: type
      selector: "#email"
      value: "[email protected]"
    - action: click
      selector: "button[type=submit]"
    - action: verify_element
      selector: ".success-message"
      contains: "Reset email sent"

理念契合 [LEVEL 2]

此技能遵循 amplihack 的核心原则:

极致简洁
  • 使用 YAML 而非代码:声明式测试比编程式测试更简单
  • 不涉及实现细节:测试描述的是做什么,而非如何做
  • 尽量减少样板内容:每项测试都聚焦且简洁
模块化设计(积木与连接件)
  • 自包含场景:每个 YAML 文件都相互独立
  • 明确的契约:步骤具有明确定义的输入和输出
  • 可组合操作:在不同测试类型中重复使用操作
零废话实现
  • 没有存根:此技能中的每个示例都是完整、可运行的测试
  • 开箱即用的默认值:测试只需最少配置即可运行
  • 明确的错误信息:框架提供可据以采取行动的错误消息
由外而内思考
  • 用户视角:测试验证用户关心的行为
  • 不依赖实现方式:重构不会破坏测试
  • 行为驱动:关注结果,而非内部实现

常见陷阱与解决方案 [LEVEL 2]

陷阱 1:过度指定

问题:UI 稍有变化,测试就会失败

# Bad - Too specific
- action: verify_element
  selector: "div.container > div.row > div.col-md-6 > span.text-primary.font-bold"
  contains: "Welcome"

解决方案:使用灵活的选择器

# Good - Focused on behavior
- action: verify_element
  selector: ".welcome-message"
  contains: "Welcome"
陷阱 2:缺少等待

问题:测试因时序问题而间歇性失败

# Bad - No wait for async operation
- action: click
  selector: ".load-data-button"
- action: verify_element
  selector: ".data-table" # May not exist yet!

解决方案:始终等待动态内容

# Good - Wait for element to appear
- action: click
  selector: ".load-data-button"
- action: wait_for_element
  selector: ".data-table"
  timeout: 10s
- action: verify_element
  selector: ".data-table"
陷阱 3:测试实现细节

问题:测试与内部状态耦合

# Bad - Tests internal cache state
- action: verify_output
  contains: "Cache hit ratio: 85%"

解决方案:测试用户可见的行为

# Good - Tests response time
- action: verify_response_time
  less_than: 100ms
  description: "Fast response indicates caching works"
陷阱 4:不稳定的断言

问题:断言依赖精确的时序或格式

# Bad - Exact timestamp match will fail
- action: verify_output
  contains: "Created at: 2025-11-16 09:30:45"

解决方案:使用灵活的模式

# Good - Match pattern, not exact value
- action: verify_output
  matches: "Created at: \\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}"
陷阱 5:未清理

问题:测试会留下影响后续运行的残留物

# Bad - No cleanup
steps:
  - action: create_file
    path: "./test-data.json"
  - action: launch
    target: "./app"

解决方案:始终使用清理部分

# Good - Cleanup ensures clean slate
steps:
  - action: create_file
    path: "./test-data.json"
  - action: launch
    target: "./app"

cleanup:
  - action: delete_file
    path: "./test-data.json"

示例库 [LEVEL 1]

此技能包含 15 个完整可运行的示例,按应用类型和复杂度级别组织:

CLI 示例
  1. calculator-basic.yaml [LEVEL 1] - 简单的 CLI 算术运算
  2. cli-error-handling.yaml [LEVEL 2] - 错误消息与恢复
  3. cli-interactive-session.yaml [LEVEL 2] - 多轮交互式 CLI
TUI 示例
  1. file-manager-navigation.yaml [LEVEL 1] - 基础 TUI 键盘导航
  2. tui-form-validation.yaml [LEVEL 2] - 复杂表单填写与验证
  3. tui-performance-monitoring.yaml [LEVEL 3] - TUI 性能仪表板测试
Web 示例
  1. dashboard-smoke-test.yaml [LEVEL 1] - 简单的 Web 仪表板验证
  2. web-authentication-flow.yaml [LEVEL 2] - 多步骤登录工作流
  3. web-visual-regression.yaml [LEVEL 2] - 基于截图的视觉测试
Electron 示例
  1. single-window-basic.yaml [LEVEL 1] - 基础 Electron 窗口测试
  2. multi-window-coordination.yaml [LEVEL 2] - 多窗口协调
  3. electron-menu-testing.yaml [LEVEL 2] - 应用菜单交互
  4. electron-ipc-testing.yaml [LEVEL 3] - 主进程/渲染进程 IPC 测试
自定义 Agent 示例
  1. custom-comprehension-agent.yaml [LEVEL 3] - 特定领域的验证逻辑
  2. custom-reporter-integration.yaml [LEVEL 3] - 自定义测试报告

完整示例代码及内联文档请参见 examples/ 目录。

框架更新检查 [LEVEL 3]

此技能内置了关于 gadugi-agentic-test 版本 0.1.0 的知识。若要检查是否有更新版本:

# Run the freshness check script
python scripts/check-freshness.py

# Output if outdated:
# WARNING: Embedded framework version is 0.1.0
# Latest GitHub version is 0.2.5
#
# New features in 0.2.5:
# - Native Playwright support for web testing
# - Video recording for all test types
# - Parallel test execution
#
# Update with: npm update -g @gadugi/agentic-test

该脚本会检查 GitHub 仓库中的发行版本,并与内置版本进行比较。这样可确保你及时了解新功能和改进。

何时更新此技能:

  • 新框架版本增加了重要功能
  • YAML 架构发生不兼容变更
  • 支持新的应用类型
  • Agent 能力扩展

与其他技能集成 [LEVEL 2]

搭配效果良好

test-gap-analyzer:

  • 使用 test-gap-analyzer 查找未经测试的函数
  • 为关键的用户可见路径编写由外向内的测试
  • 使用单元测试(来自 test-gap-analyzer)测试内部函数

philosophy-guardian:

  • 确保测试 YAML 遵循极致简洁原则
  • 确认测试关注行为,而非实现

pr-review-assistant:

  • 在 PR 审查中加入由外向内的测试
  • 确认测试覆盖了变更的功能
  • 检查测试是否易读、清晰

module-spec-generator:

  • 生成包含由外向内测试场景的模块规范
  • 使用规范作为测试 YAML 的模板
组合工作流示例
# 1. Analyze coverage gaps
claude "Use test-gap-analyzer on ./src"

# 2. Write outside-in tests for critical paths
claude "Use qa-team to create web tests for authentication"

# 3. Verify philosophy compliance
claude "Use philosophy-guardian to review new test files"

# 4. Include in PR
git add tests/agentic/
git commit -m "Add outside-in tests for auth flow"

故障排除 [LEVEL 2]

测试超时

症状:测试超过超时时间并失败

原因:

  • 应用启动耗时超过预期
  • 网络请求较慢
  • 元素从未出现(选择器不正确)

解决方案:

# Increase timeout
- action: wait_for_element
  selector: ".slow-loading-element"
  timeout: 30s # Increase from default

# Add intermediate verification
- action: launch
  target: "./app"
- action: wait_for_output
  contains: "Initializing..."
  timeout: 5s
- action: wait_for_output
  contains: "Ready"
  timeout: 20s
找不到元素

症状:verify_element 或 click 因“找不到元素”而失败

原因:

  • CSS 选择器不正确
  • 元素尚未渲染(时序问题)
  • 元素位于 iframe 或 Shadow DOM 中

解决方案:

# Add wait before interaction
- action: wait_for_element
  selector: ".target-element"
  timeout: 10s
- action: click
  selector: ".target-element"

# Use more specific selector
- action: click
  selector: "button[data-testid='submit-button']"

# Handle iframe
- action: switch_to_iframe
  selector: "iframe#payment-frame"
- action: click
  selector: ".pay-now-button"
在本地测试通过,但在 CI 中失败

症状:测试在开发机器上正常运行,但在 CI 环境中失败

原因:

  • 屏幕尺寸不同(Web/Electron)
  • 缺少依赖
  • 时序差异(CI 机器速度较慢)
  • 环境变量不同

解决方案:

# Set explicit viewport size (web/Electron)
scenario:
  environment:
    viewport:
      width: 1920
      height: 1080

# Add longer timeouts in CI
- action: wait_for_element
  selector: ".element"
  timeout: 30s  # Generous for CI

# Verify prerequisites
prerequisites:
  - "Chrome browser installed"
  - "Environment variable API_KEY is set"
输出与预期不符

症状:尽管输出看起来正确,verify_output 仍然失败

原因:

  • 存在额外的空格或换行符
  • 输出中包含 ANSI 颜色代码
  • 区分大小写

解决方案:

# Use flexible matching
- action: verify_output
  matches: "Result:\\s+Success" # Allow flexible whitespace

# Strip ANSI codes
- action: verify_output
  contains: "Success"
  strip_ansi: true

# Case-insensitive match
- action: verify_output
  contains: "success"
  case_sensitive: false

参考:操作目录 [LEVEL 3]

CLI 操作
操作参数说明
launchtarget、args、cwd、env启动 CLI 应用程序
send_inputvalue、delay向 stdin 发送文本
send_signalsignal发送操作系统信号(SIGINT、SIGTERM 等)
wait_for_outputcontains、matches、timeout等待 stdout/stderr 中出现文本
verify_outputcontains、matches、stream检查输出内容
verify_exit_codeexpected验证退出代码
capture_outputsave_as、stream将输出保存到文件
TUI 操作
操作参数说明
launchtarget、args、terminal_size启动 TUI 应用程序
send_keypressvalue、times、modifiers发送键盘输入
wait_for_screencontains、timeout等待屏幕上出现文本
verify_screencontains、matches、region检查屏幕内容
capture_screenshotsave_as保存终端屏幕截图
navigate_menupath按菜单结构导航
fill_formfields填写 TUI 表单字段
Web 操作
操作参数说明
navigateurl、wait_for_load前往 URL
clickselector、text、nth点击元素
typeselector、value、delay在输入框中输入
wait_for_elementselector、timeout、disappears等待元素
verify_elementselector、contains、count、exists检查元素状态
verify_urlequals、contains、matches验证 URL
screenshotsave_as、selector、full_page捕获屏幕截图
scrollselector、direction、amount滚动页面/元素
select_optionselector、value选择下拉选项
checkboxselector、checked勾选/取消勾选复选框
Electron 操作
操作参数描述
launchtarget, args, wait_for_window启动 Electron 应用
window_actionwindow, action与窗口交互
menu_clickpath点击菜单项
dialog_actiontype, action, filename处理对话框
ipc_sendchannel, data发送 IPC 消息
ipc_expectchannel, timeout等待 IPC 消息
verify_windowtitle, visible, focused, count检查窗口状态
所有 Web 操作Electron 包含 Chromium
常用参数
参数类型描述
timeoutDuration最长等待时间(例如,“5s”、“2m”)
descriptionString面向用户的步骤说明
continue_on_failureBoolean步骤失败时不让场景失败
idString用于条件判断的步骤标识符
conditionExpression仅当条件为 true 时执行步骤

快速参考:YAML 模板 [LEVEL 1]

scenario:
  # Required fields
  name: "Test Name"
  description: "What this test verifies"
  type: cli | tui | web | electron

  # Optional metadata
  tags: [smoke, critical]
  timeout: 60s

  # What must be true before running
  prerequisites:
    - "Condition 1"
    - "Condition 2"

  # Environment setup
  environment:
    variables:
      VAR_NAME: "value"

  # Variables for templating
  variables:
    username: "testuser"

  # Test steps (executed in order)
  steps:
    - action: launch
      target: "./app"

    - action: send_input
      value: "command\n"

    - action: verify_output
      contains: "Success"
      timeout: 5s

  # Cleanup (always runs)
  cleanup:
    - action: stop_application

技能使用示例 [LEVEL 1]

调用此技能
Claude, use the qa-team skill to create a CLI test for my calculator app.

Claude, use qa-team to generate web tests for the login flow.

Claude, create TUI tests using the qa-team skill for file navigation.
你将获得
  1. 完整的 YAML 测试场景,符合你的需求
  2. 内联文档,说明各个部分
  3. 应用最佳实践(超时、等待、验证)
  4. 合适的复杂度级别(根据需求分为 1、2 或 3 级)
  5. 运行测试的说明
请求与响应示例

用户:“创建一个使用有效凭据进行用户登录的 Web 测试”

Claude(使用此技能):

scenario:
  name: "User Login - Valid Credentials"
  description: "Verifies user can successfully log in with valid email and password"
  type: web
  tags: [smoke, auth, critical]

  prerequisites:
    - "User [email protected] exists with password 'TestPass123!'"
    - "Application is running on http://localhost:3000"

  steps:
    # Navigate to login page
    - action: navigate
      url: "http://localhost:3000/login"
      description: "Open login page"

    # Wait for page to fully load
    - action: wait_for_element
      selector: "form.login-form"
      timeout: 5s
      description: "Wait for login form to render"

    # Fill in email field
    - action: type
      selector: "input[name='email']"
      value: "[email protected]"
      description: "Enter email address"

    # Fill in password field
    - action: type
      selector: "input[name='password']"
      value: "TestPass123!"
      description: "Enter password"

    # Submit form
    - action: click
      selector: "button[type='submit']"
      description: "Click login button"

    # Wait for redirect to dashboard
    - action: wait_for_url
      contains: "/dashboard"
      timeout: 10s
      description: "Should redirect to dashboard after successful login"

    # Verify user is logged in
    - action: verify_element
      selector: ".user-profile"
      contains: "[email protected]"
      description: "User email should appear in profile widget"

    # Capture evidence
    - action: screenshot
      save_as: "successful-login.png"
      description: "Save screenshot of logged-in state"
# To run this test:
# 1. Save as test-login-valid.yaml
# 2. Run: gadugi-test run test-login-valid.yaml
# 3. Check evidence in ./evidence/user-login-valid-credentials-TIMESTAMP/

相关资源 [LEVEL 1]

官方文档

第 4 级:影子环境集成 [LEVEL 4]

在隔离的影子环境中运行外部测试,在推送前验证更改。此方法结合了 gadugi-agentic-test 的行为测试能力与影子环境的干净状态隔离。

为什么使用影子环境进行测试
  1. 干净状态:全新容器,不会污染主机
  2. 本地更改:按原样测试尚未提交的代码
  3. 多仓库:协调多个仓库之间的更改
  4. CI 一致性:影子环境看到的 ≈ CI 将看到的
影子测试工作流

如需完整的影子环境文档,请参阅 shadow-testing 技能。以下介绍如何将其与外部测试集成:

模式 1:在影子环境中运行 CLI 测试(Amplifier)
# Create shadow with your local library changes
shadow.create(local_sources=["~/repos/my-lib:org/my-lib"])

# Run outside-in test scenarios inside shadow
shadow.exec(shadow_id, "gadugi-test run test-scenario.yaml")

# Extract evidence
shadow.extract(shadow_id, "/evidence", "./test-evidence")

# Cleanup
shadow.destroy(shadow_id)
模式 2:在影子环境中运行 CLI 测试(独立模式)
# Create shadow with local changes
amplifier-shadow create --local ~/repos/my-lib:org/my-lib --name test

# Run your test scenarios
amplifier-shadow exec test "gadugi-test run test-scenario.yaml"

# Extract results
amplifier-shadow extract test /evidence ./test-evidence

# Cleanup
amplifier-shadow destroy test
模式 3:多仓库集成测试
# test-multi-repo.yaml
scenario:
  name: "Multi-Repo Integration Test"
  type: cli

  prerequisites:
    - "Shadow environment with core-lib and cli-tool"

  steps:
    - action: launch
      target: "cli-tool"

    - action: send_input
      value: "process --lib core-lib\n"

    - action: verify_output
      contains: "Success: Using core-lib"
# Setup shadow with both repos
amplifier-shadow create \
  --local ~/repos/core-lib:org/core-lib \
  --local ~/repos/cli-tool:org/cli-tool \
  --name multi-test

# Run test that exercises both
amplifier-shadow exec multi-test "gadugi-test run test-multi-repo.yaml"
模式 4:在影子环境中测试 Web 应用
# test-web-app.yaml
scenario:
  name: "Web App with Local Library"
  type: web

  steps:
    - action: navigate
      url: "http://localhost:3000"

    - action: click
      selector: "button.process"

    - action: verify_element
      selector: ".result"
      contains: "Processed with v2.0" # Your local version
# Shadow with library changes
amplifier-shadow create --local ~/repos/my-lib:org/my-lib --name web-test

# Start web app inside shadow (uses your local lib)
amplifier-shadow exec web-test "
  cd /workspace &&
  git clone https://github.com/org/web-app &&
  cd web-app &&
  npm install &&  # Pulls your local my-lib via git URL rewriting
  npm start &
"

# Wait for app to start, then run tests
amplifier-shadow exec web-test "sleep 5 && gadugi-test run test-web-app.yaml"
验证最佳实践

在影子环境中运行测试时,务必验证使用的是本地源代码:

# After shadow.create, check snapshot commits
shadow.status(shadow_id)
# Shows: snapshot_commits: {"org/my-lib": "abc1234..."}

# When your test installs dependencies, verify commit matches
# Look in test output for: my-lib @ git+...@abc1234
完整示例:验证库更改
# test-library-change.yaml - Outside-in test
scenario:
  name: "Validate Library Breaking Change"
  type: cli
  description: "Test that dependent app still works with new library API"

  steps:
    - action: launch
      target: "/workspace/org/dependent-app/cli.py"

    - action: send_input
      value: "process data.json\n"

    - action: verify_output
      contains: "Processed successfully"
      description: "New library API should still work"

    - action: verify_exit_code
      expected: 0
# Complete workflow
# 1. Create shadow with your breaking change
amplifier-shadow create --local ~/repos/my-lib:org/my-lib --name breaking-test

# 2. Install dependent app (pulls your local lib)
amplifier-shadow exec breaking-test "
  cd /workspace &&
  git clone https://github.com/org/dependent-app &&
  cd dependent-app &&
  pip install -e . &&  # This installs git+https://github.com/org/my-lib (your local version)
  echo 'Ready to test'
"

# 3. Run outside-in test
amplifier-shadow exec breaking-test "gadugi-test run test-library-change.yaml"

# If test passes, your breaking change is compatible!
# If test fails, you've caught the issue before pushing
何时使用 Shadow 集成

在以下情况下,使用 shadow + 外向内测试:

  • ✅ 使用依赖项目测试库的更改
  • ✅ 验证跨多个仓库的协调更改
  • ✅ 推送前需要在干净状态下进行验证
  • ✅ 希望及早发现集成问题
  • ✅ 测试设置和安装流程是否正常

以下情况不要使用 shadow:

  • ❌ 简单的单元测试(开销太大)
  • ❌ 测试已提交的代码(shadow 没有额外价值)
  • ❌ 性能测试(容器开销会使结果失真)
了解更多

完整的 shadow 环境文档包括:

  • 用于 DIY 设置的 Shell 脚本
  • Docker Compose 示例
  • 多语言支持(Python、Node、Rust、Go)
  • 故障排查和验证技巧

加载 shadow-testing 技能:

Claude, use the shadow-testing skill to set up a shadow environment

对于 Amplifier 用户,shadow 工具已内置:

shadow.create(local_sources=["~/repos/lib:org/lib"])

相关技能
  • shadow-testing:完整的 shadow 环境设置和使用说明
  • test-gap-analyzer:查找未经测试的代码路径
  • philosophy-guardian:审查测试理念的遵循情况
  • pr-review-assistant:在 PR 审查中纳入测试
  • module-spec-generator:生成包含测试场景的规范
延伸阅读
  • 外向内与内向外测试方法
  • 行为驱动开发(BDD)原则
  • AI 驱动测试的最佳实践
  • 测试自动化模式
  • Shadow 环境测试方法

第 4 级:A/B 比较工具和自我改进审计 [LEVEL 4]

可复用工具,用于并排运行任意两个 CLI 实现,并量化它们的行为差异。适用于任何需要比较两者的场景:

  • 迁移一致性:Python→Rust、v1→v2、单体→微服务
  • A/B 测试:比较针对同一 CLI 的两种方法
  • 功能标志验证:同一个二进制文件,不同的配置
  • 版本回归:比较版本 N 与版本 N+1
  • 金丝雀验证:将金丝雀构建与稳定版进行比较
工具

位于 .claude/scenarios/ab-comparison/:

文件用途
ab_comparison_harness.py在隔离沙箱中并排运行两个 CLI
ab_audit_cycle.py自我改进循环:识别 → 分类 → 修复 → 重新验证
SCENARIO_FORMAT.mdYAML 场景格式规范
example_scenario.yaml计算器 CLI 的示例场景
快速开始
# Compare any two CLI implementations
python .claude/scenarios/ab-comparison/ab_comparison_harness.py \
    --a "python -m myapp.cli" \
    --b "./target/debug/myapp" \
    --scenario tests/scenarios/*.yaml

# A/B with feature flag
python .claude/scenarios/ab-comparison/ab_comparison_harness.py \
    --a "myapp --feature-flag=off" \
    --b "myapp --feature-flag=on" \
    --scenario tests/scenarios/regression.yaml

# Shadow mode: log divergences without failing (for production rollout)
python .claude/scenarios/ab-comparison/ab_comparison_harness.py \
    --a "myapp-stable" \
    --b "myapp-canary" \
    --scenario tests/scenarios/*.yaml \
    --shadow-mode \
    --shadow-log /tmp/canary-divergences.jsonl

# Self-improving audit cycle (iterate until convergence)
python .claude/scenarios/ab-comparison/ab_audit_cycle.py \
    --a "python -m myapp.cli" \
    --b "./target/debug/myapp" \
    --scenarios-dir tests/scenarios/

# Legacy flags (--legacy/--candidate) also work
python .claude/scenarios/ab-comparison/ab_comparison_harness.py \
    --legacy "python -m myapp.cli" \
    --candidate "./target/debug/myapp" \
    --scenario tests/scenarios/*.yaml
场景格式(摘要)
cases:
  - name: "unique-test-name"
    category: "install"                     # For audit grouping
    argv: ["subcommand", "--flag"]          # Same args for both sides
    timeout: 15                             # Seconds
    env:
      PATH: "${SANDBOX_ROOT}/bin:${PATH}"   # Template variables
    setup: |                                # Bash script run in both sandboxes
      mkdir -p bin
      echo '#!/bin/bash' > bin/stub && chmod +x bin/stub
    compare:
      - exit_code                           # Integer match
      - stdout                              # Text or JSON-semantic
      - stderr                              # Text match
      - "fs:path/to/file"                  # File/dir hash comparison
      - "jsonfs:path/to/file.json"         # JSON semantic comparison

完整规范请参阅 SCENARIO_FORMAT.md。

关键设计决策
  1. 隔离的沙箱:每一方都有自己的 HOME、TMPDIR、PATH。两次运行之间以及与宿主环境之间都不会发生冲突。

  2. JSON 语义比较:比较 stdout 时,如果可能,会将两侧内容解析为 JSON,并忽略键的顺序。如果不是 JSON,则回退到精确文本比较。

  3. 桩二进制文件模式:提供可将参数和环境变量捕获到文件中的伪二进制文件,以此测试启动器行为,然后比较这些文件。

  4. 超时韧性:超时时捕获部分输出(退出码 124),而不是导致工具崩溃。这对于测试可能在沙箱环境中挂起的命令至关重要。

  5. Shadow 模式:将差异记录到只追加的 JSONL 文件中,不会导致运行失败。在推出期间使用此模式监控真实工作负载。

  6. 审计分类:根据关键词推断对差异进行分组,并生成按优先级排序的修复工作流规范。

自我改进循环模式
┌─────────────┐
│  IDENTIFY   │  Run all scenarios, collect divergences
└──────┬──────┘
       ▼
┌─────────────┐
│ CATEGORIZE  │  Group by area: install (5), launch (3), recipe (1)
└──────┬──────┘
       ▼
┌─────────────┐
│  SPECIFY    │  Generate fix specs: [CRITICAL] fix-install, [HIGH] fix-launch
└──────┬──────┘
       ▼
┌─────────────┐
│    FIX      │  Agent/human fixes code
└──────┬──────┘
       ▼
┌─────────────┐
│ RE-VALIDATE │  Run audit again → check progress (5→2 divergences)
└──────┬──────┘
       ▼
    Converged? ──no──→ back to FIX
       │
      yes
       ▼
     DONE
真实世界结果

用于验证 amplihack-rs 迁移(rysweet/amplihack-rs#25):

  • 118/118 项比较测试,覆盖 12 个层级
  • 619/619 项钩子黄金文件测试
  • 9/9 项 shadow 工具案例
  • 发现并修复 5 个 Python 缺陷
  • 发现并修复 1 个配方编排器缺陷
  • 实现了完整的启动器行为匹配

更新日志 [LEVEL 3]

版本 1.2.0(2026-03-11)
  • 新增:第 4 级——A/B 对比测试框架与自我改进审计
  • 通用 ab_comparison_harness.py,适用于任意并排 CLI 对比 (迁移一致性、A/B 测试、功能标志、版本回归、金丝雀)
  • 通用 ab_audit_cycle.py 自我改进循环
  • SCENARIO_FORMAT.md YAML 规范
  • 支持 --a/--b 标志(也支持 --legacy/--candidate,以兼容旧版本)
  • 示例场景文件
  • 从 amplihack-rs 一致性验证中提取(118/118 项测试)
版本 1.1.0(2026-01-29)
  • 新增:第 4 级——影子环境集成
  • 添加了完整的影子测试工作流模式
  • 提供 Amplifier 原生版和独立 CLI 的集成示例
  • 多仓库集成测试模式
  • 影子环境中的 Web 应用测试
  • 用于验证库变更的完整工作流示例
  • 提供影子测试技能的参考链接,便于深入了解相关文档
版本 1.0.0(2025-11-16)
  • 初始技能版本
  • 支持 CLI、TUI、Web 和 Electron 应用
  • 15 个完整可运行示例
  • 渐进式披露级别(1、2、3)
  • 内嵌 gadugi-agentic-test 框架文档(v0.1.0)
  • 用于版本监控的新鲜度检查脚本
  • 与 amplihack 理念全面集成
  • 全面的故障排除指南
  • 操作参考目录

请牢记:从外向内的测试可验证应用的行为,而非实现方式。专注于用户可见的行为,测试便能在重构后保持稳定,同时有效验证关键工作流。

从第 1 级的简单冒烟测试开始,仅在需要时逐步增加复杂度。框架中的 AI Agent 会处理困难部分——你只需描述预期行为。

评论

支持 Markdown