본문 바로가기

개발/NestJS

Github Action + NestJS e2e 테스트 환경 구성

개요


인턴십 기간 동안, 사내 프로젝트 개발에 참여하며 서비스 안정화를 위해 테스트 코드를 작성했습니다.

 

특히 애플리케이션의 비즈니스 로직을 담당하는 서비스 레이어에 대해서는 시스템 간 상호작용을 직접 확인하기 위해 통합 테스트를 작성했습니다.

 

보다 더 안정화된 서비스를 위해, main 브랜치에 push 될 때 자동으로 테스트를 실행하는 워크플로우를 추가해 보겠습니다.

 

 

 

Continuous Integration(CI) 파이프라인


name: Run Tests

on:
  push:
    branches:
      - main

jobs:
  container-job:
    runs-on: ubuntu-latest
    container: node:20

    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: root
          POSTGRES_USER: postgres
          POSTGRES_DB: icon-app
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5


    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Install dependencies
        run: npm install --prefix $GITHUB_WORKSPACE/backend

      - name: Run tests
        run: |
          cd backend
          yarn test:ci

 

간략하게 github action의 동작과정을 설명해보겠습니다.

 

프로젝트의 루트 디렉토리 내 .github/workflows/ 폴더에 deploy.yml과 같은 YAML 파일을 작성해 둡니다.

 

이 파일에는 워크플로우와 관련된 정보가 기입되며, 코드 푸시, PR 생성과 같은 해당 워크플로우가 트리거될 조건과 실행될 작업(job)들이 정의됩니다.

 

GitHub Actions 서버는 저장소에 정의된 워크플로우 파일을 읽어, 설정된 트리거 조건에 맞춰 자동으로 이를 실행하게 됩니다.

 

그래서 위 코드에서 작성한 워크플로우의 동작 과정을 순서로 설명하자면 아래의 순서로 진행됩니다.

 

1. CI 서버에서 postgres, node를 도커로 설치

2. repository의 코드 내려받기

3. 프로젝트 관련 의존성을 설치

4. 테스트 실행

 

 

 

트리거 조건


on:
  push:
    branches:
      - main

 

트리거 조건은 main 브랜치에 push가 될때로 설정했습니다.

 

조건은 push 뿐만아니라 pull_request, schedule, issues 등 여러 조건으로 설정할 수 있습니다.

on:
  pull_request:
    branches:
      - main

on:
  schedule:
    - cron: '0 0 * * 1'

on:
  issues:
    types: [opened, edited]

 

 

 

CI 서버에서 postgres를 도커로 설치


  container-job:
    runs-on: ubuntu-latest
    container: node:20

 

runs-on: ubuntu-latest는 작업이 Ubuntu 가상 머신에서 실행됨을 의미합니다.

 

Nest를 테스트 하기 때문에, node:20 이미지를 도커 컨테이너로 생성합니다.

 

services:
  postgres:
    image: postgres:16
    env:
      POSTGRES_PASSWORD: root
      POSTGRES_USER: postgres
      POSTGRES_DB: icon-app
    options: >-
      --health-cmd pg_isready
      --health-interval 10s
      --health-timeout 5s
      --health-retries 5

 

Github Action에서 services 키워드는 워크플로에서 작업의 일부인 서비스 컨테이너를 만들 수 있습니다.

 

이를 이용해 postgres 이미지를 받아와서 connection 관련 정보를 env 아래에 넣어준 뒤, 동작을 테스트합니다.

 

 

 

repository의 코드 내려받기


steps:
  - name: Checkout repository
    uses: actions/checkout@v3

 

name은 Github Action GUI에서 표기할 작업의 이름이고, uses는 GitHub Marketplace에서 제공되는 액션 또는 직접 작성한 액션을 호출할 때 사용됩니다.

 

이 액션은 보통 코드 체크아웃, 빌드, 테스트, 배포 등을 수행할 때 사용됩니다.

 

저는 테스트 하기 위한 코드 체크아웃을 위해 사용했습니다.

 

 

 

 

프로젝트 관련 의존성을 설치


  - name: Install dependencies
    run: npm install --prefix $GITHUB_WORKSPACE/backend

 

run은 CLI에서 실행될 명령어를 정의할 때 사용됩니다.

 

--prefix $GITHUB_WORKSPACE를 이용해 명령어가 실행될 경로를 잡아준 뒤 npm install로 의존성을 설치했습니다.

 

 

 

테스트 실행


  - name: Run tests
    run: |
      cd backend
      yarn test:ci

 

yarn test 명령어로 테스트를 실행합니다.

 

Github Aciton에서 실행되는 모든 job은 모두 독립되어 실행되기 때문에 의존성을 설치하는 job에서 이동한 경로가 test 실행 job에서는 유지되지 않습니다.

 

그렇기 때문에 다시 테스트를 실행하는 경로로 이동해서 명령어를 입력합니다.

 

 

 

Github Action 실행 결과


 

 

 

결론


Github Action을 이용해 CI 파이프라인을 구축해 보았습니다.

 

이번 게시글에서 적용한 기능들 이외에도 테스트 성공 실패 여부를 slack 알림 기능으로 보내는 것과 같은 유용한 기능들을 Github Aciton에서 제공합니다.

 

해당 기능들을 포함하여 차차 파이프라인을 개선해나가서, 보다 안정적인 서비스를 개발할 수 있도록 해야겠습니다.

 

 

 

References

https://docs.github.com/ko/actions/use-cases-and-examples/using-containerized-services/about-service-containers

'개발 > NestJS' 카테고리의 다른 글

[Node.js] worker thread를 이용한 CPU bound 작업 병렬 처리  (0) 2024.10.12