테스트의 중요성은 알고 있었으나, 팀 내 백엔드 개발자가 나 혼자라는 핑계로 계속해서 테스트 코드를 짜는 일을 미뤄왔었다. 그러다 디자이너가 당분간 부재하는 상황이 생겼고 이 기회에 최소한의 테스트라도 추가하고자 가장 빠르게 테스트를 도입할 방법을 고민해봤고, Django에서 제공하는 기본 test보다는 pytest를 사용하는 쪽이 더 나을 것이라고 판단하여 pytest를 도입하기로 결정하였다.
pytest 사용해본 결과 pytest는 테스트 실행 때마다 DB를 새로만드는 것이 아니라 기존에 settings에 설정된 DB_NAME에 test_라는 접두어를 붙여 새로운 DB를 생성한 이후 생성한 DB를 계속 사용하는 방식으로 테스트가 진행되어 django test보다 조금 더 빠르게 실행할 수 있다는 장점과 pytest-xdist pytest-cov 등의 플러그인 등을 통해 필요한 기능을 쉽게 사용할 수 있었다.
내가 적용한 Django 프로젝트는 대략 이러한 환경에서 구동 중이다.
회사 프로젝트
- python==3.5
- django==1.11
- djangorestframework==3.7.7
개인 프로젝트
- python==3.6
- django==2.0
- djangorestframework==3.7.3
pytest
기존 django 프로젝트 환경에서 pytest를 사용하려면 pytest-django를 설치해주고 조금의 설정만 하면 된다.
설치
$ pip3 install pytest-django
설정
설치가 끝났다면 manage.py가 있는 디렉토리에 pytest.ini를 만들고 설정을 추가하면 된다.
첫 줄의 DJANGO_SETTING_MODULE을 통해 django 프로젝트의 settings파일과 연결시켜준다.
norecursedirs= 에는 테스트할 필요가 없는 파일들을 추가시켜주면 된다.
실행
pytest를 실행시키면 test_라는 접두어가 붙은 모든 파일을 실행시킨다.
$ python -m pytest
테스트 커버리지
pytest에서는 pytest-cov라는 플러그인을 통해 간단하게 테스트 커버리지를 알 수 있다.
설치는 간단하게 pip를 사용하면 된다.
$ pip3 install pytest-cov
설치 이후에 pytest를 실행할 때 명령어에 –cov를 추가해주기만 하면 된다.
$ python -m pytest --cov=.
. 는 현재 디렉토리를 말한다.
결과는 아래 그림처럼 출력된다.
위 결과를 보면 migrations 등이 테스트 커버리지에서 빠져있는데 .coveragerc 라는 파일을 pytest.ini와 동일한 디렉토리에 만든 다음 아래 처럼 설정했다.
테스트 병렬 실행
실행해야할 테스트가 많아지면 실행 시간이 많이 필요해진다. 이럴 때에 고려할 수 있는 것이 병렬 실행이다. pytest에서는 병렬 실행도 pytest-xdist를 통해 간단하게 해결 가능하다.
$ pip3 install pytest-xdist
pytest-xdist 설치 후 실행할 때
$ python -m pytest --cov=. -n 3
-n 3 처럼 동시에 실행하고 싶은 숫자를 입력해주면 자동으로 병렬 실행된다.
Travis CI
코드가 변경될 때마다 테스트를 실행해야하는 번거로움을 제거하고자 CI툴을 활용하였다. 그 중 Travis CI는 공개 저장소에 대해서는 무료로 사용이 가능하며, 설정이 매우 간단하다.
Travic CI (org)에 들어간 후 github 등 계정을 연결하고 해당 저장소에 권한을 부여해준 후 project 루트 디렉토리에 .travis.yml 파일을 추가해주기만 하면된다.
위처럼 설정하면 푸시할 때마다 script에 해당하는 부분이 실행되고 테스트 성공 여부를 알려준다.