Playwright文档中有一个参数示例.它的工作原理:

const people = ['Alice', 'Bob'];
for (const name of people) {
  test(`testing with ${name}`, async () => {
    // ...
  });
  // You can also do it with test.describe() or with multiple tests as long the test name is unique.
}

然而,我希望在每次测试之前获得数据数组,并生成测试循环

//data like data[] = [{name:'Alice',age:'20'},..]
let data: any[] = []; 

test.beforeEach(async ({ request }) => {
    
    data = await getData(request);
});

for (let i = 0; i < data.length; i++) {
  test(`testing with ${name}`, async (page) => {
    // ...
  });

}

在Visual Studio代码中,它显示错误:没有找到测试

但当我指定一个精确的值let data: any[] =[{name:'Alice',age:'20'}];时,它就可以工作了.

我测试类似的 case https://github.com/microsoft/playwright/issues/9916 How do I properly run individual Playwright tests from a dynamic array of built urls?

推荐答案

根本的问题是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测试检测.

Typescript相关问答推荐

如何修复VueJS中的val类型不能赋给函数

Angular 17 -如何在for循环内创建一些加载?

根据另一个属性的值来推断属性的类型

泛型函数中输入参数类型的推断问题

类型{}上不存在属性&STORE&A;-MobX&A;REACT&A;TYPE脚本

编剧错误:正在等待Expect(Locator).toBeVisible()

APIslice-CreateAPI的RTK打字错误

在Typescript 中,有没有`index=unfined的速记?未定义:某个数组[索引]`?

垫表页脚角v15

如何缩小函数的返回类型?

API文件夹内的工作员getAuth()帮助器返回:{UserID:空}

当数组类型被扩展并提供标准数组时,TypeScrip不会抱怨

作为函数参数的联合类型的键

Typescript,如何在通过属性存在过滤后重新分配类型?

是否将Angular *ngFor和*ngIf迁移到新的v17语法?

类型脚本中函数重载中的类型推断问题

如何处理可能为空的变量...我知道这不是Null?

通过函数传递确切的类型,但验证额外的字段

剧作家测试未加载本地网址

TS2532:对象可能未定义