根本的问题是Playwright运行了两次测试代码.第一次是同步的,大概是用来检测test()
个调用的数量.第二遍实际上执行测试.在测试文件的顶层记录某些内容显示了这两个步骤的过程.
不幸的是,目前还没有在初始测试检测步骤中在顶层使用异步代码的明显方法.
这是有效的:
import {test} from "@playwright/test"; // ^1.42.1
(async () => {
for (const name of ["a", "b", "c"]) {
test(`testing with ${name}`, async () => {
// ...
});
}
})();
但这并不能检测到测试
import {setTimeout} from "node:timers/promises";
import {test} from "@playwright/test";
(async () => {
await setTimeout(0); // actually do something async
for (const name of ["a", "b", "c"]) {
test(`testing with ${name}`, async () => {
// ...
});
}
})();
此外,before
个钩子不是测试发现过程的一部分.以下代码
import {test} from "@playwright/test";
console.log("TEST SUITE");
test.beforeAll(() => console.log("BEFORE"));
for (const name of ["a", "b", "c"]) {
test(`testing with ${name}`, async () => {
// ...
});
}
输出:
$ npx playwright test
TEST SUITE
Running 3 tests using 1 worker
TEST SUITE
✓ 1 pw.test.js:7:7 › testing with a (5ms)
BEFORE
✓ 2 pw.test.js:7:7 › testing with b (4ms)
✓ 3 pw.test.js:7:7 › testing with c (2ms)
3 passed (270ms)
根据this comment,一种解决方法是使用test.step()
:
import {test} from "@playwright/test";
let people = [];
test.beforeAll(async ({request}) => {
const url = "https://jsonplaceholder.typicode.com/users";
const response = await request.get(url);
people = (await response.json()).map(e => e.name);
});
test("test", async () => {
for (const name of people) {
await test.step(`testing with ${name}`, async () => {
// ...
});
}
});
问题是输出缺少测试用例名称:
$ npx playwright test
Running 1 test using 1 worker
✓ 1 pw.test.js:11:5 › test (8ms)
1 passed (407ms)
另一种解决方法是在运行测试之前在单独的脚本中生成数据,将其存储在一个文件中,并在测试开始时同步读取该文件.例如:
generate-people-data.js:
const fs = require("node:fs/promises");
(async () => {
const url = "https://jsonplaceholder.typicode.com/users";
const response = await fetch(url);
const people = (await response.json()).map(e => e.name);
await fs.writeFile("people.json", JSON.stringify(people));
})();
people.test.js:
import fs from "node:fs";
import {test} from "@playwright/test";
const json = fs.readFileSync("people.json", {encoding: "utf-8"});
const people = JSON.parse(json);
for (const name of people) {
test(`testing with ${name}`, async () => {
// ...
});
}
运行:
$ node generate-people-data && npx playwright test
Running 10 tests using 1 worker
✓ 1 pw.test.js:7:7 › testing with Leanne Graham (9ms)
✓ 2 pw.test.js:7:7 › testing with Ervin Howell (4ms)
✓ 3 pw.test.js:7:7 › testing with Clementine Bauch (1ms)
✓ 4 pw.test.js:7:7 › testing with Patricia Lebsack (1ms)
✓ 5 pw.test.js:7:7 › testing with Chelsey Dietrich (1ms)
✓ 6 pw.test.js:7:7 › testing with Mrs. Dennis Schulist (1ms)
✓ 7 pw.test.js:7:7 › testing with Kurtis Weissnat (1ms)
✓ 8 pw.test.js:7:7 › testing with Nicholas Runolfsdottir V (1ms)
✓ 9 pw.test.js:7:7 › testing with Glenna Reichert (1ms)
✓ 10 pw.test.js:7:7 › testing with Clementina DuBuque (3ms)
10 passed (253ms)
如果您不喜欢&&
,您可以运行npx playwright test
作为生成器脚本的最后一步.
另一个选项是来自另一个线程的synchronous fetch approach.
也许在当前版本中有一种更优雅的方法,或者Playwright的future 版本将支持Esclc测试检测.