Jest Workflow Unit Tests Run Long

Hello Community,
Our test pipelines are failing because my first simple temporal workflow unit test is taking longer than the maximum per test (5 seconds) to execute.

I timed the individual pieces of the unit test and found that the key contributor to this are:

  • await TestWorkflowEnvironment.createTimeSkipping();
    …which takes ~0.5 secs and…
  • Worker.create
    …which takes ~2.5-3 secs

Is this a normal and acceptable run-time for these specific sdk calls or can I influence this code for better performance?

Here is the gist of my test:

imports...
let testEnv: TestWorkflowEnvironment;

const workflowCoverage = new WorkflowCoverage();
const taskQueue = 'test';

beforeAll(async () => {
  testEnv = await TestWorkflowEnvironment.createTimeSkipping();
});

afterAll(async () => {
  testEnv?.teardown();
  // this currently causes jest to abort when collecting coverage
  // workflowCoverage.mergeIntoGlobalCoverage();
});

describe('workflows/myTest', () => {
  it('runs through a happy path', async () => {
    const { client, nativeConnection } = testEnv;
    
    const workerOptions = workflowCoverage.augmentWorkerOptions({
      connection: nativeConnection,
      taskQueue,
      workflowsPath: require.resolve('../../../src/workflows/my-workflow'),
      activities: {
        createJobActivity: () => (true),
      },
    });
    const worker = await Worker.create(workerOptions);

    await worker.runUntil(async () => {
      const wfHandle = await client.workflow.start(myWorkflow, {
        workflowId: uuid4(),
        args: [id: uuid4()],
        taskQueue,
      });
      assert.ok(wfHandle);
      const state1 = await wfHandle.query<StateType>(getStateQuery);
      assert.ok(state1 === 'STARTED');

      const pretendConfirmation = true;
      await wfHandle.signal(confirmationSignal, pretendConfirmation);
    });
  });
});

That feels a little bit high indeed, yet still within expectations.

To compare, similar tests from the TS SDK suite takes between 100 ms and 2000 ms on my local machine, with most being in the lower range.

A few things that might help reduce your test execution time:

  • Creating test workflow environments (both the regular one and the time skipping one) require downloading the corresponding server binary from the cloud. This obviously take some time. Once it has been downloaded, the binary file is kept in a local cache, so that should only affect the very first test that you run.
  • Passing the workflowsPath option to Worker.create means that the Worker will need to bundle your workflow code. That might take some time (>5 seconds is not uncommon here for complex workflow projects with tons of dependencies). Make sure to limit as much as possible what gets included in your workflow bundle (ie. reduce the number of modules that gets imported), or prebundle your workflow code reuse the workflow bundle in every tests. A Slack user recently reported cutting down the time it takes to runs some test from 1.5 s down to 250 ms, just by prebundling their workflows.
  • Don’t have metrics on this, but I expect the time skipping test server to be slower than the regular server. Prefer TestWorkflowEnvironment.createLocal() if possible.
  • I strongly recommend always enabling the WorkerOptions.reuseV8Context. It should generally not have specific impact on start time, but it should considerably reduce the time it takes to run each workflow tasks. We intend to make that option the default starting with the 1.9.0 release.
  • As a very last thing, you may be able to save just a little bit more by enabling the WorkerOptions.debug option, which will avoid the initialization and use of the workflow worker’s thread pool.
1 Like

Thanks a lot!!