• Django 유닛 테스트 with Pytest #1

    2021. 7. 5.

    by. Jacob Lee

    728x90

     


     

    시작하기 앞서, 왜 Unittest를 안 사용하고 Pytest를 사용해서 테스트 코드를 짜는지, Pytest는 무엇인지가 궁금하다면, 이 전에 포스트했던 Pytest vs. Unittest 글을 확인해보시면 좋을 것 같다.

     

    Tutorial #1

     

    가상환경 구축

    # 가상환경 생성
    python3 -m venv venv
    
    # 가성환경 활성화
    source venv/bin/activate

     

    장고 설치 & 프로젝트 시작

    # 장고 설치
    pip install django
    
    # 장고 프로젝트 생성
    django-admin startproject core .
    
    # 생성된 파일들
    ❯ ls
    core  manage.py  venv

     

    장고 앱 생성

    # 프로젝트로 이동
    cd core
    
    # 앱 생성
    django-admin startapp app1

     

    앱 추가 & 테스트 폴더 생성

    앱 생성시 tests.py 파일이 자동으로 생성되기는 하지만 app1과 프로젝트 레벨에 tests 폴더를 추가하자.

    # settings.py
    
    INSTALLED_APPS = [
        ...
        'core.app1',
    ]
    
    # pytest > core > app1
    # apps.py
    from django.apps import AppConfig
    
    
    class App1Config(AppConfig):
        name = 'core.app1'
    
    # pytest
    mkdir tests
    
    # pytest > core > app1
    mkdir tests

     

    Pytest 설치

    기본 Pytest 프레임워크도 있지만 Django를 위한 pytest-django를 설치하자.

    # Pytest
    pip install pytest-django

     

    Pytest 환경 설정하기

    Pytest 환경 설정을 위해 프로젝트 루트에 pytest.ini라는 파일을 다음과 같이 만들어 준다.

    # pytest
    vi pytest.ini
    
    # pytest.ini
    [pytest]
    DJANGO_SETTINGS_MODULE = core.settings
    # test_로 시작하는 모든 테스트 실행
    python_files = test_*.py

     

    테스트 작성

    pytest 디렉토리 안 tests 폴더에 샘플 테스트를 추가 해보자.

    # test_ex1.py
    import pytest
    
    def test_example():
        assert 1 ==1

     

    테스트 실행

    프로젝트 루트 디렉토리에서 테스트를 실행하자.

    위와 같이 테스트가 잘 실행됬음을 확인할 수 있다.

    pytest를 실행하면 테스트가 실행되고, 몇 가지의 테스트가 얼마나 걸려 통과했는지를 확인할 수 있다.

    중간에 경로 옆에 초록점이 통과한 테스트를 뜻한다. 지금은 한 개의 테스트지만 100개의 테스트가 있을 때 모두 통과했다고 가정하면 초록점은 100개가 되는 것이다.

     

    실패 테스트 작성

    import pytest
    
    def test_example():
        assert 1 == 1 
    
    def test_failed_example():
        assert 1 == 2

     

    실패 테스트 실행

    성공했을 때와는 다르게 실패시 F라는 문자가 경로 옆에 나타난다.

    또한 몇 개가 성공하고 몇 개가 실패했는지, 어디서 에러가 발생했는지, 무슨 에러인지를 알려준다.

     

     

    테스트 Assertion

    Image from Very Academy

     

    테스트 실패시 멈추기

    만약 어떤 테스트가 실패했다는 것을 인지하고 테스트를 끝내고 싶다면 pytest -x 명령어를 사용하면 된다.

    import pytest
    
    def test_example():
        assert 1 == 2 
    
    def test_failed_example():
        assert 1 == 2

     

    추가 출력하기

    만약 테스트 코드 결과 외에 추가적으로 출력하고 싶은게 있다면?  pytest -rP 명령어를 사용하면 된다.

    import pytest
    
    def test_example():
        print("무야호")
        assert 1 == 1 
    
    def test_example1():
        assert 1 == 1

     

    특정 테스트 실행

    Pytest에서는 특정 폴더 테스트, 특정 파일의 특정 유닛을 테스트 할 수 있다.

    # 모든 디렉토리 (프로젝트 루트 이하 모든 tests 디렉토리)
    > pytest tests
    
    # 특정 디렉토리 (pytest > core)
    > pytest core
    
    # 특정 파일의 함수
    > pytest tests/test_ex1.py::test_example1

     

    특정 테스트 스킵

    @pytest.mark.skip 헬퍼를 이용해 특정 테스트를 스킵할 수도 있다.

    import pytest
    
    @pytest.mark.skip
    def test_example():
        assert 1 == 1 
    
    def test_example1():
        assert 1 == 1

     

    특정 실패 예상되는 테스트 실패하기

    테스트 중 이 테스트는 실패할 것이라고 예상 되는 테스트에는 @pytest.mark.xfail을 사용할 수 있다.

    import pytest
    
    @pytest.mark.xfail
    def test_example():
        assert 1 == 1 
    
    def test_example1():
        assert 1 == 1

     

    커스텀 마커 추가하기

    위에서 사용했던 pytest가 제공하는 markers 말고도 커스텀으로 마커를 추가하는 것이 가능하다.

    makers라는 변수 안에 이름을 지정하고 :다음에 무슨 역할을 하는지 적어주며 된다.

    pytest -m "slow" 명령어를 사용해서 slow 마커스를 가지고 있는 함수만 테스트 한다.

    # pytest_ini
    [pytest]
    DJANGO_SETTINGS_MODULE = core.settings
    python_files = test_*.py
    
    markers =
        slow: slow running test
        
    # test_ex1.py
    import pytest
    
    @pytest.mark.slow
    def test_example():
        assert 1 == 1 
    
    def test_example1():
        assert 1 == 1

     

    Reference

     

    728x90

    댓글