목차

Test Fixture 란

소프트웨어 테스트에서 테스트 환경을 설정하고 관리하기 위한 코드 집합을 의미합니다. 테스트가 정확하고 일관성 있게 실행될 수 있도록 준비하는 과정입니다. 이는 테스트를 위해 필요한 모든 상태나 환경을 포함합니다. 예를 들어, 데이터베이스를 설정하거나, 필요한 객체를 생성하거나, 특정 상태로 초기화하는 작업이 포함됩니다.

Test Fixture를 구성하는 기본 원칙

  • 독립적인 테스트 환경 구성: 이전 테스트의 실행이 이후 테스트에 영향을 주지 않도록 하기 위해, beforeEach 또는 afterEach를 사용해 환경을 초기화하고 정리
  • Setup과 Teardown 구분 
    • SetUp : beforeAll, beforeEach 메서드를 사용하여 필요한 초기 설정
    • Teardown : afterAll, afterEach를 사용해 자원을 정리
  • 재사용 가능한 코드 작성: 공통된 설정이나 데이터 준비 작업을 별도의 헬퍼 함수나 클래스로 추출하여, 필요할 때 재사용할 수 있게 작성

Test Fixture를 사용하는 이유

  1. 테스트가 항상 동일한 조건에서 실행되며, 테스트의 독립성과 신뢰성을 보장
  2. 사용하면 코드가 간결해지고, 유지보수성이 높아지며, 자동화된 테스트 실행이 용이

예제 상황

  1. 데이터베이스 테스트: 데이터베이스를 사용하는 애플리케이션의 경우, 각 테스트 전에 데이터베이스를 특정 상태로 초기화하고, 테스트 후에 정리하는 작업을 Test Fixture로 구성
  2. HTTP 요청 테스트: API 테스트에서는 각 요청에 대한 환경 설정(예: 모의 데이터 또는 인증 토큰 설정)을 Test Fixture로 구성

NestJS에서의 Test Fixture

NestJS에서 테스트를 작성할 때, beforeEach, afterEach, beforeAll, afterAll을 사용하여 테스트 픽스처를 구성할 수 있습니다. 주로 TestingModule을 사용하여 애플리케이션 모듈의 인스턴스를 생성하고, 의존성을 주입하는 작업이 포함

 

구성 요소 설명

  • TestingModule: NestJS의 테스트 모듈을 생성하여 의존성을 주입하고, 각 컴포넌트가 올바르게 동작하는지 확인합니다.
  • beforeAll: 테스트 스위트 내에서 한 번만 실행되는 초기화 코드입니다. 여기서 TestingModule을 컴파일하고 컨트롤러와 서비스를 인스턴스화합니다.
  • beforeEach: 각 테스트가 실행되기 전에 실행되어, 테스트 상태를 초기화하거나 Jest의 mock을 재설정합니다.
  • afterAll: 테스트가 모두 종료된 후 한 번 실행되어, 테스트 환경을 정리하거나 자원을 해제합니다.

NestJS와 Jest를 사용하여 테스트 픽스처를 구성하는 방법을 보여주는 예제

import { Test, TestingModule } from '@nestjs/testing';
import { MyService } from './my.service';
import { MyController } from './my.controller';

describe('MyController', () => {
  let controller: MyController;
  let service: MyService;

  beforeAll(async () => {
    // 모든 테스트 전에 실행되는 setup 작업 (한 번만 실행)
    const module: TestingModule = await Test.createTestingModule({
      controllers: [MyController],
      providers: [MyService],
    }).compile();

    controller = module.get<MyController>(MyController);
    service = module.get<MyService>(MyService);
  });

  beforeEach(() => {
    // 각 테스트 전에 필요한 초기화 작업 수행
    jest.clearAllMocks(); // Jest의 모든 mock 초기화
  });
  
  afterEach(() => {
    // 각 테스트 후 자원 해제나 초기화 작업
  });
  
  // 테스트
  it('should return expected data', async () => {
    const result = 'expected result';
    jest.spyOn(service, 'getData').mockImplementation(() => result);

    expect(await controller.getData()).toBe(result);
  });
  

  afterAll(() => {
    // 모든 테스트 후에 실행되는 teardown 작업 (한 번만 실행)
    // 테스트 모듈 정리 또는 자원 해제
  });
});

 

 

반복되는 코드를 모두 Fixture를 만들어서 해야 할까?

 

경우에 따라 다르겠지만, 테스트 상황에서 기본적으로 몰라도 되는 확인해보지 않아도 되는 코드는  Fixture를 생성해서 구현하는 것이 좋아 보인다. 예를 들어, 데이터 베이스 초기화같은 것이 있겠다.

 

하지만, 유저 생성, 토큰생성 등을 beforeAll 이나 beforeEach 에 구현해 버리면 각 테스트 마다 확인하기 위해 코드의 위 아래를 오가야하므로 오히려 비효율적이라고 생각한다.

 

차라리, 해당 기능들을 함수나 클래스를 만들어서 각 테스트에서 호출하여 사용하는 방법이 해당 테스트를 더 빨리 이해할 수 있을 것 같다.

  

 

'TDD > 개념' 카테고리의 다른 글

[ TDD ] 런던파 vs 고전파  (0) 2024.12.02

목차

계층과 확장성

확장성에대한 요구

  • 서버 1대로 작동하는 서비스가 다수
    • 하테나 표준 서버 (4 core CPU, 8 GB 메모리) 예시
      • 피크 시 성능은 수천 요청/ 분 → 월 100 만 page view 처리 가능
    • 고성능 서버 (4 core CPU 2개, 32 GB 메모리)
      • 피크 시 : 월 200 만 page view 처리가능
  • 하테나에서 수억 page view / 월
    • 대규모 서비스는 서버 1대로는 동작할 수 없다.

계층별 확장성

  • AP 서버 ▶ 비교적 간단하게 확장가능
    • 구성이 동일하고 상태를 갖지 않기 때문
  • DB / 파일 서버 ▶ 분산, 확장성 확보가 어려움
    • read 분산 : 비교적 용이  ▶ 메모리를 많이 탑재, 기타
    • write 분산 : 매우 어려움

→ AP 서버 와  데이터 소스를(DB / 파일 서버) 구분해서 확장을 고려해야 한다.

부하 파악,  튜닝

부하파악 - 가시화

어떻게 서버를 확장할 것인지를 검토하기 위해서는 먼저 서버 부하를 파악할 수 있어야 한다.

 

서버군을 관리하고 각각의 부하를 적절하게 그래프화하는 것이 중요

 

하테나 북마크 예시

서버의 역할을 나열하여 관리하는 화면

 

부하를 측정하기 위한 항목 - Load Average,  CPU 관련, 메모리 관련

 

가장먼저 Load Average 확인

*Load Average ?
     프로세스가 언제든지 동작할 수 있는 상태이지만, 아직 실제 CPU가 할당되지 않아서 대기상태에 있는 프로세스의 수의 평균치
    (ex) 5분 동안 Load Average가 1이면 => 5분동안 평균 1개의 프로세스가 대기상태로 되어 있다는 의미, 이때 CPU의 코어 수 이하이면 부하가 양호한 편 (보통 CPU의 코어 수 이하에서 절반 정도로 맞춰지도록 제어함)

 

메모리 사용처 확인

 사용자 공간이 소비되고 있는 메모리공유되고 있는 메모리, 그리고 커널이 사용하고 있는 버퍼의 메모리

이런 항목을 통해 ▶ " 이런 거동을 하고 있으니 이런 동작을 보이고 있어" 와 같이 파악 ▶ 서버의 성능을 더 끌어내 고성능 시스템을 실현

 

용도에 맞는 튜닝 - 사용자용 서버, 봇용 서버

 

서버 분리

  • 봇용 : 응답시간이 중요하지 않음 → 요청 처리 수를 최대화시키는 방향으로 튜닝 가능
  • 사용자용 : 응답시간 중요 → 처리대기 프로세스를 쌓아두지 않고 양호한 응답을 유지하는 방향으로 튜닝 가능

봇과 사용자를 분리하여 AP 서버의 튜닝 정책을 변경해서

  • 효율을 중시할지
  • 응답시간을 중시할지
  • 리소스를 최대한 사용하는 것을 중시할지

결정하여 운영방향을 나눌 수 있다.

 

DB 도 사용자용과 봇용으로 나눠서 응답을 중요시할지, 리소스를 소진하는 것을 중요시할지 나누어서 운영할 수 있다.

 

튜닝 및 확장성 확보

 

튜닝

  • 부하파악, 상태 감시 : 서버관리툴
  • 부하를 가시화해서 병목이나 이상현상을 파악할 수 있도록 한다.
    • 여러 서버의 그래프를 겹쳐봄으로써 병목이나 이상현상 파악가능
  • OS의 동작원리를 알고 서버 성능을 올바르게 끌어내기 

확장성 확보

  • 로드밸랜서이용
  • 파티셔닝(DB분할)

jest 를 적용하기 위해서 필요한 설정

1. Jest 설치 확인

npm install jest --save-dev

 

2. pacakge.json 에 있는 테스트 스크립트 변경/추가

 "scripts": {
    "test": "jest" 
  },

 

3. 기본적인 설정 파일을 생성 : jest.config.js 생성

$ npx jest --init

   - Would you like to use Typescript for the configuration file?   → No 선택

+ Recent posts