Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

It takes 9 seconds to run my tests, but each test is < 20ms? #274

Open
dprothero opened this issue Sep 6, 2022 · 3 comments
Open

It takes 9 seconds to run my tests, but each test is < 20ms? #274

dprothero opened this issue Sep 6, 2022 · 3 comments
Labels
external-dependency Depends on an entity/dependency external to the team's control technical A technical issue that requires understanding of the code, infrastructure or dependencies

Comments

@dprothero
Copy link

I'm wondering if the AWS SDK is doing something behind the scenes during initialization. It's taking 9 seconds to run two simple tests where I'm mocking DynamoDB.putItem, however jest is reporting the time for each test as taking less than 20ms.

Can anyone see if I'm doing something wrong? Or, is this just to be expected when mocking the SDK?

Here's my test suite:

import AWSMock from 'aws-sdk-mock';
import AWS from 'aws-sdk';
import * as db from '../../src/utils/database';

describe('database', () => {
  beforeAll(() => {
    process.env.AWS_ACCESS_KEY_ID = 'AKIAIOSFODNN7EXAMPLE';
    process.env.AWS_SECRET_ACCESS_KEY = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY';
  });

  afterEach(() => {
    AWSMock.restore();
  });

  describe('writeCheckRunItem', () => {
    const writeCheckRunItem = db.writeCheckRunItem;

    test('writes a new item with minimum required fields', async () => {
      let passedParams;

      AWSMock.setSDKInstance(AWS);
      AWSMock.mock('DynamoDB', 'putItem', (params, callback) => {
        passedParams = params;
        callback(undefined, {});
      });

      const item = {
        owner: 'foo',
        repo: 'bar',
        head_sha: '123',
        check_id: 1,
      };

      await writeCheckRunItem(item);

      expect(passedParams).toEqual({
        TableName: 'check_runs',
        Item: {
          key: { S: 'foo/bar/123' },
          owner: { S: 'foo' },
          repo: { S: 'bar' },
          head_sha: { S: '123' },
          check_id: { N: '1' },
          pr_number: { N: undefined },
          docs_key: { S: undefined },
          docs_owner: { S: undefined },
          docs_repo: { S: undefined },
          docs_pr_number: { N: undefined },
        },
      });
    });

    test('writes a new item with all fields', async () => {
      let passedParams;

      AWSMock.setSDKInstance(AWS);
      AWSMock.mock('DynamoDB', 'putItem', (params, callback) => {
        passedParams = params;
        callback(undefined, {});
      });

      const item = {
        owner: 'foo',
        repo: 'bar',
        head_sha: '123',
        check_id: 1,
        pr_number: 2,
        docs_owner: 'baz',
        docs_repo: 'qux',
        docs_pr_number: 3,
      };

      await writeCheckRunItem(item);

      expect(passedParams).toEqual({
        TableName: 'check_runs',
        Item: {
          key: { S: 'foo/bar/123' },
          owner: { S: 'foo' },
          repo: { S: 'bar' },
          head_sha: { S: '123' },
          check_id: { N: '1' },
          pr_number: { N: '2' },
          docs_key: { S: 'baz/qux/3' },
          docs_owner: { S: 'baz' },
          docs_repo: { S: 'qux' },
          docs_pr_number: { N: '3' },
        },
      });
    });
  });
});

And here's the source module that it's testing (database.ts):

import AWS from 'aws-sdk';

export interface CheckRunQuery {
  owner: string;
  repo: string;
  head_sha: string;
}

export interface CheckRunOptionalFields {
  pr_number?: number;
  docs_owner?: string;
  docs_repo?: string;
  docs_pr_number?: number;
}

export interface CheckRunItem extends CheckRunQuery, CheckRunOptionalFields {
  check_id: number;
}

export interface CheckRunItemResponse extends CheckRunQuery, CheckRunOptionalFields {
  check_id?: number;
}

export async function writeCheckRunItem(item: CheckRunItem): Promise<void> {
  const params = {
    TableName: 'check_runs',
    Item: {
      key: { S: `${item.owner}/${item.repo}/${item.head_sha}` },
      owner: { S: item.owner },
      repo: { S: item.repo },
      head_sha: { S: item.head_sha },
      check_id: { N: item.check_id.toString() },
      pr_number: { N: item.pr_number?.toString() },
      docs_key: { S: item.docs_owner ? `${item.docs_owner}/${item.docs_repo}/${item.docs_pr_number}` : undefined },
      docs_owner: { S: item.docs_owner },
      docs_repo: { S: item.docs_repo },
      docs_pr_number: { N: item.docs_pr_number?.toString() },
    },
  };

  AWS.config.update({ region: 'us-east-1' });
  const ddb = new AWS.DynamoDB({ apiVersion: '2012-08-10' });
  await ddb.putItem(params).promise();
}

Test run output:

image

@nelsonic
Copy link
Member

nelsonic commented Sep 6, 2022

@dprothero thanks for opening this issue to report your experience. 😞
We don't use jest anymore so it's a good reminder of why we switched. 😉
Known issue with jest startup time, see: jestjs/jest#10833 🐌
Consider using ava or tape if you want your tests to run muuuuuch faster. 🐎
Keep us posted if you are able to speed them up. 👌

@nelsonic nelsonic added technical A technical issue that requires understanding of the code, infrastructure or dependencies external-dependency Depends on an entity/dependency external to the team's control labels Sep 6, 2022
@dprothero
Copy link
Author

Hmmm, I'm not disputing that jest is probably slower, but I don't believe that is the cause of the slowdowns. This is a tiny repo. When I run other tests in isolation that don't make use of AWS, they run quite quickly. The above test was run with yarn test --watch test/utils/database.test.ts. Below are results for another module that doesn't use AWS, run with yarn test --watch test/utils/config.test.ts:

image

@dprothero
Copy link
Author

dprothero commented Sep 6, 2022

Unless you're saying there's some interaction between jest and AWS and/or the way the mocks work...?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
external-dependency Depends on an entity/dependency external to the team's control technical A technical issue that requires understanding of the code, infrastructure or dependencies
Projects
None yet
Development

No branches or pull requests

2 participants