Lsiron

Nest.js에서 Jest로 유닛 테스트와 E2E 테스트 시작하기 본문

백엔드/Nest.js

Nest.js에서 Jest로 유닛 테스트와 E2E 테스트 시작하기

Lsiron 2024. 8. 28. 02:55

Nest.js에는 기본적으로 테스팅과 관련된 스크립트가 5가지가 있다.

 

package.json 파일을 보면 아래와 같은 코드가 적용되어 있을 것이다. ( Nest.js를 설치했다는 전제 하 )

    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"

 

여기서 Jest는 JavaScript를 아주 쉽게 테스팅할 수 있게 해주는 npm 패키지이다.

 

일반적으로는 Jest를 따로 설치해 주어야 하지만, Nest.js에는 기본적으로 Jest가 설정되어 있어서 추가 설치 없이 바로 사용할 수 있다.

.spec.ts 파일과 Jest

이제 아래 파일을 봐 보자.

 

Nest.js로 Controller 파일이나 Service 파일을 만들면, 함께 생성되는 .spec.ts 파일이 있다.

 

이 파일이 바로 테스팅을 위한 파일이다. 예를 들어 movies.service.ts 파일을 테스팅하고 싶다면, 동일한 이름을 가진 movies.service.spec.ts 파일이 있어야 한다.

 

이 .spec.ts 파일들은 기본적으로 Jest가 테스팅할 수 있도록 설정되어 있다!

 

즉, Nest.js는 .spec.ts 파일을 자동으로 찾아서 테스트를 실행하기 때문에 특정 파일을 테스트하고 싶다면 그 파일에 대한 .spec.ts 파일을 생성하면 된다.

커버리지 확인

코드 커버리지를 확인하기 위해 아래 명령어를 입력 해 보자.

$ npm run test:cov

 

이 명령어는 모든 .spec.ts 파일을 찾아서 코드의 몇 퍼센트가 테스트되고 있는지, 몇 줄이 테스트되지 않았는지를 알려준다.

 

예를 들어, movies.service.spec.ts 파일에서는 12.5%의 함수가 테스트되고, 21.42%의 라인이 테스트되었을 수 있다.

 

특정 라인, 예를 들어 11번에서 37번까지의 라인은 테스팅되지 않았다는 식으로 자세히 보고된다.

 

이 모든 것이 가능한 이유는 movies.service.spec.ts 파일이 있기 때문이다.

 

따라서 테스트를 실행하려면 해당 서비스 또는 컨트롤러에 대한 .spec.ts 파일이 반드시 있어야 한다.

Watch Mode에서 테스트 실행

테스트를 자동으로 실행하고 싶다면 아래 명령어로 Watch 모드에서 테스트를 돌릴 수 있다.

$ npm run test:watch

 

이 명령어를 실행하면, 파일이 변경될 때마다 자동으로 테스트가 실행되며, 예를 들어 movies.service.spec.ts 파일이 테스트를 수행하게 된다.

유닛 테스트와 E2E 테스트

Nest.js에서 두 가지 주요 테스팅 방법이 있다. 바로 유닛 테스트E2E 테스트이다.

//movie.service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { Movie } from './entities/movie.entity';
import { CreateMovieDto } from './dto/create-movie.dto';
import { UpdateMovieDto } from './dto/update-movie.dto';

@Injectable()
export class MoviesService {
    private movies: Movie[] = [];

    getAll(): Movie[] {
        return this.movies;
    }

    getOne(id:number): Movie {
        const movie = this.movies.find(movie => movie.id === id);
        if(!movie) {
            throw new NotFoundException(`Movie with ID ${id} not found`)
        }
        
        return movie;
    }

    delete(id: number) {
        this.getOne(id)
        this.movies = this.movies.filter(movie => movie.id !== id);
    }

    create(movieData: CreateMovieDto){
        this.movies.push({
            id: this.movies.length + 1,
            ...movieData
        })
    }

    update(id: number, updateData: UpdateMovieDto) {
        const movie = this.getOne(id);
        this.delete(id);
        this.movies.push({...movie, ...updateData })
    }
}

 

유닛 테스트는 각 함수나 모듈을 개별적으로 테스트하는 방식이다. 예를 들어, getAll() 함수와 getOne() 함수를 개별적으로 테스트하고 싶을 때 유닛 테스트를 사용한다. 이 방식은 개별 함수가 기대한 대로 동작하는지 확인하는 데 초점을 맞춘다.

 

E2E 테스트는 시스템 전체를 통합적으로 테스트하는 방식이다. 이는 실제 사용자가 서비스를 이용할 때의 흐름을 테스트하는 것으로, 예를 들어 유저가 특정 링크를 클릭했을 때 기대한 페이지가 나오는지 확인하는 식이다. 유저의 관점에서 전체 시스템의 동작을 검증하는 것이 목표이다.

 

유닛 테스트는 개별 기능에 집중하고, E2E 테스트는 시스템 전체가 제대로 작동하는지 확인하는 것이라 생각하면 된다.

 

참조: 노마드코더