npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vitest-environment-mp-auto

v2.0.0

Published

Vitest 自定义环境,将 mp-auto + Midscene AndroidAgent 集成到 Vitest 生命周期中。

Readme

vitest-environment-mp-auto

Vitest 自定义环境,将 mp-auto + Midscene AndroidAgent 集成到 Vitest 生命周期中。

  • globalSetup 全局只执行一次 mp-auto start,等待小程序 WS 连接就绪后才开始跑用例
  • environment 创建并复用 AndroidAgent,连同 mp-auto HTTP 辅助函数一起注入到全局变量
  • 第一版强制串行(maxWorkers: 1),因为安卓设备和微信只有一个

安装

npm install vitest-environment-mp-auto --save-dev

前置:需要全局可用的 mp-auto CLI(通过 @tencent/mp-auto 安装)和已连接的 Android 设备。

配置

vitest.config.ts

import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    // 使用 mp-auto 环境(自动解析 vitest-environment-mp-auto 包)
    environment: 'mp-auto',
    // globalSetup 确保 mp-auto daemon 就绪
    globalSetup: 'vitest-environment-mp-auto/global-setup',
    // 必须开启:environment 拦截 describe/it/expect 并自动 recordToReport
    globals: true,

    // 测试树注入:跑完后在 midscene html 左侧注入 pass/fail/skip 树
    reporters: ['default', 'html', 'vitest-environment-mp-auto/reporter'],

    // 串行执行(单设备限制)
    fileParallelism: false,
    pool: 'forks',
    isolate: false,
    maxWorkers: 1,

    // UI 自动化需要较长超时
    hookTimeout: 120_000,
    testTimeout: 120_000,

    // 传递给 environment + globalSetup 的配置
    environmentOptions: {
      mpAuto: {
        projectPath: '/path/to/miniprogram', // 小程序项目路径(传给 mp-auto start)
        port: 9400,           // mp-auto daemon 端口,默认 9400
        // serial: 'xxx',     // 指定 Android 设备序列号(多设备时)
        // contextPath: './', // .context/ 所在路径(默认 cwd)
      },
    },
  },
});

环境变量(兼容回退)

推荐通过 environmentOptions.mpAuto 配置所有参数。环境变量仅作为兼容回退:

| 变量 | 对应配置项 | 说明 | | --- | --- | --- | | MP_AUTO_PROJECT_PATH | mpAuto.projectPath | 小程序项目路径 | | MP_AUTO_PORT | mpAuto.port | daemon 端口(默认 9400) | | MP_AUTO_CONTEXT_PATH | mpAuto.contextPath | .context/ 所在路径 | | ANDROID_SERIAL | mpAuto.serial | Android 设备序列号 |

优先级:environmentOptions.mpAuto.* > 环境变量 > 默认值。

如果 mp-auto 已经在运行且有小程序客户端连接,globalSetup 会跳过启动,无需设置项目路径。

类型支持

v1.1.0 起全局类型已合并进主入口,零配置即可获得 agentdescribeitexpect 以及所有 mp-auto helper 的类型提示。

只要项目 tsconfig.json 能解析到 vitest-environment-mp-auto(默认都能),主入口 dist/index.d.ts/// <reference path="./globals.d.ts" /> 会自动把全局声明带入项目。

通常这一条就够了——它在 vitest.config.ts 里本来就需要:

import 'vitest-environment-mp-auto';   // 或直接使用 environment: 'mp-auto'

如果你关闭了 includes/types 的默认值、或者使用 "types": [...] 白名单限制了类型加载,需要显式补一条:

{
  "compilerOptions": {
    "types": ["vitest-environment-mp-auto"]
  }
}

兜底方案(适用于极端定制的 tsconfig)—— 在任意一个 .d.ts 文件(如 vitest-env.d.ts)或测试文件顶部加三斜线引用:

/// <reference types="vitest-environment-mp-auto" />

⚠️ 不要再用 vitest-environment-mp-auto/types/global,该路径仅为兼容旧版本保留,将来会移除。

全局 API

environment 注入以下全局变量,测试文件中无需任何 import,直接使用。

配合 globals: true,vitest API(describe/it/expect/beforeEach/afterEach 等)也会被 environment 自动拦截并包裹 agent.recordToReport(),生成 Midscene HTML 报告。

agent

AndroidAgent 实例(来自 @midscene/android),全进程共享,提供 Midscene UI 自动化能力:

await agent.aiTap('提交按钮');
await agent.aiAssert('显示成功提示');
await agent.aiWaitFor('页面加载完成', { timeoutMs: 15_000 });
await agent.aiInput('搜索框', { value: 'hello' });
const title = await agent.aiQuery('string, 页面标题文字');

mp-auto 辅助函数(自动 recordToReport)

| 函数 | 说明 | | --- | --- | | clearMocks() | 清除所有 mock 规则 | | clearRequests() | 清除已录制的请求 | | relaunch(url) | wx.reLaunch 到指定页面 | | navigate(url) | wx.navigateTo 到指定页面 | | mockRequest(url, response, opts?) | 添加单条 mock 规则 | | mockRequests(rules) | 批量添加 mock 规则 | | getRequests(urlFilter?) | 查询已录制的请求 | | setupPage(pageUrl, pageId, scenarioId) | 加载页面场景 mock + 导航(一步到位) | | loadPageScenario(pageId, scenarioId) | 加载页面场景的结构化 mock | | loadMock(...args) | 从 .context/business/mocks/ 加载响应变体 | | setContextPath(path) | 设置 .context/ 所在的仓库路径 |

测试文件示例

describe('首页', () => {
  beforeEach(async () => {
    await clearMocks();
    await clearRequests();
  });

  it('TC-IDX-001: 页面正常加载', async () => {
    await setupPage('/pages/index', 'module/index', 'S1');
    await agent.aiAssert('页面标题显示"首页"');
    await agent.aiAssert('底部导航栏可见');
  });

  it('TC-IDX-002: 点击提交后显示成功', async () => {
    await setupPage('/pages/index', 'module/index', 'S1');
    await agent.aiTap('提交按钮');
    await agent.aiAssert('显示"提交成功"提示');
    const reqs = await getRequests('/api/submit');
    expect(reqs).toHaveLength(1);
  });

  it('TC-IDX-030: [Mock] 接口异常时显示错误提示', async () => {
    await mockRequest('/api/data', { code: -1, msg: '系统维护中' });
    await relaunch('/pages/index');
    await agent.aiAssert('"系统维护中"提示文字可见');
  });
});

工作原理

vitest run
  │
  ├── globalSetup.setup()
  │     ├── fetch /api/status → 检查 mp-auto 是否已就绪
  │     ├── 未就绪 → execSync("mp-auto start <projectPath>")
  │     │     └── daemon 启动 → 注入 bridge → 预览二维码 → ADB 扫码 → WS 连接
  │     └── 就绪确认 (clients > 0)
  │
  ├── environment.setup()    ← 每个测试文件执行前
  │     ├── 创建 AndroidAgent(首次)或复用已有实例
  │     ├── 注入 global.agent + 辅助函数
  │     └── 拦截 describe/it/expect:describe/it 不再截图;
  │         expect 只在失败时截图并附带 describe→it 路径 + 错误摘要
  │
  ├── [串行执行所有测试文件]
  │     └── 每个 it 启动时记录 executions 索引,后面写入 bridge.json
  │
  ├── environment.teardown() ← 最后一个文件结束后
  │     ├── drainPendingRecords + agent.destroy()(finalize html)
  │     └── 写 midscene_run/.vitest-mp-auto/bridge.json
  │         { reportFile, caseAnchors, totalExecutions }
  │
  ├── reporter.onTestRunEnd()  ← 主进程
  │     └── 读 bridge.json → 把 pass/fail/skip 树 + 客户端 bootstrap
  │         脚本注入到 midscene html 的 </html> 之前
  │
  └── globalSetup.teardown()
        └── (daemon 保持运行,不自动 stop)

测试树面板(reporter)

配置 reporters: ['default', 'html', 'vitest-environment-mp-auto/reporter'] 后,vitest 跑完后 midscene html 左侧会多出一个折叠面板:

  • 顶部统计 N tests · X pass · Y fail · Z skip · 总耗时
  • file → describe → it 层级渲染,每级聚合 PASS/FAIL/SKIP
  • 工具栏按钮: 全部折叠、+ 全部展开、! 只显示失败用例
  • 点击某个用例:滚动到右侧 Execution 步骤区该用例的第一步并高亮
  • 失败用例右侧有 error 按钮,点击展开完整错误栈

注入是幂等的:同一个 html 再次打开 reporter 时会替换旧的注入块(使用 <!--VITEST_MP_TREE_BEGIN--> 哨兵)。

本地开发

改完源码后重新构建并在消费仓库里刷新:

# 在本包目录
pnpm build

# 在消费仓库(例如 apps/points)
pnpm install --force  # 或者 pnpm update vitest-environment-mp-auto

如果用 pnpm link 到本地:

# 在本包目录
pnpm build && pnpm link --global

# 在消费仓库
pnpm link --global vitest-environment-mp-auto