pytest-django
를 설치하면 자동적으로 pytest
도 같이 설치됩니다.
pip install pytest-django
DJANGO_SETTINGS_MODULE
환경 변수를 설정함으로써, 원하는 --settings=yourproject.settings
옵션을 명시하는 것과 같이 dev, stg, prd 등을 설정할 수 있습니다.
추가적으로, test 로 시작하는 다른 파일이나 test로 끝나는 파일 등을 적용하기 위해서는 다음과 같이 추가해줍니다.
[pytest]
DJANGO_SETTINGS_MODULE = config.settings
python_files = test.py test_*.py *_tests.py
단위 테스트는 의존성을 최대한 낮춰서 작성해줘야 한다. 따라서 다른 테스트 코드를 이용해 모델을 생성하는 것이 아니라 mock 데이터를 만들어두고 해당 데이터를 이용해 테스트를 진행해주는 방식으로 해야합니다.
pytest에서는 mock를 다음과 같이 만들어 줄 수 있습니다.
import pytest
.
.
@pytest.fixture
def sample_user():
"""
User 생성 샘플 코드입니다.
"""
return User.objects.create(
user_id="odh0112",
name="오동훈",
email="odh0112@naver.com",
mdn="01085031575",
is_admin=True,
)
함수 상단에 @pytest.fixture
를 붙여주면 끝입니다! 여기서 fixture가 무엇이냐!
fixture란
- 시스템의 필수조건을 만족하는 테스팅 프로세스를 설정하는 것
- 같은 설정의 테스트를 쉽게 반복적으로 수행할 수 있도록 도와주는 것
간략하게 말하면 수행될 테스팅에 있어 필요한 부분들을 가지고 있는 코드 또는 리소스라고 말할 수 있습니다.
위에서 만든 mock 데이터는 필요한 테스트 부분에 파라미터로 넣어주면 사용 가능합니다.
pytest.mark.django_db
는 마커입니다. 해당 마커는 테스트 기능을 이용할 때 데이터베이스가 필요하다는 표시입니다. 따라서 model 테스트를 진행할 때는 해당 마커를 표시해주고 시작하면 됩니다.
import pytest
pytestmark = pytest.mark.django_db
def test_user_model_create_success():
"""
유저 모델 테스트 - 성공
"""
user = User.objects.create(
user_id="odh0112",
name="오동훈",
email="odh0112@naver.com",
mdn="01085031575",
is_admin=True,
)
assert user.user_id == "odh0112"
assert user.name == "오동훈"
assert user.email == "odh0112@naver.com"
1. post로 보내는 Case
def test_diagnose_success(client):
"""
검출 결과 전송 테스트 - 성공
"""
url = reverse("app명:url name명")
data = {
## 보낼 데이터 ##
}
response = client.post(path=url, data=data, content_type='application/json')
## 아래 부분은 각자가 설정한 케이스대로 테스트 진행해주면 됩니다. ##
assert response.status_code == 200
assert response.data["message"] == "OPERATION_SUCCESS"
2. get로 보내는 Case
파라미터에 있는 sample_download_info
는 mock 데이터입니다. mock 데이터로 만든 모델 정보를 파라미터로 받아 사용할 수 있습니다.
def test_version_success(client, sample_download_info):
"""
버전 확인 테스트 - 성공
"""
url = reverse("patternVersion")
response = client.get(path=url)
assert response.status_code == 200
3. pk값처럼 url 뒤에 값이 붙어야 하는 Case
kwargs
를 이용해 url 뒤의 설정한 이름과 값을 같이 넘겨주면 됩니다.
# 1. 넘기는 값이 1개 일 때 (url뒤의 값 이름을 pk로 설정해두었습니다.)
def test_coupon_get_detail_success(client, sample_coupon):
"""
쿠폰 상세 조회 테스트 - 성공
"""
url = reverse("coupon:couponDetail", kwargs={"pk": sample_coupon.id})
response = client.get(path=url)
assert response.status_code == 200
assert response.data["name"] == "정률 할인 basic test"
# 2. 넘기는 값이 2개 일 때 (url뒤의 값 이름을 pk, user_id로 설정해두었습니다.)
def test_coupon_does_not_exist_user_failure(client, sample_coupon):
"""
쿠폰 발급 실패 테스트 - 성공 (존재하지 않은 유저 Case)
"""
url = reverse("coupon:CouponIssue", kwargs={"pk": sample_coupon.id, "user_id": 10})
response = client.post(path=url)
assert response.data["status_code"] == 4004
assert response.data["message"] == "DOES_NOT_EXIST"
task 부분은 별도의 url로 연결되어 있지 않기 때문에 함수 호출하듯이 불러 검증해주면 됩니다.
실행 방법은 되게 간단합니다.
pytest
pytest -v (자세히 보고 싶을 때)
pytest 명령어 옵션이 더 궁금하다면 다음 블로그를 참고해주세요!
우선 coverage를 확인하기 위해서는 pytest-cov
를 설치해줍니다.
pip install pytest-cov
설치 후에 다음 명령어를 입력하면 테스트 커버리지를 확인할 수 있습니다.
pytest --cov={cov 확인할 폴더 or 앱 명}/ {cov를 test할 파일 or 폴더}/
pytest --cov=applications/ tests/
--cov-report term-missing
를 입력하면 코드에서 어느 부분이 테스트가 안되고 있는지 확인 가능합니다.
pytest --cov-report term-missing --cov=applications/ tests/
coverage report
를 사용하면 현재 커버리지를 확인할 수 있고,
coverage html
를 사용하면 현재 커버리지 기반으로 html 문서를 아래의 사진과 같이 만들어줍니다.
coverage report
coverage html
참고자료 📩
pytest 공식문서
pytest marker
pytest 명령어 옵션
Django Test 개선