TDD - Jest

SSAD·2023년 3월 2일
0

BackEnd

목록 보기
42/44
post-custom-banner

테스트 코드의 중요성

  • 새로운 코드를 작성한 후에 잘 동작 하였음

  • 그리고 다른 새로운 기능을 하는 코드를 작성

  • 이때 아까까지 정상적으로 동작하던 기존의 코드의 기능이 망가질수 있음

  • 코드의 변화가 있을 때마다, 직접 모든 기능을 전부 체크해 보는 것은 효율적이지 않음


TDD

TDD란 Test Driven Development의 약자로 '테스트 주도 개발'이라고 함

  • 반복 테스트를 이용한 소프트웨어 방법론으로
    작은 단위의 테스트 케이스를 작성하고 이를 통과하는 코드를 추가하는 단계를 반복하여 구현

  • 짧은 개발 주기의 반복에 의존하는 개발 프로세스

  • 애자일 방법론 중 하나인
    eXtream Programming(XP)의 'Test-First' 개념에 기반을 둔 단순 설계를 주요시 함

  • eXtream Propgramming(XP)란
    미래에 대한 예측을 최대한 하지 않고
    지속적으로 프로토타입을 완성하는 애자일 기방법론 중 하나임


테스트의 종류

unit test(단위 테스트)

  • 응용 프로그램에서 함수처럼 가장 작은 단위를 테스트함

integration test(통합 테스트)

  • unit test가 가장 작은 부분만 따로 테스트 한다면,
    통합 테스트는 유닛들을 모아서 함께 테스트

  • 서버의 구성 요소들이 함께 잘 작동하는지를 테스트하기 위함

e2e test(end-to-end)

  • 사용자의 입장에서 사용자의 상황을 처음부터 끝까지 가정하여
    올바르게 작동하는지 테스트 하는 것을 말함

  • 예상되는 사용자의 행동과, 여러 시나리오들을 만들어 시뮬레이션

  • e2e 테스트를 도와주는 프론트엔드 도구에는 대표적으로 Cypress, Selenium 등이 있음



Jest In NestJS

Jest 란?

JavaScript 테스트 프레임워크

  • NestJs에서는 JavaScript 테스트 프레임워크인 jest를 기본 테스트 프레임워크로 지원

  • 테스트 코드의 모양이 직관적이고 문서화가 잘 되어 있어 많이 활용하는 Framework

  • 여러가지 상황에 맞는 로직과 결과가 나오는지 자동으로 테스트를 해줌

  • Jest 이전에는 여러가지 테스트 라이브러리르 섞어 사용

  • Mock함수를 만들기 위해 Sinon과 TestDouble과 같은 Test Mock라이브러리를
    추가로 설치하여 사용하였음

  • Jest 거의 모든 기능을 한번에 지원


Jest 실습해보기

package.json에서 Jest 확인

app.controller.spec.ts 에서 기본 구조 확인

Jest 파일 구조

  • beforeEach : Testing 이전에 실행되는 부분
  • describe : 여러 개의 테스트를 모아 놓은 그룹 단위
  • test(it) : 하나의 테스트
  • expect : 값을 테스트할 때마다 사용됨, matcher랑 같이 사용
  • matcher : 다른 방법으로 값을 테스트하도록 사용

src -> ___.spec.ts 파일 작성

// 하나의 테스트
it('add a + b', () => {
  const a = 1;
  const b = 2;

  expect(a + b).toBe(3);
});

// 그룹테스트
describe('group test', () => {
  it('group test1', () => {
    console.log('group_test1');
  });
  it('group test2', () => {
    console.log('group_test2');
  });
});

결과

실습

// 상품구매 테스트
describe('buy product', () => {
  beforeEach(() => {
    // login
  });

  it('money validation', () => {
    const result = true;
    expect(result).toBe(true);
  });

  it('buy product', () => {
    const result = true;
    expect(result).toBe(true);
  });
});

결과

  • beforeEach는 각각의 테스트 진행하기 전에 먼저 실행되어야 하는 로직이 들어감

  • 각각의 검증 코드들을 작성

실습2

import { AppController } from './app.controller';
import { AppService } from './app.service';

describe('AppController', () => {
  let appService: AppService;
  let appController: AppController;

  beforeEach(() => {
    appService = new AppService();
    appController = new AppController(appService);
  });

  describe('getHello', () => {
    it('return Hello World!', () => {
      const result = appController.getHello();
      console.log(result);
      expect(result).toBe('Hello World!');
    });
  });
});
  • describe에 테스트 할 Service와 Controller 주입
  • beforeEach에 Service, Controller 연결

결과

실습3

NestJS는 Dependency injection을 통해 각 Module을 캡슐화하여
서로 의존성을 배재함

Testing module을 만들어서 Testing을 진행

  • @nest/testing 패키지를 사용
    테스트에 사용되는 종속성만 선언해서 모듈을 만들고
    Service, Repository를 가져올 수 있음
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';

describe('AppController', () => {
  let appController: AppController;

  beforeEach(async () => {
    const app: TestingModule = await Test.createTestingModule({
      controllers: [AppController],
      providers: [AppService],
    }).compile();

    appController = app.get<AppController>(AppController);
  });

  describe('getHello', () => {
    it('return Hello World!', () => {
      expect(appController.getHello()).toBe('Hello World!');
    });
  });
});
  • beforEach에 app이라는 Testing module 생성

    • Test module은 app.module.ts의 역할
  • .get(AppController) 작성하여 app에서 AppController를 가져옴

    • appController 변수에 할당하여 Testing module에 연결

결과

profile
learn !
post-custom-banner

0개의 댓글