在尝试使用Playwright中的参数化测试时遇到了一些问题。

huangapple go评论151阅读模式
英文:

Have some issues when trying to use parametrize test in Playwright

问题

这是我的代码

const { test, expect } = require('@playwright/test')
const { generateRandomUser } = require('../helpers')

const firstUser = generateRandomUser();
const secondUser = generateRandomUser();
const users = [firstUser, secondUser];

// 参数化测试
users.forEach(user => {
  console.log('USER', user);
  const { username, email, password } = user;
  test(`应注册 ${username}`, async ({ page }) => {
    await page.goto('https://conduit.mate.academy/user/register');

    await page.getByPlaceholder('Username').fill(username);
    await page.getByPlaceholder('Email').fill(email);
    await page.getByPlaceholder('Password').fill(password);
    await page.getByRole('button', { name: 'Sign up' }).click();

    await expect(page.locator(`a.nav-link[href='/profile/${username}']`)).toBeVisible();

    await page.pause();
  });
});

这是generateRandomUser函数

const { faker } = require('@faker-js/faker');

exports.generateRandomUser = () => {
  const random = Math.random().toString().slice(2, 6);
  let username = faker.lorem.word() + '_' + random;
  username = username.toLowerCase()
  const email = username + '@gmail.com';
  const password = faker.internet.password();

  return {
    username,
    email,
    password
  }
}

所以,基本上我只想深入了解Playwright,并决定尝试参数化测试,但当我运行它们时,我收到以下错误消息:

Internal error: unknown test(s) in worker:
chromium > exploring_playwright.spec.js > should register officiis_0247

2 failed
[chromium] › exploring_playwright.spec.js:12:3 › should register beatae_1183 ───────────────────
[chromium] › exploring_playwright.spec.js:12:3 › should register officiis_0247 ─────────────────

而且,当我使用console.log()来查看用户是否正确生成时,我可以在控制台中看到超过2个用户的输出,这很奇怪,我猜这就是失败的原因,但我不知道如何可能发生这种情况。我在以前的测试中以及注册页面中都使用了generateRandomUser()函数,就像这里一样,一切都正常工作。

const { test, expect } = require('@playwright/test')
const { generateRandomUser, registerNewUser } = require('../../helpers')

test.beforeEach(async ({ page }) => {
  await page.goto('https://conduit.mate.academy/user/register');
})

test('应注册一个新用户', async ({ page }) => {
  const { username, email, password } = generateRandomUser();

  await page.getByPlaceholder('Username').fill(username);
  await page.getByPlaceholder('Email').fill(email);
  await page.getByPlaceholder('Password').fill(password);
  await page.getByRole('button', { name: 'Sign up' }).click();

  await expect(page.locator(`a.nav-link[href='/profile/${username}']`)).toBeVisible();
})

我尝试使用YouTube视频和文档等资源。这是参考资料(图片)这个 和这个

我向ChatGPT询问,尝试添加描述块,尝试使用test.describe.parallel,但没有什么用。

这个选项也是不正确的

for (let i = 0; i < 2; ++i) {
  const { username, email, password } = generateRandomUser();
  console.log(username, email, password)

  test(`应注册 ${username}`, async ({ page }) => {
    await page.goto('https://conduit.mate.academy/user/register');

    await page.getByPlaceholder('Username').fill(username);
    await page.getByPlaceholder('Email').fill(email);
    await page.getByPlaceholder('Password').fill(password);
    await page.getByRole('button', { name: 'Sign up' }).click();

    await expect(page.locator(`a.nav-link[href='/profile/${username}']`)).toBeVisible();

    await page.pause();
  });
}

我仍然看到创建了6个用户,而不是2个。

英文:

Here is my code

const {test, expect} = require(&#39;@playwright/test&#39;)
const { generateRandomUser } = require(&#39;../helpers&#39;)

const firstUser = generateRandomUser();
const secondUser = generateRandomUser();
const users = [firstUser, secondUser];

// parametrized test
users.forEach(user =&gt; {
  console.log(&#39;USER&#39;, user);
  const { username, email, password } = user;
  test(`should register ${username}`, async ({ page }) =&gt; {
    await page.goto(&#39;https://conduit.mate.academy/user/register&#39;);

    await page.getByPlaceholder(&#39;Username&#39;).fill(username);
    await page.getByPlaceholder(&#39;Email&#39;).fill(email);
    await page.getByPlaceholder(&#39;Password&#39;).fill(password);
    await page.getByRole(&#39;button&#39;, { name: &#39;Sign up&#39; }).click();

    await expect(page.locator(`a.nav-link[href=&#39;/profile/${username}&#39;]`)).toBeVisible();

    await page.pause();
  });
});

Here is the generateRandomUser function

const { faker } = require(&#39;@faker-js/faker&#39;);

exports.generateRandomUser = () =&gt; {
  const random = Math.random().toString().slice(2, 6);
  let username = faker.lorem.word() + &#39;_&#39; + random;
  username = username.toLowerCase()
  const email = username + &#39;@gmail.com&#39;;
  const password = faker.internet.password();

  return {
    username,
    email,
    password
  }
}

So, basically I just want to have a good grasp of Playwright and just decided to try parametrize test, but when I run them I get this error

Internal error: unknown test(s) in worker:
chromium &gt; exploring_playwright.spec.js &gt; should register officiis_0247

2 failed
[chromium] › exploring_playwright.spec.js:12:3 › should register beatae_1183 ───────────────────
[chromium] › exploring_playwright.spec.js:12:3 › should register officiis_0247 ─────────────────

And moreover, when I use console.log() to see if the user was generated right I can see that in my console more than 2 outputs of users, which is strange, I guess this is the reason it fails but I have no idea how is it possible. I used this generateRandomUser() function for the previous tests and also for the Sign Up Page, like here and everything works fine.

const {test, expect} = require(&#39;@playwright/test&#39;)
const { generateRandomUser, registerNewUser } = require(&#39;../../helpers&#39;)

test.beforeEach(async ({page}) =&gt; {
  await page.goto(&#39;https://conduit.mate.academy/user/register&#39;);
})

test(&#39;should register a new user&#39;, async ({page}) =&gt; {
  const {username, email, password} = generateRandomUser();

  await page.getByPlaceholder(&#39;Username&#39;).fill(username);
  await page.getByPlaceholder(&#39;Email&#39;).fill(email);
  await page.getByPlaceholder(&#39;Password&#39;).fill(password);
  await page.getByRole(&#39;button&#39;, { name: &#39;Sign up&#39; }).click();

  await expect(page.locator(`a.nav-link[href=&#39;/profile/${username}&#39;]`)).toBeVisible();
})

I tried to use resources like Youtube videos and documentation. Here is the references (photos) this one and this one

I asked ChatGPT, tried to add describe block, tried to use test.describe.parallel, but it didn't do much.

This option is also incorrect

for(let i = 0; i &lt; 2; ++i) {
  const {username, email, password} = generateRandomUser();
  console.log(username, email, password)

  test(`should register ${username}`, async ({ page }) =&gt; {
    await page.goto(&#39;https://conduit.mate.academy/user/register&#39;);

    await page.getByPlaceholder(&#39;Username&#39;).fill(username);
    await page.getByPlaceholder(&#39;Email&#39;).fill(email);
    await page.getByPlaceholder(&#39;Password&#39;).fill(password);
    await page.getByRole(&#39;button&#39;, { name: &#39;Sign up&#39; }).click();

    await expect(page.locator(`a.nav-link[href=&#39;/profile/${username}&#39;]`)).toBeVisible();

    await page.pause();
  });
}

I still see 6 users created instead of 2.

答案1

得分: 1

I believe you might be running the tests on several workers which cause firstUser and secondUser to be generated for each worker. If you run the test with a single worker, the test will most likely run as expected:

// playwright.config
export default defineConfig({
    workers: 1
}

Several workers

If you want to run the test on several workers, you could set a seed to persist the faker generated data, example of implementation:

import {faker} from '@faker-js/faker/locale/nb_NO'

const {test, expect} = require('@playwright/test')
const { generateRandomUser } = require('../helpers')

const firstUser = generateRandomUser(11);
const secondUser = generateRandomUser(22);
const users = [firstUser, secondUser];

// parametrized test
for(const user of users) {
  const { username, email, password, seed } = user;
  faker.seed(seed)
  test.only(`should register ${username}`, async ({ page }) => {
    // Your code
  });
};
const { faker } = require('@faker-js/faker');

exports.generateRandomUser = (seed) => {
  faker.seed(seed)
  // For the seed to work, you cannot use math.random, but faker generated number
  // const random = Math.random().toString().slice(2, 6); 

  const random = faker.number.int({ min: 100, max: 100000 })
  let username = faker.lorem.word() + '_' + random;
  username = username.toLowerCase()
  const email = username + '@gmail.com';
  const password = faker.internet.password();

  return {
    username,
    email,
    password,
    seed
  }
}
英文:

I beleive you might be running the tests on several workers which cause firstUser and secondUser to be generated for each worker. If you run the test with a single worker, the test will most likely run as expected:

// playwright.config
export default defineConfig({
    workers: 1
}

Several workers

If you want to run the test on several workers, you could set a seed to persist the faker generated data, example of implementation:

import {faker} from &#39;@faker-js/faker/locale/nb_NO&#39;

const {test, expect} = require(&#39;@playwright/test&#39;)
const { generateRandomUser } = require(&#39;../helpers&#39;)

const firstUser = generateRandomUser(11);
const secondUser = generateRandomUser(22);
const users = [firstUser, secondUser];

// parametrized test
for(const user of users) {
  const { username, email, password, seed } = user;
  faker.seed(seed)
  test.only(`should register ${username}`, async ({ page }) =&gt; {
    // Your code
  });
};
const { faker } = require(&#39;@faker-js/faker&#39;);

exports.generateRandomUser = (seed) =&gt; {
  faker.seed(seed)
  // For the seed to work, you cannot use math.random, but faker generated number
  // const random = Math.random().toString().slice(2, 6); 

  const random = faker.number.int({ min: 100, max: 100000 })
  let username = faker.lorem.word() + &#39;_&#39; + random;
  username = username.toLowerCase()
  const email = username + &#39;@gmail.com&#39;;
  const password = faker.internet.password();

  return {
    username,
    email,
    password,
    seed
  }
}

答案2

得分: 0

我尝试了你的代码,基本形式下运行正常。

const {test, expect} = require('@playwright/test')
// const { generateRandomUser } = require('../helpers')

const firstUser = "firstUser";
const secondUser = "secondUser";
const users = [firstUser, secondUser];

// 参数化测试
users.forEach(user => {
  console.log('USER', user);
  test(`应该注册 ${user}`, async ({ page }) => {
    console.log(user);
  });
});

输出:

$ npx playwright test example3.spec.ts

USER firstUser
USER secondUser

运行 2 个测试,使用 1 个工作进程

USER firstUser
USER secondUser
  ✓  1 example3.spec.ts:11:3 › 应该注册 firstUser (109ms)
firstUser
  ✓  2 example3.spec.ts:11:3 › 应该注册 secondUser (53ms)
secondUser

  2 个通过 (3.7s)

我使用的是 Playwright 版本 1.35.1。

我认为 generateRandomUser 函数没有任何等待,这个函数是异步的吗?

看起来你的问题在于用户名在调用之前没有被定义,这导致了测试失败。

英文:

I tried your code in base form and it is working fine

const {test, expect} = require(&#39;@playwright/test&#39;)
// const { generateRandomUser } = require(&#39;../helpers&#39;)

const firstUser = &quot;firstUser&quot;;
const secondUser = &quot;secondUser&quot;;
const users = [firstUser, secondUser];

// parametrized test
users.forEach(user =&gt; {
  console.log(&#39;USER&#39;, user);
  test(`should register ${user}`, async ({ page }) =&gt; {
    console.log(user);
  });
});

Output:

 $ npx playwright test example3.spec.ts

USER firstUser
USER secondUser

Running 2 tests using 1 worker

USER firstUser
USER secondUser
  ✓  1 example3.spec.ts:11:3 › should register firstUser (109ms)
firstUser
  ✓  2 example3.spec.ts:11:3 › should register secondUser (53ms)
secondUser

  2 passed (3.7s)

and I'm on Playwright version 1.35.1

I think generateRandomUser does not have any await, or is that function is async or not?

seems like your issue here is with username not getting defined till it is called which is failing the tests.

答案3

得分: 0

ForEach loop doesn't await for the promises.

使用 for-of 循环替代:

async function printFiles () {
  const files = await getFilePaths();

  for await (const file of files) {
    const contents = await fs.readFile(file, 'utf8');
    console.log(contents);
  }
}

参考链接: https://stackoverflow.com/a/37576787

英文:

> ForEach loop doesn't await for the promises.

Use for- of loop instead:

async function printFiles () {
  const files = await getFilePaths();

  for await (const file of files) {
    const contents = await fs.readFile(file, &#39;utf8&#39;);
    console.log(contents);
  }
}

Reference: https://stackoverflow.com/a/37576787

huangapple
  • 本文由 发表于 2023年7月6日 16:10:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76626772.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定