Skip to content

CI 에서 DB Test를 위한 환경 셋업

joohongpark edited this page Dec 28, 2022 · 3 revisions

목표

GitHub Actions에 RDB (MariaDB)를 구동시켜 테스트 환경 설정

1. GitHub Actions 상에서 DB 인스턴스 구동

https://docs.github.com/en/actions/using-containerized-services/about-service-containers GitHub Docs에 따르면 GitHub Actions 상에서 Docker Hub 상에 배포되는 도커 이미지를 구동시킬 수 있다고 합니다.

도커 컨테이너는 job 단위로 구동되며 일반적으로는 리눅스 os 상에서 구동하여야 한다고 합니다.

구동 방법은 두가지가 있습니다.

  • job 자체를 도커 인스턴스 내에서 구동
  • job과는 별개로 도커 인스턴스를 띄워서 구동

현재 프로젝트에선 굳이 도커 인스턴스 내에서 job을 구동시킬 필요가 없으므로 도커 인스턴스를 띄워서 구동하는 방법을 선택했습니다.

1.1 YAML 설정

jobs:
  backend-CI:
    runs-on: ubuntu-latest
    services:
      mariadb:
        image: mariadb
        env:
          MARIADB_DATABASE: test_db
          MARIADB_USER: test_user
          MARIADB_PASSWORD: test_password
          MARIADB_ROOT_PASSWORD: test_password
        ports:
          - 3306:3306
        options: >-
          --health-cmd "mysqladmin ping -P 3306 -ptest_password | grep 'mysqld is alive' || exit 1"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

services 라는 키 값에 대해 다음과 같이 데이터를 삽입합니다.

  • image : 구동할 이미지
  • env : 환경변수
  • ports : 포트 export
  • options : 헬스체크 등을 위한 별도 파라미터

별도 옵션을 통해 인스턴스의 헬스체크를 실행할 수 있습니다. 인스턴스 생성 후 서버 생성시까지 시간 소요가 있으므로 헬스체크를 실행해야 합니다.

Docker에서 지원하는 헬스체크 옵션이 있으며 기존 헬스체크 파라미터에 health- 접두사를 붙여서 헬스체크를 합니다.

헬스체크 명령은 해당 이미지에서 지원하는 명령어를 사용하거나 별도로 구현해야 합니다.

1.2 DDL 및 샘플 데이터 삽입

DDL과 샘플 데이터가 마련된 sql 파일을 실행중인 도커 인스턴스에 삽입해야 합니다. 특정 시점부터 GutHub Actions의 우분투 인스턴스에서 mysql 클라이언트를 제공해 준다고 하기 때문에 기본으로 제공되는 mysql 클라이언트를 이용해 DDL과 데이터를 삽입합니다.

- name: DB에 샘플 데이터 삽입
  run: >-
    mysql --force
    --host="127.0.0.1"
    --port="3306"
    --database="test_db"
    --user="test_user"
    --password="test_password"
    < "backend/database/42cabi_v3_test.sql"

2. E2E 테스트를 위한 사전 설정

Nest.js에서 기본으로 제공해주는 E2E 설정을 그대로 사용하면 모듈을 import 하는 부분에서 모듈을 참조하지 못해 에러가 발생할 수 있습니다.

jest-e2e.json 설정에 다음 항목을 추가해 정상적으로 모듈을 가져올 수 있도록 경로를 설정합니다.

"moduleNameMapper": {
  "^src/(.*)$": "<rootDir>/../src/$1"
},

3. E2E 테스트 단계 설정

E2E 테스트를 수행하기 위한 단계를 추가합니다.

E2E 테스트에서만 필요한 환경 변수는 env 옵션을 사용해 다음과 같이 추가합니다.

- name: E2E 테스트
  env:
    HOST: localhost
    DB_USER: test_user
    DB_PORT: 3306
    DATABASE: test_db
    DB_PASSWORD: test_password
    ROOT_PASSWORD: test_password
    FORTYTWO_APP_ID: 1234
    FORTYTWO_APP_SECRET: 1234
    CALLBACK_URL: /auth/login/callback
    COOKIE_KEY: secret
    JWT_SECRETKEY: SecretKey
    JWT_ALGORITHM: HS256
    JWT_EXPIREIN: 28d
    JWT_ISSUER: 42cabi
    MAIL_SEND: false
    DEBUG_LOG: true
  run: npm run test:e2e --prefix backend

4. afterEach 를 이용해 실행중인 앱 종료시키기

E2E 테스트 케이스에 대해 afterEach 를 이용해 구동중인 앱을 종료시켜야 정상적으로 E2E 테스트가 종료가 됩니다.

describe('test', () => {
  let app: INestApplication;

  beforeEach(async () => {
    const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();

    app = moduleFixture.createNestApplication();
    await app.init();
  });

  it('/ (GET)', () => {
    return request(app.getHttpServer()).get('/').expect(404);
  });

  afterEach(async () => {
    await app.close();
  });
});
Clone this wiki locally