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') })
错误原因
- Fixture生命周期错误:Playwright的fixture必须通过
use()函数传递值,直接返回请求结果会导致测试框架无法感知fixture已完成执行,从而触发超时。 - 调用方式错误:测试文件中手动传递
request参数给postTruck是多余的,fixture已经自动注入了request实例。 - 测试隔离问题:
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
相关产品推荐
相关产品推荐

