[Django] - pytest

오동훈·2023년 2월 23일
0

Django

목록 보기
21/23

1. 설치

pytest-django를 설치하면 자동적으로 pytest도 같이 설치됩니다.

pip install pytest-django

2. pytest 설정

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

3. Testcode 작성 방법

1. mock 데이터

단위 테스트는 의존성을 최대한 낮춰서 작성해줘야 한다. 따라서 다른 테스트 코드를 이용해 모델을 생성하는 것이 아니라 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 데이터는 필요한 테스트 부분에 파라미터로 넣어주면 사용 가능합니다.

2. model test

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"

3. view test

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"

4. task test

task 부분은 별도의 url로 연결되어 있지 않기 때문에 함수 호출하듯이 불러 검증해주면 됩니다.

4. Test 실행 방법

1. test 실행

실행 방법은 되게 간단합니다.

pytest

pytest -v (자세히 보고 싶을 때)

pytest 명령어 옵션이 더 궁금하다면 다음 블로그를 참고해주세요!

2. coverage 확인

우선 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 개선

profile
삽질의 기록들🐥

0개의 댓글