跳到主要内容
QZ Site
首页写作项目关于

© 2026 QZ Site. All rights reserved.

豫ICP备2026034998号-1|琼公网安备46020002000486号

← 返回写作

IME 自动化测试开源方案

测试自动化·2026年7月27日·12 分钟阅读

IME 自动化测试方案总结

现状:IME 测试自动化是个业界难题

观点

核心困难在于:浏览器自动化工具(Playwright/Puppeteer)运行在浏览器外部,而 IME 是操作系统级别的服务。自动化工具无法直接调用操作系统的输入法,因为:

  1. Headless 模式下没有操作系统 IME 可用
  2. 即使有 GUI 环境,程序化控制 IME 候选词选择非常困难
  3. CDP 除 Input.insertText 外,也提供实验性的 Input.imeSetComposition 接口,可设置组合输入,传入空字符串可取消组合。具体支持情况要按目标浏览器和协议版本核对。这仍不等于自动操作系统输入法的候选词窗口,也不能据此宣称已经覆盖真实输入法的完整交互。

现有开源方案

方案说明适用范围与限制
Adobe IMPACTAdobe 开源的 IME 自动化框架,专为 CJK 输入测试设计,通过 Python + Selenium 控制系统级 IME最接近需求,但依赖 GUI 环境和系统 IME
puppeteer-text-typer通过手动构造 CompositionEvent 并注入页面来模拟 IME 组合过程轻量,但不触发浏览器真实的 IME 状态
Playwright keyboard.insertText()内置方法,直接插入文本(跳过组合过程)只能测最终结果,无法测组合中间状态
Playwright pressSequentially()逐字符按键,触发 keydown/keyup 事件不触发 composition 事件,无法模拟 IME

两种验证层次:事件处理与真实输入法

策略1:页面事件处理测试(轻量,不需要真实 IME) 手动构造 CompositionEvent 可检查页面是否依据 compositionstart/compositionend 维护组合状态,但不会启动真实输入法。下面的教学用例会等待完整防抖窗口,确认组合期间未跳转;结束时显式设置中文值并断言 URL 参数等于“啊”。fill() 不保证生成 isComposing=true 的 InputEvent,compositionend.data 也不会自动修改输入值。运行前须按目标页面配置地址、选择器、搜索参数及防抖时长;这不是本站或真实操作系统输入法已经通过的测试记录。

typescript
import { test, expect } from '@playwright/test';

// 教学用例:页面事件处理测试,不是真实操作系统 IME 测试。
// 按被测页面调整这三个配置;此处不是本站实测记录。
const PAGE_URL = 'http://localhost:3000/blog';
const SEARCH_PARAM = 'search';
const DEBOUNCE_MS = 300; // 必须与应用实际搜索防抖时间一致

test('组合期间不搜索,结束后提交最终中文', async ({ page }) => {
  await page.goto(PAGE_URL);
  const input = page.locator('input[placeholder*="搜索"]');
  const initialURL = page.url();
  await input.evaluate(el => {
    el.dispatchEvent(new CompositionEvent('compositionstart', { bubbles: true }));
  });

  // fill 本身不保证生成 isComposing=true 的 InputEvent。
  // 本例检查应用是否依据 compositionstart/end 维护组合状态。
  await input.fill('a');
  // 故意覆盖一个完整防抖窗口,不能只在 fill 后立即断言。
  await page.waitForTimeout(DEBOUNCE_MS + 100);
  await expect(page).toHaveURL(initialURL);

  // compositionend.data 不会替我们修改 input.value。
  await input.fill('啊');
  await expect(input).toHaveValue('啊');
  await input.evaluate(el => {
    el.dispatchEvent(new CompositionEvent('compositionend', {
      bubbles: true,
      data: '啊',
    }));
  });
  // 检查最终值,不只检查是否出现参数;poll 等待应用防抖提交。
  await expect.poll(
    () => new URL(page.url()).searchParams.get(SEARCH_PARAM),
    { timeout: Math.max(5000, DEBOUNCE_MS + 1000) },
  ).toBe('啊');
});

策略2:Adobe IMPACT(重量级,需要 GUI 环境) 如果你需要测试真实 IME 的完整行为(包括候选词窗口、多步选择等),IMPACT 是目前最专业的方案。但它需要:

  • Windows/macOS GUI 环境(不能 headless)

  • 安装对应语言的系统 IME

  • Python + Selenium 环境

 

注意

对个人网站,可以先用事件注入测试检查页面是否正确处理组合输入事件,但它不能代替操作系统输入法的端到端验证:

  1. 事件注入适合检查组合输入期间是否误触发搜索或跳转,可放进 CI。
  2. 最终仍应在目标浏览器和真实输入法中检查候选词选择、确认、取消与焦点切换。
  3. 本文的方案介绍与示例,不等于这些环境已经全部验证通过。参考资料见下方链接。
  • Adobe IMPACT - IME Automation for CJK

  • puppeteer-text-typer

  • Puppeteer Feature Request: Composition Events

  • Playwright keyboard.insertText 文档

最近更新

Agent Engineering · 文章

Prompt Engineering:我会怎样把任务交给模型

沿着做事的顺序理解 Prompt Engineering:先把任务说明白,遇到复杂问题再组织处理过程,最后按需要检查结果。用十种常见方法和具体示例,讨论它们分别解决什么问题、怎样组合,以及什么时候不需要增加复杂流程。

2026年11月5日·23 分钟阅读

Agent Engineering

从 Prompt 到 Harness:我对 Agent 工程的理解

刚开始使用大模型时,我最关心的是:怎么把话说清楚,让模型给出更好的回答? 后来,我开始做 Agent,发现问题逐渐变了。模型不只是回答问题,它还要读取文件、调用工具、处理结果,甚至跨越多轮对话和多次运行,持续完成一项任务。 这时候,光把提示词写好已经不够了。我还需要考虑:模型每一步能看到什么?工具出了问题怎么办?

2026年11月5日·14 分钟阅读

学习流程

为了一个中文 hover,我和 AI 绕了一大圈

最近,我在读一个 Python Agent 项目的源码。 鼠标放到 argparse、ArgumentParser 这些名字上,编辑器会弹出一大段英文说明。这个悬停提示通常叫 hover,本来是帮助理解代码的,但对我当时的学习阶段来说,它又增加了一层障碍:我得先理解英文,再理解 API,最后才能回到眼前这段代码。

2026年11月1日·16 分钟阅读

目录

  • IME 自动化测试方案总结
  • 现状:IME 测试自动化是个业界难题
  • 现有开源方案
  • 两种验证层次:事件处理与真实输入法
← 较早发布和 Coding Agent 协作:把问题说清楚,把事情做完整
较晚发布 →03-asyncio 与并发模型盲区梳理