You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Playwright中Flaky Test的超时及不稳定问题?

解决Playwright测试超时/不稳定问题的方案

问题背景

测试应用时,提交表单后需40秒以上加载数据且刷新整个应用,已尝试调整超时、串行执行等措施,但仍出现waitForSelector超时或测试不稳定的情况,当前使用focus+Enter替代click操作。

具体优化方案

1. 修复错误的断言写法

原代码中的断言逻辑有误,Playwright断言需使用其内置方法,而非直接调用toBeDefined()。正确写法应针对元素的存在性/可见性做断言,同时可单独设置超时:

// 替换原断言代码
await expect(page.locator('.eid')).toBeAttached({ timeout: 120000 });
// 若元素需要可见,改用以下断言
// await expect(page.locator('.eid')).toBeVisible({ timeout: 120000 });

注:waitForSelector和断言可结合使用,双重保障元素状态稳定。

2. 等待页面导航/刷新完成

因为提交操作会触发整个应用刷新,需先等待页面导航完成,避免竞态条件。使用Promise.all同时执行提交和等待导航:

await page.goto(url);
await page.locator('.txtname').fill(namehere);
await page.focus('.btnsubmit');

// 并行执行回车操作和等待导航
await Promise.all([
  page.waitForNavigation({ 
    waitUntil: 'networkidle', // 等待网络空闲(无请求超过500ms)
    timeout: 120000 // 设置120秒超时,覆盖长加载场景
  }),
  page.keyboard.press('Enter')
]);

// 导航完成后再等待目标元素
await page.waitForSelector('.eid', { timeout: 120000 });
await expect(page.locator('.eid')).toBeAttached();

3. 替换为更稳定的元素定位器

类名.eid可能因前端样式变更或重复使用导致定位不稳定,建议使用data-testid属性(需前端配合添加),这是UI测试的最佳实践:

// 前端元素添加data-testid属性
// <div class="eid" data-testid="table-row-eid"></div>

// 测试代码中使用该定位器
await page.waitForSelector('[data-testid="table-row-eid"]', { timeout: 120000 });
await expect(page.locator('[data-testid="table-row-eid"]')).toBeAttached();

4. 增加加载状态的等待

如果页面有加载动画/提示,先等待加载状态消失,再等待目标元素,确保数据完全加载:

// 先等待加载 spinner 消失(假设加载元素类名为.loading)
await page.waitForSelector('.loading', { state: 'hidden', timeout: 120000 });
// 再等待目标元素出现
await page.waitForSelector('.eid', { timeout: 120000 });

5. 给不稳定测试添加重试机制

针对偶尔失败的测试,可在测试用例级别添加重试,让失败的测试自动重新执行:

// 单个测试用例重试2次
test('测试表格数据加载', async ({ page }) => {
  // 测试代码逻辑
}).retry(2);

// 或给整个测试套件的用例都添加重试
test.describe('表格测试套件', () => {
  test.use({ retries: 2 });
  
  test('用例1', async ({ page }) => { /* ... */ });
  test('用例2', async ({ page }) => { /* ... */ });
});

6. 调整Playwright全局超时配置(可选)

如果多个测试都需要长超时,可在playwright.config.js中全局调整,避免每个地方单独设置:

module.exports = {
  use: {
    timeout: 120000, // 全局操作超时120秒
    navigationTimeout: 120000, // 导航超时120秒
  },
};

内容的提问来源于stack exchange,提问作者Chukchak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 12:53:22