generator 通过 yield 返回标准化校验任务,实现断言链的延迟构建与流式执行;运行器遍历并 await 每步,天然支持异步等待、重试、条件跳过与错误聚合。

Generator 可以让断言逻辑具备“暂停-恢复”能力,天然适配多步异步校验场景。在自动化测试中,它不直接执行断言,而是生成可组合、可延迟求值的校验步骤序列,配合自定义运行器实现流式断言链(如 expect(...).toBeVisible().toHaveText("Submit") 的底层驱动机制)。
用 Generator 构建可中断的断言步骤流
每个断言方法(如 toBeVisible、toHaveAttribute)返回一个 Generator 函数,产出校验动作描述(含目标元素、预期值、重试策略等),而非立即执行。这样整个链式调用只构建计划,不触发真实操作。
- Generator 每次
yield返回一个标准化校验任务对象,例如{ type: 'visible', target: el, timeout: 5000 } - 调用方(如测试运行器)统一遍历 Generator,按需执行每个任务,并支持失败时中断、重试或收集上下文
- 避免嵌套 Promise 或手动管理状态机,逻辑更线性、调试更直观
与异步等待和重试机制自然结合
Generator 的 next() 可在 await 后恢复,正好匹配 UI 测试中常见的“等待元素出现 → 校验属性 → 等待文本变更”这类依赖时序的流程。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 在运行器中用
for await (const step of assertionChain())驱动每一步,每步内部可自由 await - 对超时步骤,可在 yield 前注入重试逻辑(如封装
waitFor工具函数),Generator 本身不感知异步,专注描述“做什么” - 示例:一个
toHaveText("Save")步骤可 yield 多次(检查 textContent、innerText、甚至轮询 DOM),直到满足或超时
支持断言链的动态组装与条件跳过
Generator 函数可接收上下文参数(如上一步结果、环境标志),决定是否 yield 某个校验步骤,实现运行时分支。
- 例如:当页面处于编辑模式时才校验“删除按钮存在”,否则跳过该 step —— 直接在 Generator 内部用
if (mode === 'edit') yield { type: 'exists', selector: '#delete-btn' } - 多个断言链可通过
function* compose(...generators) { for (const g of generators) yield* g() }合并,便于复用公共校验模板 - 错误信息可随每步 yield 携带
message字段,运行器统一收集,生成清晰的失败报告
实际集成示意(精简版)
以下是一个最小可行结构,展示 Generator 如何支撑流式断言:
// 断言构造器(返回 Generator)
function expect(el) {
return {
toBeVisible() {
return function* () {
yield { type: 'wait', predicate: () => el?.offsetParent !== null, timeout: 3000 };
yield { type: 'assert', check: () => el?.offsetParent !== null, message: 'element not visible' };
};
},
toHaveText(text) {
return function* () {
yield { type: 'wait', predicate: () => el?.textContent?.includes(text), timeout: 2000 };
yield { type: 'assert', check: () => el?.textContent?.includes(text), message: `expected text "${text}"` };
};
}
};
}
<p>// 运行器(消费 Generator)
async function runAssertions(genFn) {
const gen = genFn();
for (const step of gen) {
switch (step.type) {
case 'wait':
await waitFor(step.predicate, step.timeout);
break;
case 'assert':
if (!step.check()) throw new Error(step.message);
break;
}
}
}</p><p>// 测试中使用
await runAssertions(() => {
const el = document.querySelector('#submit');
return function<em> () {
yield</em> expect(el).toBeVisible()();
yield* expect(el).toHaveText('Submit')();
}();
});</p>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










