Jest: 全局之前

创建于 2017-06-15  ·  36评论  ·  资料来源: facebook/jest

有没有办法让全局 beforeAll ?

我可以在每个测试文件中定义 beforeAll ,但这将为每个测试文件运行一次 beforeAll 。

是否有任何全局 beforeAll 将在第一次测试开始之前运行一次并完成?

最有用的评论

+1 用于全局设置。 像其他用户一样,我只想设置和拆除应用程序/数据库一次。

所有36条评论

你见过setupFiles吗?

作为参考,我的项目使用setupFiles ,如下所示:

package.json

{
  "jest": {
    "setupFiles": [
      "./private/mocks/runtime.js"
    ]
  }
}

./private/mocks/runtime.js

global.__meteor_runtime_config__ = {ROOT_URL: 'localhost'};

仅供参考 Stack Overflow 可能是解决这类问题的更好地方。 (关于使用而不是错误报告/功能请求的问题)。

此外,我已取消订阅此问题,因此如果您回复,将不会收到任何通知。

我正在使用 create-react-app。
并且 setupFiles 为每个测试文件再次运行。

给出一个不正确的答案并在它之后关闭一个问题。 太棒了!

@cpojer @ashtonsix我不认为这应该被关闭并且答案不正确,每个测试套件都运行setupFilessetupTestFrameworkScriptFile ,所以没有“全局” beforeAll我们可以设置的地方就像在测试之前清理测试数据库一样

你可以在 package.json 中有一个pretest吗?

@Negan1911 - 也许,但很难说出 OP 中的含义。 如果您认为这是一个有用的功能并希望更清楚地说明此功能请求,您可以考虑创建第二个问题?

@cpojer @ashtonsix如果我理解正确,目前不可能像在 Mocha 中讨论的那样进行全局设置和拆卸。
我(可能还有 OP)拥有的用例是我想运行一个服务器,然后才运行我所有的集成测试(并且可能在所有这些测试都运行之后删除测试数据库)。
您对此有什么建议或最佳实践吗?
我发现人们大多告诉启动服务器并在“本地”beforeAll/afterAll 中为每个测试套件关闭它,例如@kentcdodds 在这里,但意味着很多重复,不是吗?

+1 进行全局设置,在我的用例中,我也想运行代理服务器

@ashtonsix对于它的价值,我认为 OP 很清楚。 我希望重新打开这个问题。

您可以创建自定义jest-environment ,参见jest-environment-nodejest-environment-jsdom并将其子类化。 它应该允许您以任何您喜欢的方式设置环境。 我们还讨论了为此添加一个异步钩子,我很高兴为此接受 PR。

+1 想尝试来自 mocha 的玩笑,并且对jest-codemods和文档的易用性印象深刻,直到我遇到了同样的问题。

每个单独文件的第一个describe都花费了惊人的时间来执行。 事实证明,设置是 - 正如之前的评论所解释的 - 每个文件运行一次,导致大量不必要的耗时操作,例如DROP DATABASECREATE DATABASE等等。

不幸的是,除了运行不理想的node setup.js && jest之外,文档中没有解决方法(这反过来又把我带到了这里)。

+1 用于全局设置。 像其他用户一样,我只想设置和拆除应用程序/数据库一次。

+1

在 #4506 中修复

有以下笑话选项globalSetupglobalTeardownhttps://facebook.github.io/jest/docs/en/configuration.html#globalsetup -string

我尝试过使用globalSetup ,但是我不断收到以下错误。我认为这个选项可能会成功@shai32。 但是,我似乎无法让它工作🤣 ...

"jest": "^21.2.1"
 "jest": {
    "globalSetup": "./jest-config.js"
  }



md5-d3a1dcf99642fcf0b9c99c838aadb689



● Validation Warning:

  Unknown option "globalSetup" with value "./jest-setup.js" was found.
  This is probably a typing mistake. Fixing it will remove this message.

  Configuration Documentation:
  https://facebook.github.io/jest/docs/configuration.html

它还没有发布。 Jest 22 现在任何一天都会到来🙂

在 #4506 中修复

我知道它在其中链接,但对于任何寻找的人: https ://github.com/facebook/jest/pull/4716

@btav这是 2 个错误😓

  1. 你现在必须使用绝对路径,或者 ("../../../~ root ~")
  2. 验证警告是误报

这里
还#5093

错误应该用 #5095 #5096 修复

这可以用来设置全局变量吗? 我试过了,但它不起作用....这是设计使然吗?

我的用例是我有一个想要全局设置的自定义日志功能。 我试过_setup.test.js ,但我的全局变量没有被转移。

@zwhitchcox使用 setupFiles 配置选项: https ://facebook.github.io/jest/docs/en/configuration.html#setupfiles -array

有时共享一个通过异步函数设置的全局变量可能很有用。 例如,在 globalSetup 中设置一次 puppeteer 浏览器然后在每个测试/测试套件中生成一个新页面会很有用。

@tdenovan这正是我现在想要做的。 但这似乎不起作用。 我以前在 mocha 中做过这个,这很容易,但开玩笑说我想我需要找出其他方法。
这是我的笑话配置

"jest": {
    "verbose": true,
    "testEnvironment": "node",
    "globalSetup": "<rootDir>/scripts/testSetup.js",
    "globalTeardown": "<rootDir>/scripts/testTeardown.js"
  },
// globalSetup.js
module.exports = async () => {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  bot = Bot(browser, page);
  await bot.goto(bot.baseUrl);
  global.bot = bot;
}

但我无法在我的测试用例中访问机器人。

GGWP! 刚刚解决了。

"e2e": "jest --testRegex '.*.e2e.js'"
// globalTeardown.js
module.exports = async () => {
  if (process.testSetup) {
    process.testSetup.bot.close();
  }
}

 process.testSetup = { bot };
// and then im my tests
const { bot } = process.testSetup;

任何人都想知道机器人是什么,

const Bot = (browser, page) => ({
  browser: browser,
  page: page,
  baseUrl: 'http://localhost:4000',
  user: {
    name: faker.name.findName(),
    email: faker.internet.email(),
    password: 'Test<strong i="13">@123</strong>',
  },
  oldUser: {
    email: '[email protected]',
    password: 'Test<strong i="14">@123</strong>',
  },
  clearSession: async () => {
    await page.evaluate(() => sessionStorage.clear());
  },
  goto: async (url) => {
    await page.goto(url);
  },
  clickButton: async (id) => {
    await page.waitForSelector(id);
    await page.click(id);
  },
  checkText: async (expect, id, text) => {
    await page.waitForSelector(id);
    const elText = await page.$eval(id, el => el.innerHTML);
    expect(elText).toContain(text);
  },
  type: async (id, text) => {
    await page.waitForSelector(id);
    await page.$eval(id, el => el.value = '');
    await page.type(id, text);
  },
  wait: async () => {
    await page.waitForNavigation();
  },
  close: () => {
    browser.close();
  },
});

网站上有 puppeteer 指南: https ://facebook.github.io/jest/docs/en/puppeteer.html

是的,但这表明在 globalSetup 异步方法中设置一个全局是可能的,根据上面它似乎不是 b

@SimenB啊.. 伙计...我试图弄清楚这一点,并且在很长一段时间内都在开玩笑的文档中并且从未注意到该部分。 浪费我的时间。

我有一个问题,如果有多个测试套件并行运行(默认情况下),我在 globalSetup 中设置的全局对象不可用。 运行单个套件测试对象可用,或者如果我设置 --runInBand 以连续运行测试。 如果测试并行运行,如何访问我在 globalSetup 中设置的变量?
我尝试了上面使用的示例(使用进程对象),我还尝试了使用自定义 TestEnvironment 但没有运气的版本:

const PuppeteerJsdomEnvironment = require('jest-puppe-shots/lib/jsdom-environment');

class JestPuppeShotsEnv extends PuppeteerJsdomEnvironment {

  async setup(config) {
    await super.setup(config);
    const { allThemesCss } = global;

    // make the allThemesCss object available in test suites
    Object.assign(this.global, {
      allThemesCss
    });
  }
}

module.exports = JestPuppeShotsEnv;

这是从 globalSetup.js 获取 allThemesCss 并确保它传递给测试套件。

@ovidiu-lapadus 我能够通过使用process而不是全局来使 globalSetup 工作。 它可以在有和没有--runInBand的情况下使用。 例如

// globalSetup.js
module.exports = async () => {
  process.FOOT = 'BALL';
};
// globalTeardown.js
module.exports = async () => {
  console.log(process.FOOT) // BALL 
};
// some.test.js
it('expects 1 to be 1', () => {
    expect(1).toBe(1);
     console.log(process.FOOT); // BALL
});

对于开玩笑的团队,我不确定为什么global在测试中未定义( babel-jest 22.2.2 ),而是在globalTeardown.js中定义。 也许这是一个错误。 现在我只使用process 。 干杯!

谢谢@cellis ,你拯救了我的一天! 我一直在用头撞墙,试图理解为什么global.FOO不起作用。 process.FOO成功了:-)

@kalutheo使用 process.FOO 有几个注意事项。 首先,我不认为你可以在 process 或 process.env 上做深度嵌套的变量。 我想出了一个更好的方法来让全局变量工作,但我是在等着发布它吗? 我所做的是使用 jest-environment 包创建我自己的dbEnvironment 。 在那里,我检查要定义的全局数据库,如果没有,我重新定义它们。 数据库环境仅用于 db 测试,我有另一个仅用于前端测试的配置。 这样,我就不会浪费时间为每个前端更改运行数据库测试。 其次,我有一种方法可以设置多个始终很热的“副本”数据库——你不需要在每次运行时都迁移或转储它们,因为我将它们与开发数据库一起迁移(你可以看到这在我分享的要点中),它允许测试运行得更快。 我设置了这些副本的池,以便在测试中获得最大的并行度。 它在开玩笑的文档中有所记录,但解释得不够好。 无论如何,这是要点: https ://gist.github.com/cellis/08cc332dacf9a548005e8cf35d4b16e2

@ovidiu-lapadus 经过仔细检查,我认为您的问题可能是您在分配全局变量之前调用super.setup() 。 请参阅我在上面发布的要点以获得可行的解决方案。

@cellis感谢您提供这些宝贵的信息。 我将尝试使用您描述的自定义环境

伙计们, globalSetup不应该在这里包括所有像babel-polyfill这样的繁重任务,与chai结合使用,需要jest-extended吗?
似乎globalSetup的工作方式与setupTestFrameworkScriptFile $ 的工作方式大不相同,并且在那里工作的方法在globalSetup中不起作用。
我知道,每个 jest 测试用例都在他的 snadboxed 环境中运行,但在setupTestFrameworkScriptFile中不做任何事情会使测试运行速度非常缓慢。

摩卡:9s
开玩笑:60s,在手表模式下:170s-200s

?

使用process是一种可能会破坏的 hack(这是一个错误)。

您可能想关注 #7184

这不是问题上所要求的全局beforeAll() ,但是有了这个,您可以轻松避免代码重复。 您可以创建一个节点环境,它将为您的所有测试文件设置: https ://stackoverflow.com/a/61260044/4934640


更新

我刚刚发现我可以在globalSetup上设置一个环境变量,这意味着我可以在测试用例/套件/文件之间共享服务器地址: https ://github.com/facebook/jest/issues/7184#

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

mmcgahan picture mmcgahan  ·  3评论

jardakotesovec picture jardakotesovec  ·  3评论

rosiakr picture rosiakr  ·  3评论

hramos picture hramos  ·  3评论

paularmstrong picture paularmstrong  ·  3评论