Django Web Framework/Django Pytest

[udemy] Real World Python Test Automation with Pytest 학습

bluebamus 2023. 4. 14.

강좌 정보 : https://www.udemy.com/course/pytest-course/

 

* 이 포스팅에서는 "[very academy] Pytest Mastery with Django"에 언급된 내용을 제외하고 처음으로 언급되는 방법들에 대해서만 기록을 한다.

- 참고 포스팅 : https://devspoon.tistory.com/82

 

[very academy] Pytest Mastery with Django

import pytest # 테스트를 패스함 @pytest.mark.skip def test_example(): print("mark skip!!!") assert 1 == 1 # 현재는 실패하는 것이 정상으로 앞으로 개발, 개선될 코드임 # 결과 : ===== * passed, 1 xpassed ===== @pytest.mark.xfai

devspoon.tistory.com

 

chapter 2-2 markers

- pytest.mark.skipif() : 

- 사용 방안 : 일반적으로 관련이 없거나 현재 환경에서 실행할 수 없기 때문에 테스트를 건너뛰거나 전혀 실행하지 않아야 함을 나타낼ㄸ skip을 사용하며 skpif는 특정 조건하에 스킵을 유도시킬 수 있다.

- 'skip'은 일반적으로 테스트를 실행할 수 없을 때 사용된다.

# 1번 방법
@pytest.mark.skipif(4 > 1, reason="Skipped becasuse 4>1")
def test_should_be_skipped_if() -> None:
   assert 1==1

# 2번 방법
number = 4

@pytest.mark.skipif(number > 1, reason="Skipped becasuse 4>1")
def test_should_be_skipped_if() -> None:
   assert 1==1

 

- pytest.mark.xfail

- 사용 방안 : xfail은 테스트가 실패하거나 오류가 발생할 것으로 예상되지만 테스트 중인 코드의 동작을 확인하기 위해 실행할 가치가 있음을 나타내는 데 사용된다.

- 'xfail'은 테스트가 실패하거나 예상대로 작동하지 않는 것으로 알려져 있지만 코드의 동작을 확인하기 위해 실행해야 할 때 사용된다.

@pytest.mark.xfail
def test_dont_care_if_fails() -> None:
   assert 1==2

 

- custom marker : pytest.mark.{marker name} (ex: pytest.mark.slow)

- 그룹을 만들어 특정 조건하에 그룹들만 실행 시키고자 할때 사용할 수 있다.

- 이 방법을 사용하기 위해서 pytest.ini에 명시하거나 실행 명령어의 옵션에 명시해야 한다.

@pytest.mark.slow
def test_with_custom_mark1() -> None:
   pass

 

chapter 2-3 Fixtures, Parametrize

- fixture로 파라미터 값 받기

@pytest.fixture
def company() -> Company:
   return Company(name="Fiver", stock_symbol="SVRR")
   
def test_with_fixture(company: Company) -> None:
   print(f"Printing {company} from fixture")

 

- pytest.mark.parametrize로 파라미터 값 받기

@pytest.mark.parametrize("company_name",["TikTok", "Instagram", "Twitch"],)
def test_parametrized(company_name) -> None:
   print(f"\nTest with {company_name}")

 

- 예외처리를 이용한 파라미터 값 받기

def raise_covid19_esception() -> None:
   raise ValueError("CoronaVirus Esception")
   
def test_raise_covid19_exception_should_pass() -> None:
   with pytest.raises(ValueError) as e:
      raise_covid19_esception()
   assert "CoronaVirus Exception" == str(e.value)

 

- caplog를 사용한 logging 방법

- pytest에서 logging을 사용해 레벨에 따른 로깅 출력을 제어할 수 있다.

- 표준 pytest caplog 픽스처를 사용하여 로그 메시지를 캡처한 다음 로깅 수준을 포함하여 내용을 어설션할 수 있다.

- 실행시 -k "logged" 를 입력해준다. 여기서 logged는 log 테스트만 하기 위한, 함수 이름에 대한 패턴이다.

def test_example(caplog):
    # Perform some action that generates log messages, e.g. calling a function
    my_function()

    # Assert that there is at least one warning-level log message
    warning_messages = [msg for msg in caplog.record_tuples if msg[1] == logging.WARNING]
    assert len(warning_messages) >= 1
# 예외처리를 로깅하는 방법
import logging

logger = logging.getLogger("CORONA_LOGS")

def function_that_logs_something() -> None:
	try:
		raise ValueError("CoronaVirus Exception")
  	except ValueError as e:
    	logger.warning(f"I am logging {str(e)}")
        
def test_logged_warning_level(caplog) -> None:
	function_that_logs_something()
    assert "I am logging CoronaVirus Exception" in caplog.text
# 기본 적인 로깅 방법

def test_logged_info_level(caplog) -> None:
	with caplog.at_level(logging.INFO):
    	logger.info("I am logging info level")
        assert "I am logging info level" in caplog.text

chapter 6-6 실행 방법

- 파일 단위 : pytest -v -s --durations=0 {file name}

- 상대경로 : pytest -v -s --durations=0 {path name}

- 키워드 : pytest -v -s --durations=0 -k "create"

- 특정 파일의 class 단위 : pytest -v -s --durations=0 -k {file name}::{class name}

   - 특정 파일의 class의 특정 함수 :  pytest -v -s --durations=0 -k {file name}::{class name}::{{function name}}

- 마커 : pytest -v -s --durations=0 -m xfail

 

chapter 6-8 pytest refactoring 

- 챕터 제목은 의미가 없다. django 자체 testcode를 pytest로 전환하는 과정이다.

- pytestmark :

   - pytest 모듈 또는 conftest 파일의 전역 수준에서 pytestmark를 정의하면 해당 모듈 또는 파일 내의 모든 테스트 기능을 지정된 pytest 마커로 표시하는 데 사용할 수 있습니다.
   - 예를 들어 테스트 모듈 또는 conftest 파일의 맨 위에 pytestmark = pytest.mark.webtest를 정의하면 해당 모듈 또는 파일에 정의된 모든 테스트 함수가 webtest 마커로 표시됩니다. 이는 'webtest' 마커를 각각의 개별 테스트 기능에 적용할 필요가 없다는 것을 의미합니다. 모든 테스트 기능에 자동으로 적용되기 때문입니다.
   - 이는 마커를 각 테스트 함수에 개별적으로 적용하는 수고를 덜기 때문에 모두 특정 마커를 적용해야 하는 많은 수의 테스트 함수가 있는 경우 유용할 수 있습니다. 또한 webtest 마커가 필요한 모든 테스트 기능이 자동으로 적용되므로 테스트 스위트의 일관성을 보장합니다.

chapter 17-1 Server Agnostic API Testing with requests library 

- requests : https://requests.readthedocs.io/en/latest/

 

Requests: HTTP for Humans™ — Requests 2.28.2 documentation

Requests: HTTP for Humans™ Release v2.28.2. (Installation) Requests is an elegant and simple HTTP library for Python, built for human beings. Behold, the power of Requests: >>> r = requests.get('https://api.github.com/user', auth=('user', 'pass')) >>> r.

requests.readthedocs.io

- 사용 방법

import requests

def test_zero_companies_django_agnostic() -> None:
	response = requests.get(url="http://127.0.0.1:8000/companies"
    assert response.status_code == 200
    assert json.loads(response.content) == []
    
def test_create_company_with_layoffs_django_agnostic() -> None:
	response = requests.post(
    	url="http://127.0.0.1:8000/companies",
        json={"name": "test company name", "status": "Layoffs"},
        )
        assert response.status_code == 201
        response_content = json.loads(response.content)
        assert response_content.get("status") == "Layoffs"
        
        cleanup_company(company_id=response_content["id"])
        
def cleanup_company(company_id: str) -> None:
	response = requests.delete(url=f"http://127.0.0.1:8000/companies/{company_id}")
    assert response.status_code == 204

 

chapter 17-3 Server Agnostic API Testing with requests library 

- responses : https://github.com/getsentry/responses

 

GitHub - getsentry/responses: A utility for mocking out the Python Requests library.

A utility for mocking out the Python Requests library. - GitHub - getsentry/responses: A utility for mocking out the Python Requests library.

github.com

- 사용 방법 :

import responses

@pytest.mark.crypto
@responses.activate
def test_mocked_dogecoin_api() -> None:
    responses.add(
        method=responses.GET,
        url="https://api.cryptonator.com/api/ticker/doge-usd",
        json={
            "ticker": {
                "base": "EDEN",
                "target": "EDEN-USD",
                "price": "0.04535907",
                "volume": "4975940509.75870037",
                "change": "-0.00052372",
            },
            "timestamp": 1612515303,
            "success": True,
            "error": "",
        },
        status=200,
    )

    assert process_crypto() == 29

chapter 18-1 Allure Report Tool

- 설치 : pip install allure-pytest

- 사용 목적 : html 기반의 보고서를 만들어 준다.

- 사용 방법 : 

   -  Allure-Pytest-Official-Documentation : https://docs.qameta.io/allure/#_pytest
   - Allure-Server-Install-CLI-Official-Documentation : https://docs.qameta.io/allure/#_installing_a_commandline
   - Allure-Official-Documentation : https://docs.qameta.io/allure/

 

chapter 19-1 Cool Plugins For pytest

- 설치 : pip install pytest-sugar

- 사용 목적 : 터미널 상의  결과를 보기 쉽게 만들어 준다 (컬러 출력, 진행률 포시줄, 테스트 통계, 테스트 시간 등)

- 사용 방법 :

https://github.com/Teemu/pytest-sugar/

 

GitHub - Teemu/pytest-sugar: a plugin for py.test that changes the default look and feel of py.test (e.g. progressbar, show test

a plugin for py.test that changes the default look and feel of py.test (e.g. progressbar, show tests that fail instantly) - GitHub - Teemu/pytest-sugar: a plugin for py.test that changes the defaul...

github.com

 

chapter 20-1 Python Mocking Theory

- 설치 : pip install pytest-mock

- 사용 목적 : 단위 테스트에서 모의 ​​개체를 만들고 사용하는 방법을 제공하는 라이브러리

- 해당 항목은 추가 학습이 요구되기 때문에 다른 포스팅에서 다루기로 함

https://devspoon.tistory.com/86

 

pytest-mock의 사용법

1. 기본 사용 방법: 1.1 설치 방법 - 설치 : pip install pytest-mock 1.2 간단한 코드 사용법 - mock으로 사용할 target 함수 정의 tests/file.py def target_mock(): return "mock : True" - mock을 사용할 코드 정의 # tests/test_mo

devspoon.tistory.com

 

 

reference : 

https://www.notion.so/Step-9-Allure-Report-6e541b8277284547bf99c76741caec6d

 

Step 9. Allure Report

이전 챕터의 내용을 하나씩 하나씩 정리를했으면, 이제 당신은 간단한 Ui테스트 구조적인 방식에 대해서 알게 되었고, 이제는 이것의 결과물을 예쁘게 만드는 일만 남았다.

www.notion.so

https://velog.io/@tkjung/TDD-Pytest-Allure-Report-%ED%99%9C%EC%9A%A9

 

TDD - Pytest Allure Report 활용

Pytest와 Allure Framework 결합

velog.io

https://www.daleseo.com/python-unittest-mock/

 

[파이썬] 테스트 모킹 - unittest.mock

Engineering Blog by Dale Seo

www.daleseo.com

https://www.daleseo.com/python-unittest-mock-patch/

 

[파이썬] 테스트 모킹 - patch

Engineering Blog by Dale Seo

www.daleseo.com

https://code13.tistory.com/256

 

[Python] How to use pytest & mock & fixture

pytest & mock & fixture 1. pytest python 으로 개발하면서 코드 단위가 커지면 자연스레 테스트방법을 찾게 되는데 unittest와 pytest를 검색하게 된다. 그 중 별 이슈가 없는 한 pytest 를 선택하게 되는데.. 쉽

code13.tistory.com

https://velog.io/@jinukix/UnitTest-Mocking-setUpData-vs-setUp

 

UnitTest - Mocking, patch

unit test를 진행할 때 외부 API에 의존하는 부분을 임의이 데이터로 대체하는 방법입니다.MagicMock()이나 patch()를 사용합니다.@patch() : 괄호 안의 값을 바꿔치기함특정 범위 내에서만 mocking이 가능하

velog.io

https://rumbarum.github.io/posts/pytest/pytest-mock/

 

pytest-mock sample들 - 개발세발개발

required pip install pytest pytest-mock pytest의 플러그인인 pytest-mock을 통해 mocking을 해보도록 하겠습니다. 폴더구조와 구성은 다음 과 같습니다. class SomethingExport: val1 = 1000 val2 = 1000 val3 = 1000 def val(self): re

rumbarum.github.io

https://medium.com/oheadline/%EC%98%A4%EB%8A%98%EC%9D%98-%ED%97%A4%EB%93%9C%EB%9D%BC%EC%9D%B8-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1%EA%B8%B0-2-mock-45ca0f239b08

 

[오늘의 헤드라인] 테스트 코드 작성기(2) — Mock

안녕하세요. 오늘의 헤드라인 서버팀의 소프트웨어 엔지니어 Jun입니다. 오늘의 헤드라인에서 ‘python 기반 테스트 코드를 작성한 과정과 고민’을 2편을 공유하고자 합니다.

medium.com

https://libertegrace.tistory.com/entry/TDD-Python-Testing-Framework2-Pytest-Unittest-mocking

 

[TDD] Python Testing Framework2 - Pytest, Unittest - mocking

1. Mock mocking이 필요한 경우를 예시로 들고, 해당 mocking을 Unittest로 구현할 때와 Pytest로 구현할 때를 나누어서 살펴보겠습니다. 1) Random result mocking import random import requests def roll_dice(); print("rolling...

libertegrace.tistory.com

https://cocook.tistory.com/179

 

[pytest] Trouble Shooting

1. 여러개의 데이터베이스를 사용할 때 프로덕트에서 부하 부담의 이유로 replica 데이터베이스를 사용하고 있고 테스트 데이터 베이스를 따로 사용하고 있다면 제대로 테스트가 돌아가지 않을

cocook.tistory.com

https://www.slideshare.net/genycho/pytest-240931546

 

기본적인 테스트에 대한 pytest 자동화 접근

반복적이고 기본적인 테스트 항목에 대해 pytest를 이용하여 자동화 적용하고, 테스트 결과/커버리지 결과 등을 활용하기 위한 자료. 품질팀과 개발팀간의 협업 프로세스

www.slideshare.net

 

댓글