Conditionally run tests in Jest

Along the same lines as the accepted answer:

const maybe = process.env.JEST_ALLOW_INTEG ? describe : describe.skip;
maybe('Integration', () => {
  test('some integration test', async () => {
    expect(1).toEqual(1);
    return;
  });
});

const itif = (condition) => condition ? it : it.skip;

describe('suite name', () => {
  itif(true)('test name', async () => {
    // Your test
  });
});

A small variation on the accepted post, but if we combine Jest's test.skip(...) with the kind of blind argument forwarding that modern JS allows thanks to the spread operator, we can get a cleaner solution that conditionally runs tests, while letting Jest know it skipped something "the official way", without needing a "functionfunction" call:

const testIf = (condition, ...args) =>
  condition ? test(...args) : test.skip(...args);

describe(`a mix of tests and conditional tests`, () => {
  test(`this will always run`, () => {
    expect("1").toBe("1");
  });

  testIf(Math.random() > 0.5, `this will only run half the time`, () => {
    expect("2").toBe("2");
  });
});

Half the time this will run as:

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        0.451 s, estimated 1 s

And half the time it will show:

Test Suites: 1 passed, 1 total
Tests:       1 skipped, 1 passed, 2 total
Snapshots:   0 total
Time:        0.354 s, estimated 1 s

But to cover the part that no one seems to have included in their answers, we can use this to skip over long-running tests by combining it with "looking at process.argv for a runtime flag":

const runLong = process.argv.includes(`--run-long`);

const testIf = (condition, ...args) =>
  condition ? test(...args) : test.skip(...args);

describe(`Run tests, and long tests only if told to`, () => {

  // ...

  testIf(runLong, `Some long-running test, skip if --run-long is not set`, () => {
    // a test that runs for a long time here
  });
});

And then we can just put that runtime flag in our npm script. However, we need to make sure to forward that flag on to our script, rather than to jest, or to npm:

...
"scripts": {
  ...
  "test": "jest somedir",
  "test:long": "npm run test -- -- --run-long",
  ...
},
...

This looks kind of weird, and it is kind of weird, but it's a consequence of how argument forwarding works for npm scripts:

  1. The first -- tells npm that it needs to forward what follows, rather than interpreting that flag itself (in effect: this makes npm run jest somedir -- --run-long).
  2. The second -- tells jest that it needs to forward what follows, instead of considering it a runtime flag for itself, so that our script gets to see it in its process.argv list (so that we call ourscript --run-long).

A common mistake is to forget that second --, which would lead to a fun error that doesn't tell you that just forgot two dashes, and no tests running at all.