Test 환경 마련하기

JaeKyung Hwang·2024년 7월 8일
0

TECH

목록 보기
2/16
post-thumbnail

성능 개선을 테스트하기 위한 환경을 마련하고자 test server와 test data를 준비해보았다. (코드 참고)

🌐Test server

  • 현재 OAuth 기반으로 사용자를 data를 생성하기 때문에 테스트를 위해서는 OAuth service를 mocking해야 한다.
  • 마찬가지로 이미지 또한 AWS S3에 저장하고 있기 때문에 S3 service를 mocking해야 한다.
  • 위와 같이 테스트에서는 mocking이 필요한 service들이 존재하기 때문에 NestJS의 TestingModule을 활용해 test server를 띄운다.
  • 추가로 test server를 구동하면 TypeORM Entity에서 정의한 대로 table도 자동으로 생성되기 때문에 편하다.

💾Test data

구성

기본적으로 성능에 영향을 주는, 다시 말해 API에서 사용하는 field 값만 random으로 정한다.
그 외에는 여러 값을 가질 수 있어도 고정 값을 사용한다.

  • n명의 사용자 생성
  • n명의 사용자 각각에게 random하게 0~5마리의 강아지를 생성
  • n명의 사용자 각각에게 random하게 0~50개30일 이내의 날짜1~(사용자가 소유한 강아지 수)마리의 강아지와 함께 산책한 산책 일지를 생성

Trouble Shooting 참고

특징

1. CLI 기반의 간단한 test data 삽입/삭제

  • 10,000명 사용자를 생성하는 test data 삽입 예시
    $ MYSQL_DATABASE=performance DATA_SIZE=10000 npm run test:insert
    
    > nest-js-example@0.0.1 test:insert
    > cross-env NODE_ENV=test ts-node ./test/performance/insert-test-data.ts
    
    Test server running at http://localhost:3333
    Connected database: performance
    Cleared all test data
    Successfully inserted test data (+28524ms):
    ┌─────────┬─────────────────┬────────┐
    │ (index) │     Entity      │ Count  │
    ├─────────┼─────────────────┼────────┤
    │    0'Users'10000  │
    │    1'Dogs'25187  │
    │    2'UserDogs'25187  │
    │    3'Journals'210526 │
    │    4'JournalsDogs'421673 │
    │    5'JournalPhotos'316036 │
    │    6'Excrements'421673 │
    └─────────┴─────────────────┴────────┘
    Total data size: 1430282
    Close connection with the database
    Terminate the test application
  • DB 비우기
    $ MYSQL_DATABASE=performance npm run test:clear

2. random seed를 지정할 수 있도록 해 테스트의 재현성 확보

  • MDN 공식 문서에 따르면 Math.random() method는 사용자가 seed를 따로 지정할 수가 없다.

    The Math.random() static method returns a floating-point, pseudo-random number that's greater than or equal to 0 and less than 1, with approximately uniform distribution over that range — which you can then scale to your desired range. The implementation selects the initial seed to the random number generation algorithm; it cannot be chosen or reset by the user.

  • 그래서 직접 난수 생성 알고리즘을 구현하거나 외부 라이브러리를 사용해야 하는데 검색해본 결과 seedrandom을 사용하기로 결정했다.

  • seedrandom 라이브러리의 경우 CommonJS 스타일만 지원하는 관계로 어쩔 수 없이 eslint의 no-var-requires 규칙을 무시하도록 주석을 추가했다.

    // eslint-disable-next-line @typescript-eslint/no-var-requires
    const seedrandom = require('seedrandom');
    
    const randomNumberGenerator = seedrandom(process.env.SEED ?? 'dangdangwalk');
                                             
    randomNumberGenerator();
  • 환경변수 SEED(default 'dangdangwalk')에 같은 값을 넣으면 동일한 개수의 테스트 데이터가 삽입된다.
    SEED=hello를 적용한 경우:

    $ MYSQL_DATABASE=performance DATA_SIZE=100 SEED=hello npm run test:insert
    
    > nest-js-example@0.0.1 test:insert
    > cross-env NODE_ENV=test ts-node ./test/performance/insert-test-data.ts
    
    Test server running at http://localhost:3333
    Connected database: performance
    Cleared all test data
    Successfully inserted test data (+301ms):
    ┌─────────┬─────────────────┬───────┐
    │ (index) │     Entity      │ Count │
    ├─────────┼─────────────────┼───────┤
    │    0'Users'100  │
    │    1'Dogs'251  │
    │    2'UserDogs'251  │
    │    3'Journals'2071  │
    │    4'JournalsDogs'4161  │
    │    5'JournalPhotos'3122  │
    │    6'Excrements'4161  │
    └─────────┴─────────────────┴───────┘
    Total data size: 14117
    Close connection with the database
    Terminate the test application
profile
이것저것 관심 많은 개발자👩‍💻

0개의 댓글