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

Playwright API Fixture在beforeEach钩子中超时问题排查求助

Playwright Fixture 在 beforeEach 调用时超时问题解决

问题背景

想用Playwright的fixture封装复用的API数据初始化逻辑,避免测试用例重复编写相同代码。同一个POST请求在测试用例内运行正常,但放到beforeEach钩子中调用fixture时,请求返回200状态码,却触发钩子执行超时(请求耗时不到1秒,已设置60秒超时),怀疑fixture的return部分存在问题。

原Fixture文件

const base = require('@playwright/test');
const randomFigures = Math.random().toString();

const randomAssetNumber = 'Asset' + randomFigures.substr(0, 8).toString()

// Extend base test by providing "postTruck".
// This new "test" can be used in multiple test files, and each of them will get the fixtures.
exports.test = base.test.extend({
    postTruck: async ({request}, use) => {
        return await request.post('https://myFullUrl.com/api/Truck', {
            headers: {'Authorization': 'ApiKey my-api-key'},
            data: {
                "ClientId": 1234,
                "AssetNumber": randomAssetNumber
            },
        })

    },

});
exports.expect = base.expect;

原测试用例文件

const { test, expect } = require('../custom-commands/customFixtures');

test.beforeEach(async ({ request, postTruck }) => {
    const response = await postTruck(request);
    expect(response.status()).toBe(200);
});

test('basic test to see that beforeEach is used', async ({ page, baseURL }) => {
    console.log('my test is being run after beforeEach hook')
    await page.goto('/')
    await expect(page).toHaveURL(baseURL + '/Login.aspx')
})

错误原因

  1. Fixture生命周期错误:Playwright的fixture必须通过use()函数传递值,直接返回请求结果会导致测试框架无法感知fixture已完成执行,从而触发超时。
  2. 调用方式错误:测试文件中手动传递request参数给postTruck是多余的,fixture已经自动注入了request实例。
  3. 测试隔离问题:randomAssetNumber定义在fixture外部,所有测试用例会复用同一个值,违反测试独立性原则。

修正后的代码

修正后的Fixture文件

const base = require('@playwright/test');

exports.test = base.test.extend({
    postTruck: async ({ request }, use) => {
        // 每个测试用例生成独立的随机资产编号
        const randomFigures = Math.random().toString();
        const randomAssetNumber = 'Asset' + randomFigures.substr(0, 8);
        
        // 执行POST请求
        const response = await request.post('https://myFullUrl.com/api/Truck', {
            headers: {'Authorization': 'ApiKey my-api-key'},
            data: {
                "ClientId": 1234,
                "AssetNumber": randomAssetNumber
            },
        });
        
        // 通过use()传递响应对象,告知框架fixture执行完成
        await use(response);
    },
});
exports.expect = base.expect;

修正后的测试用例文件

const { test, expect } = require('../custom-commands/customFixtures');

test.beforeEach(async ({ postTruck }) => {
    // 直接使用注入的postTruck fixture,无需额外传参
    expect(postTruck.status()).toBe(200);
});

test('basic test to see that beforeEach is used', async ({ page, baseURL }) => {
    console.log('my test is being run after beforeEach hook')
    await page.goto('/')
    await expect(page).toHaveURL(baseURL + '/Login.aspx')
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 15:21:13