pytest 테스트 내에서 로깅


90

일부 상태 변수를 검사하기 위해 테스트 함수 내에 몇 가지 로깅 문을 넣고 싶습니다.

다음 코드 스 니펫이 있습니다.

import pytest,os
import logging

logging.basicConfig(level=logging.DEBUG)
mylogger = logging.getLogger()

#############################################################################

def setup_module(module):
    ''' Setup for the entire module '''
    mylogger.info('Inside Setup')
    # Do the actual setup stuff here
    pass

def setup_function(func):
    ''' Setup for test functions '''
    if func == test_one:
        mylogger.info(' Hurray !!')

def test_one():
    ''' Test One '''
    mylogger.info('Inside Test 1')
    #assert 0 == 1
    pass

def test_two():
    ''' Test Two '''
    mylogger.info('Inside Test 2')
    pass

if __name__ == '__main__':
    mylogger.info(' About to start the tests ')
    pytest.main(args=[os.path.abspath(__file__)])
    mylogger.info(' Done executing the tests ')

다음 출력이 표시됩니다.

[bmaryada-mbp:/Users/bmaryada/dev/platform/main/proto/tests/tpch $]python minitest.py
INFO:root: About to start the tests 
======================================================== test session starts =========================================================
platform darwin -- Python 2.6.2 -- pytest-2.0.0
collected 2 items 

minitest.py ..

====================================================== 2 passed in 0.01 seconds ======================================================
INFO:root: Done executing the tests 

'__name__ == __main__'블록 의 로깅 메시지 만 콘솔로 전송됩니다.

pytest테스트 방법에서 콘솔로 로깅 을 강제 로 내보내는 방법이 있습니까?


3
py.test의 작성자가 게시 한이 답변을 볼 수 있습니다 . 그는 높은 수준의 다양성을 제공하는 pytest 플러그인을 제안합니다.
chb

답변:


30

나를 위해 작동합니다. 다음은 내가 얻은 출력입니다. [snip-> example was wrong]

편집 : -sstdout을 캡처하지 않도록 py.test에 옵션을 전달해야하는 것 같습니다 . 여기서 (py.test가 설치되지 않음) python pytest.py -s pyt.py.

코드에 필요한 것은 다음으로 전달 -s하는 args것입니다 main.

 pytest.main(args=['-s', os.path.abspath(__file__)])

출력 캡처 에 대한 py.test 문서를 참조하십시오 .


죄송합니다. 서둘러 코드를 붙여 넣었습니다. '문제'를 확인하려면 'test_one'함수에서 'assert 0 == 1'을 제거하십시오. 일부 실패가있을 때만 (내가 거짓 어설 션을 사용하여 강제) py.test는 로깅 정보를 인쇄하는 것 같습니다.
슈퍼 셀렉터

문제 없습니다. 프로그래밍 방식을 찾고 명령 줄에서 수정하는 방법을 찾았습니다.
TryPyPy 2011 년

1
기본 암시 적 stderr 대신 일부 파일로 로깅 출력을 리디렉션 할 수도 있습니다.
hpk42 2011 년

@superselector hpk42는 py.test 사람입니다. IIUC, 귀하의 코드에서는 logging.basicConfig(filename="somelog.txt", level=logging.DEBUG).
TryPyPy

115

버전 3.3부터는 pytest라이브 로깅을 지원하므로 테스트에서 생성 된 모든 로그 레코드가 즉시 터미널에 인쇄됩니다. 이 기능은 라이브 로그 섹션에 설명되어 있습니다. 라이브 로깅은 기본적으로 비활성화되어 있습니다. 활성화 log_cli = 1하려면 pytest.iniconfig 1 에서 설정하십시오 . 라이브 로깅은 터미널 및 파일로의 방출을 지원합니다. 관련 옵션을 사용하면 레코드를 사용자 정의 할 수 있습니다.

단말기:

  • log_cli_level
  • log_cli_format
  • log_cli_date_format

파일:

  • log_file
  • log_file_level
  • log_file_format
  • log_file_date_format

참고 : log_cli플래그는 명령 줄에서 전달할 수 없으며에서 설정 해야합니다pytest.ini . 다른 모든 옵션은 명령 줄에서 전달하거나 구성 파일에서 설정할 수 있습니다. 이 주석 에서 Kévin Barré 가 지적했듯이 명령 줄에서 ini 옵션을 재정의하는 것은 옵션을 통해 수행 할 수 있습니다 . 따라서에서 선언 하는 대신 다음을 호출 할 수 있습니다.-o/--overridelog_clipytest.ini

$ pytest -o log_cli=true ...

시연에 사용되는 간단한 테스트 파일 :

# test_spam.py

import logging

LOGGER = logging.getLogger(__name__)


def test_eggs():
    LOGGER.info('eggs info')
    LOGGER.warning('eggs warning')
    LOGGER.error('eggs error')
    LOGGER.critical('eggs critical')
    assert True

보시다시피 추가 구성이 필요하지 않습니다. 명령 줄에서 pytest지정 pytest.ini되거나 전달 된 옵션에 따라 로거를 자동으로 설정합니다 .

터미널, INFO레벨, 멋진 출력에 라이브 로깅

구성 pytest.ini:

[pytest]
log_cli = 1
log_cli_level = INFO
log_cli_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)
log_cli_date_format=%Y-%m-%d %H:%M:%S

테스트 실행 :

$ pytest test_spam.py
=============================== test session starts ================================
platform darwin -- Python 3.6.4, pytest-3.7.0, py-1.5.3, pluggy-0.7.1 -- /Users/hoefling/.virtualenvs/stackoverflow/bin/python3.6
cachedir: .pytest_cache
rootdir: /Users/hoefling/projects/private/stackoverflow/so-4673373, inifile: pytest.ini
collected 1 item

test_spam.py::test_eggs
---------------------------------- live log call -----------------------------------
2018-08-01 14:33:20 [    INFO] eggs info (test_spam.py:7)
2018-08-01 14:33:20 [ WARNING] eggs warning (test_spam.py:8)
2018-08-01 14:33:20 [   ERROR] eggs error (test_spam.py:9)
2018-08-01 14:33:20 [CRITICAL] eggs critical (test_spam.py:10)
PASSED                                                                        [100%]

============================= 1 passed in 0.01 seconds =============================

터미널 및 파일 만 메시지에 라이브 로깅 CRITICAL터미널, 공상 출력 레벨 pytest.log파일

구성 pytest.ini:

[pytest]
log_cli = 1
log_cli_level = CRITICAL
log_cli_format = %(message)s

log_file = pytest.log
log_file_level = DEBUG
log_file_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)
log_file_date_format=%Y-%m-%d %H:%M:%S

테스트 실행 :

$ pytest test_spam.py
=============================== test session starts ================================
platform darwin -- Python 3.6.4, pytest-3.7.0, py-1.5.3, pluggy-0.7.1 -- /Users/hoefling/.virtualenvs/stackoverflow/bin/python3.6
cachedir: .pytest_cache
rootdir: /Users/hoefling/projects/private/stackoverflow/so-4673373, inifile: pytest.ini
collected 1 item

test_spam.py::test_eggs
---------------------------------- live log call -----------------------------------
eggs critical
PASSED                                                                        [100%]

============================= 1 passed in 0.01 seconds =============================

$ cat pytest.log
2018-08-01 14:38:09 [    INFO] eggs info (test_spam.py:7)
2018-08-01 14:38:09 [ WARNING] eggs warning (test_spam.py:8)
2018-08-01 14:38:09 [   ERROR] eggs error (test_spam.py:9)
2018-08-01 14:38:09 [CRITICAL] eggs critical (test_spam.py:10)

1 섹션 pytest에서 setup.cfg에서 구성 할 수 있지만 [tool:pytest]사용자 지정 라이브 로깅 형식을 제공하려는 경우에는 그렇게하지 마십시오. 다른 도구 읽기 setup.cfg%(message)s문자열 보간과 같은 것을 처리 하고 실패 할 수 있습니다. pytest.ini오류를 방지하기 위해 사용 합니다.


17
pytest.ini에log_cli 있어야 하는 메모 에 대해서는-o 옵션을 사용 하여 명령 줄에서 값을 재정의 할 수있는 것 같습니다 . pytest -o log_cli=true --log-cli-level=DEBUG나를 위해 작동합니다.
Kévin Barré

@ KévinBarré 매우 좋은 의견과 일반적으로 매우 유용한 힌트, 감사합니다! 답변을 업데이트했습니다.
hoefling

이것은 로깅을 사용할 때 확실히 정답입니다. 테스트 내부에있는 로그와 별도로 고려해야하는 테스트 대상 시스템 내부에있는 로그를 구분하는 것을 좋아하지만 .
CMCDragonkai

@CMCDragonkai는 불행히도 pytest그 문제가 다소 제한적입니다. 그러나 이는 앱의 테스트를위한 특수 로깅 구성으로 가능해야합니다. 로거에서 전파를 끄고 지정된 파일에 기록하는 "테스트 핸들러"를 추가하십시오. 이렇게 pytest하면 사용자 지정 처리기가 SuT 로그를 처리하는 동안 테스트에서 오는 레코드 만 기록합니다.
hoefling 19

1
@OfekAgmon pytest출력 을 저장 하려면 --result-log인수를 사용할 수 있습니다 (사용 되지 않지만 여기에 대안이 있습니다 ). 그러나 pytest출력과 라이브 로깅 출력을 동일한 파일에 저장할 수는 없습니다 .
hoefling
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.