본문 바로가기

소프트웨어-이야기/테스트-자동화

(Gitlab CI) Gitlab에 테스트 CI 연동하기 - Django + Postgresql

배경

최근에 신규 프로젝트를 진행하면서, 코드의 구조를 변경하는 경우가 잦아졌다.

빠른 사이클로 기능을 구현하다보니, 회귀 테스트를 못하게 되는 경우가 빈번해졌다. 

그러면서 잘 동작하던 코드들이 고장나는 경우가 많아졌고, 디버깅으로 인한 삽질이 늘어나기 시작했다.

이런 고통의 루프에서 벗어나고자 gitlab ci으로 테스트빌드 자동화를 적용해보았다.

 

gitlab-ci 장점

짜잔 ㅎ_ㅎ

gitlab ci에 테스트 자동화를 적용하면, gitlab에 코드를 push할 때마다 자동으로 테스트코드를 돌려준다.

그리고 풀리퀘스트를 날릴 때에도 자동으로 돌려주고, 성공/실패여부도 자동으로 알려준다 😄

 

이해만 한다면, gitlab ci는 꽤 쉽다. 

 

gitlab ci 준비물

a. gitlab runner 

gitlab ci에 등록한 job을 실행해주고, 실행 결과를 gitlab proejct에 전달해주는 역할을 하는 프로그램이다. 

gitlab runner 설치와 등록은 Registering Runners 페이지를 참고하면 된다.  😃 

 

gitlab runner는 몇가지 executor가 있는데, 간단한 프로그램이 아니라면 docker executor를 사용하기를 권장한다. 

docker executor는 docker 환경에서 job을 실행한다.

이 덕분에 DB, Redis 등.. 애플케이션이 동작하기 위해 필요한 서버들을 가상으로 띄우기 편하다. 

2번째 line에 있는 executor가 내가 설정한 executor 타입인지 꼭 확인하자! ( shell executor으로 docker service 기능을 사용하다가 삽질했다 ㅠ )

 

b. 프로젝트에 gitlab ci job 등록하기

.gitlab-ci.yml 파일을 프로젝트 최상단 경로에 추가하면, 자동으로 gitlab ci가 등록된다.

그리고 이 job은 remote branch에 push 될때마다 실행된다.

 

Pytest Gitlab CI JOB Sample

image: python:3.6

stages:
  - test

variables:
  POSTGRES_DB: test_postgres_db
  POSTGRES_USER: test_postgres_user
  POSTGRES_PASSWORD: "test_postgres_password"

pytest:
  stage: test
  services:
    - postgres:12.1
  script:
    - export DATABASE_URL=postgres
    - PGPASSWORD=$POSTGRES_PASSWORD psql -h "postgres" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "SELECT 'OK' AS status;"
    - pip install -r requirements.txt
    - pip install -r requirements_dev.txt
    - cd myproject
    - python3 manage.py makemigrations --settings=myproject.settings.test
    - python3 manage.py migrate --settings=myproject.settings.test
    - pytest --junitxml=../pytest-results.xml
  artifacts:
    reports:
      junit: pytest-results.xml

1. images

기본으로 사용할 도커 이미지를 선언한다. 만약 gitlab registry를 사용하고 있다면, registry  주소를 선언해줘도 된다.

ex. image: registry.americano.com/group/starbucks:my-python

 

2. stages

gitlab ci에는 3가지 stages으로 구성되어있다.

위의 yml 파일은 아래의 내용을 포함하고 있다.

- test stage 단계를 사용할 것이고

- 임의로 만든 pytest라는 커맨드를 test stage 단계에서 실행할 것이다.

 

3. services

테스트 환경에서 사용할 도커 서비스들을 명시해두는 곳이다.

postgresql service를 사용하는 경우, POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD를 변수로 명시해두면,

자동으로 DB, USER, PASSWORD를 만들어준다. 

그래서 기본 테스트 데이터베이스 생성 및 권한 설정을 신경쓰지 않아도 된다.

 

그리고 service를 사용하여 테스트데이터베이스를 구성한 경우, 테스트 DB에는 postgresql이라는 주소를 통해서만 접근할 수 있다. 127.0.0.1 혹은 localhost으로 접근할 수 없다.

때문에 애플리케이션의 테스트 환경 셋팅 파일은 도커 환경의 DB 주소를 주입받을 수 있도록 설정되어있어야한다. 

import os
DATABASES = {
    "default": {
        "ENGINE" : "django.db.backends.postgresql_psycopg2",
        "NAME": os.getenv("POSTGRES_NAME","test_postgres_name"),
        "USER": os.getenv("POSTGRES_USER","test_postgres_user"),
        "PASSWORD": os.getenv("POSTGRES_PASSWORD","test_postgres_password"),
        "HOST": os.getenv("DATABASE_URL", "127.0.0.1"),
        "PORT" : '5432'
    }
}

로컬환경에서는 127.0.0.1으로 붙고, gitlab ci 환경에서는 DATABASE_URL 환경변수로 테스트 DB 경로를 주입받아야한다.

( 참고 - GitLab CI Django and Postgres )

 

<이 글에서 다루지 않은 세부사항>

- docker executor 모드로 docker runner 셋팅하기 

- junit 포맷으로 테스트 출력결과를 내보내는 이유 

- 파이썬 패키지 설치 시간 단축하는 방법 

- gitlab ci yml 샘플에서 갑자기 postgresql에 "SELECT 'OK' 를 날려본 이유 등.. 

 

<참고 자료>

PostgreSQL Sample Gitlab Project

 

Pipeline · GitLab-examples / postgres

GitLab.com

gitlab.com

Using PostgreSQL

 

Using PostgreSQL | GitLab

Using PostgreSQL As many applications depend on PostgreSQL as their database, you will eventually need it in order for your tests to run. Below you are guided how to do this with the Docker and Shell executors of GitLab Runner. Use PostgreSQL with the Dock

docs.gitlab.com

JUnit test reports

 

JUnit test reports | GitLab

GitLab Docs GitLab CI/CD JUnit test reports JUnit test reports JUnit test reports Introduced in GitLab 11.2. Requires GitLab Runner 11.2 and above. Overview It is very common that a CI/CD pipeline contains a test job that will verify your code. If the test

docs.gitlab.com