Async setup of environment with Jest

后端 未结 3 1120
北恋
北恋 2021-01-04 14:01

Before running e2e tests in Jest I need to get an authentication token from the server.

Is it possible to do this globally one and set it somehow to the glo

相关标签:
3条回答
  • 2021-01-04 14:41

    There's a CLI/config option called: setupFiles, it runs immediately before executing the test code itself.

    "jest": {
      "globals": {
        "__DEV__": true,
        ...
      },
      "setupFiles": [
        "./setup.js"
      ]
    }
    

    setup.js might look something like:

    (async function() {
        // const { authToken } = await fetchAuthTokens()
        global.authToken = '123'
    })()
    

    And then you can access authToken directly in each test suites (files) like beforeAll(_ => console.log(authToken)) // 123.


    However, if you want a global setup that runs per worker(cpu core) instead of per test file (recommended by default since test suites are sandboxed). Based on current jest API constraints, you may choose to customize your test's runtime environment through the testEnvironment option. Then you need to implement a custom class that extends jsdom/node environment exposes setup/runScript/teardown api.

    Example:

    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);
      }
    }
    

    my-test.js

    let authToken;
    
    beforeAll(() => {
      authToken = global.authToken;
    });
    
    0 讨论(0)
  • 2021-01-04 14:46

    I could find no way of skipping tests (test.skip) based on the result of an async condition. The tests determined if they were to be run before my global async condition resolved. I even tried using beforeAll and awaiting the resolution of my promise, but while in tests my condition had resolved, when the tests determined if they were to be run, the promise was unresolved and my var was undefined.

    I ended up doing this with bash in scripts/isLocalCmsRunningOn3030.sh:

    #!/bin/bash
    
    if [[ $(lsof -i :3030 | grep 'node' | grep 'LISTEN') ]]; then
      echo TRUE
    else
      echo FALSE
    fi
    

    package.json:

    IS_CMS_RUNNING=$(scripts/isLocalCmsRunningOn3030.sh) jest
    

    In my setupFile.js:

    global.testIf = (condition) => (condition ? test : test.skip);
    

    In my test file

      testIf(process.env.IS_CMS_RUNNING === 'TRUE')('testname', () => {
      });
    
    0 讨论(0)
  • 2021-01-04 14:46

    Ini my case, I had to get the token for current session once. Here I used globalSetup property in jest config. Ref: https://jestjs.io/docs/en/configuration#globalsetup-string

    My jest.config:

    module.exports = {
      globalSetup: "./tests/global-setup.js",
      // ..other config... 
      globals: {
          TEST_EMAIL: 'test@test.com',
          TEST_PASSWORD: 'some_password',
      }
    }
    

    global-setup.js:

     module.exports = async function() {
      const getSessionToken = () => {
        // api call to get SessionToken
        /* return fetch() */
      }
    
      sessionToken = await getSessionToken();
      process.env.SESSION_TOKEN = sessionToken;
     }
    
    
    0 讨论(0)
提交回复
热议问题