使用Jest异步设置环境

dev*_*ull 5 javascript jest e2e-testing

Jest中运行e2e测试之前,我需要从服务器获取身份验证令牌.

是否可以在全局范围内执行此操作并将其设置为每个测试的全局环境/上下文?

我尝试使用globalSetup配置选项:

const auth = require('./src/auth')
const ctx = require('./src/context')

module.exports = () => {
    return new Promise(res => {
        auth.getToken()
            .then(token => {
                ctx.init({token})
                global.token = token
                res()
            })

    })
}
Run Code Online (Sandbox Code Playgroud)

context.js

let _token

const init = ({token}) => {
    _token = token
}

const getToken = () => {
    return _token
}

module.exports = {
    init,
    getToken

}
Run Code Online (Sandbox Code Playgroud)

但两者都global.token没有ctx.getToken()返回undefined.

我需要使用帮助脚本并将令牌作为env var传递,然后将其设置为global.

  "scripts": {
    "test": "TOKEN=$(node src/get-token.js) jest"
  },
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法(不涉及shell)?

Xle*_*lee 9

有一个名为setupFiles的CLI/config选项,它在执行测试代码之前立即运行.

"jest": {
  "globals": {
    "__DEV__": true,
    ...
  },
  "setupFiles": [
    "./setup.js"
  ]
}
Run Code Online (Sandbox Code Playgroud)

setup.js 可能看起来像:

(async function() {
    // const { authToken } = await fetchAuthTokens()
    global.authToken = '123'
})()
Run Code Online (Sandbox Code Playgroud)

然后你可以authToken直接在每个测试套件(文件)中访问beforeAll(_ => console.log(authToken)) // 123.


但是,如果您希望每个工作程序(cpu核心)而不是每个测试文件运行全局设置(默认情况下建议使用,因为测试套件是沙箱).根据当前的jest API约束,您可以选择通过该testEnvironment选项自定义测试的运行时环境.然后,您需要实现扩展jsdom/ node环境公开setup/ runScript/ teardownapi 的自定义类.

例:

customEnvironment.js

// my-custom-environment
const NodeEnvironment = require('jest-environment-node');

class CustomEnvironment extends NodeEnvironment {
  constructor(config) {
    super(config);
  }

  async setup() {
    await super.setup();
    const token = await someSetupTasks();
    this.global.authToken = token;
  }

  async teardown() {
    await super.teardown();
    await someTeardownTasks();
  }

  runScript(script) {
    return super.runScript(script);
  }
}
Run Code Online (Sandbox Code Playgroud)

我-test.js

let authToken;

beforeAll(() => {
  authToken = global.authToken;
});
Run Code Online (Sandbox Code Playgroud)

  • **`如果您想要一个针对每个工作线程(CPU 核心)而不是每个测试文件运行的全局设置`**:文档说“TestEnvironment 是沙盒的”。每个测试套件都会在自己的 TestEnvironment 中触发安装/拆卸:[https://jestjs.io/docs/en/configuration.html#testenvironment-string](https://jestjs.io/docs/en/configuration. html#testenvironment-字符串) (3认同)
  • 这仅使用硬编码值有效。当涉及到异步功能时,令牌始终是未定义的。 (2认同)