首页 > 解决方案 > 在 Puppeteer 测试中运行 for 循环

问题描述

我正在尝试在将值发送到搜索栏的 Puppeteer 测试中运行 for 循环:

  test('test one', () => {
    var results = [""]
    var fuzz = ['apple', 'banana', 'kiwi'];
    fuzz.forEach(async function(value) {
      await page.goto('http://localhost:8080/')
      await page.$eval('#searchtext', el => el.value = value);
      await page.$eval('#searchform', form => form.submit())
      await page.waitForSelector('.results-table');
      var text = await page.evaluate(() => document.body.textContent);
      results.push(text)
    });
    expect(results).toEqual(expect.arrayContaining(['bleh']));
  });

但是,每当我运行它时,它都会返回一个空results数组,这让我认为 forEach 循环没有完成。

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining ["bleh"]
    Received: [""]

我知道 for 循环中的代码是正确的,因为我有其他测试没有循环并且做同样的事情但返回结果。任何想法如何干净/正确地做到这一点?谢谢。

标签: javascriptnode.jstestingjestjspuppeteer

解决方案


正如评论中所指出的,您无需等待异步功能完成。我假设您想要一个接一个地执行测试,因为您在所有测试中都使用相同的页面变量。在这种情况下,您将不得不使用for循环而不是forEach函数:

test('test one', async () => {
    var results = [""]
    var fuzz = ['apple', 'banana', 'kiwi'];
    for (var value of fuzz) {
      await page.goto('http://localhost:8080/')
      await page.$eval('#searchtext', el => el.value = value);
      await page.$eval('#searchform', form => form.submit())
      await page.waitForSelector('.results-table');
      var text = await page.evaluate(() => document.body.textContent);
      results.push(text)
    }
    expect(results).toEqual(expect.arrayContaining(['bleh']));
  });

顾名思义,异步函数是异步执行。这意味着,它们独立await于调用它们的函数运行,除非调用函数使用关键字等待它们的执行。这意味着当您检查结果时,您无法控制您的async函数当前位于哪一行(实际上它们甚至还没有开始,但那是另一回事)。

此外,由于它们都是异步的,它们也相互独立。意思是,它们都或多或少地同时执行,导致在您的表单中插入随机的乱码。


推荐阅读