pytest를 실행하는 동안 생성 된 일반 인쇄 출력을 어떻게 볼 수 있습니까?


400

때로는 코드에 인쇄 문을 삽입하고 연습 할 때 인쇄되는 것을보고 싶습니다. 그것을 "운동"하는 나의 일반적인 방법은 기존의 pytest 테스트를하는 것입니다. 그러나 이것을 실행할 때 표준 출력을 볼 수없는 것 같습니다 (적어도 IDE의 PyCharm 내에서).

pytest 실행 중에 표준 출력을 보는 간단한 방법이 있습니까?


실패시에만 또는 항상?

17
-s 비활성화 당 테스트 캡처
hpk42

3
@delnan-항상보고 싶습니다
Des

답변:



51

에서 upvoted 주석 받는 허용 대답 , 묻는다 :

콘솔에 인쇄 할 수있는 방법이 있나요 는 JUnit을 보고서에 표시되도록 출력을 캡처은?

UNIX에서는 일반적으로 티잉 이라고합니다 . 이상적으로는 캡처하는 대신 티잉이 py.test 기본값이됩니다. 비공식적으로, py.test 또는 기존의 타사 py.test 플러그인 (... 아는, 어쨌든 )은 티잉을 지원합니다. 파이썬이 사소한 티 를 즉시 지원하지만 합니다.

원숭이 - 패치 할 py.test을 아무것도 지원되지 않는 비 간단하다. 왜? 때문에:

  • 대부분의 py.test 기능은 외부로 가져 오기 위한 것이 아닌 개인 _pytest패키지 뒤에 잠겨 있습니다. 일반적으로 수행중인 작업을 모르는 상태에서 이렇게하면 공용 패키지가 런타임시 모호한 예외를 발생시킵니다. 고마워요, py.test. 정말 견고한 아키텍처입니다.pytest
  • 당신이 경우에도 수행 에 민간 원숭이 패치 방법도 _pytest안전한 방식으로 API를, 당신은 그렇게해야 하기 전에 공중 실행 pytest외부에서 패키지 실행을 py.test명령. 당신은 할 수없는 플러그인에서이 작업을 수행 (예를 들어, 최상위 conftest테스트 스위트 모듈). py.test가 플러그인을 동적으로 가져 오기 시작할 때까지, 원숭이 패치를 원했던 py.test 클래스는 오랫동안 인스턴스화되어 왔으며 명령을 순서대로 하지 않습니다 해당 인스턴스에 액세스 . 이는 원숭이 패치를 의미있게 적용하려는 경우 더 이상 외부 명령을 안전하게 실행할 수 없음을 의미 합니다. 대신 사용자 정의 setuptools로 해당 명령의 실행을 래핑해야합니다. . py.testtest
    1. 개인 _pytestAPI를 원숭이가 패치합니다 .
    2. 명령 pytest.main()을 실행하기 위해 public 함수를 호출합니다 py.test.

이 답변은 py.test의 옵션 -s과 stdout이 아닌--capture=no stderr을 캡처하는 옵션을 패치 합니다. 기본적으로이 옵션은 stderr 또는 stdout을 캡처하지 않습니다. 물론 이것은 티잉이 아닙니다. 그러나 모든 위대한 여행은 모두가 5 년 안에 잊어 버리는 지루한 전편으로 시작됩니다.

왜 이렇게합니까? 나는 지금 당신에게 말할 것이다. py.test-driven 테스트 스위트에는 느린 기능 테스트가 포함되어 있습니다. 이러한 테스트의 표준을 표시하는 것은 도움이되고 안심이되며 또 다른 장기 실행 기능 테스트가 몇 주 동안 아무런 조치를 취하지 않을 때 leycec 에 도달 하지 못하게killall -9 py.test 합니다. 그러나 이러한 테스트의 stderr을 표시하면 py.test가 테스트 실패에 대한 예외 추적을보고하지 않습니다. 전혀 도움이되지 않습니다. 따라서 우리는 py.test를 강제하여 stderr을 캡처하지만 stdout 은 캡처 하지 않습니다 .

도착하기 전에이 답변은 testpy.test를 호출 하는 사용자 정의 setuptools 명령 이 이미 있다고 가정합니다 . 그렇지 않은 경우 py.test의 잘 작성된 우수 사례 페이지 의 수동 통합 하위 섹션을 참조하십시오.

마십시오 하지 설치 pytest 주자 , 타사 setuptools에 사용자 지정 setuptools에가 제공하는 플러그인 test도 py.test를 호출 명령을 실행합니다. pytest-runner가 이미 설치되어 있으면 해당 pip3 패키지를 제거한 다음 위의 링크 된 수동 접근 방식을 채택해야합니다.

위에서 강조 표시된 수동 통합 의 지시 사항을 따른다고 가정하면 코드베이스에 PyTest.run_tests()메소드가 포함되어야합니다 . 이 방법을 다음과 같이 수정하십시오.

class PyTest(TestCommand):
             .
             .
             .
    def run_tests(self):
        # Import the public "pytest" package *BEFORE* the private "_pytest"
        # package. While importation order is typically ignorable, imports can
        # technically have side effects. Tragicomically, that is the case here.
        # Importing the public "pytest" package establishes runtime
        # configuration required by submodules of the private "_pytest" package.
        # The former *MUST* always be imported before the latter. Failing to do
        # so raises obtuse exceptions at runtime... which is bad.
        import pytest
        from _pytest.capture import CaptureManager, FDCapture, MultiCapture

        # If the private method to be monkey-patched no longer exists, py.test
        # is either broken or unsupported. In either case, raise an exception.
        if not hasattr(CaptureManager, '_getcapture'):
            from distutils.errors import DistutilsClassError
            raise DistutilsClassError(
                'Class "pytest.capture.CaptureManager" method _getcapture() '
                'not found. The current version of py.test is either '
                'broken (unlikely) or unsupported (likely).'
            )

        # Old method to be monkey-patched.
        _getcapture_old = CaptureManager._getcapture

        # New method applying this monkey-patch. Note the use of:
        #
        # * "out=False", *NOT* capturing stdout.
        # * "err=True", capturing stderr.
        def _getcapture_new(self, method):
            if method == "no":
                return MultiCapture(
                    out=False, err=True, in_=False, Capture=FDCapture)
            else:
                return _getcapture_old(self, method)

        # Replace the old with the new method.
        CaptureManager._getcapture = _getcapture_new

        # Run py.test with all passed arguments.
        errno = pytest.main(self.pytest_args)
        sys.exit(errno)

이 원숭이 패치를 활성화하려면 다음과 같이 py.test를 실행하십시오.

python setup.py test -a "-s"

Stdout은 아니지만 stdout은 캡처 되지 않습니다 . 맵시 있는!

위의 원숭이 패치를 티 stdout 및 stderr로 확장하는 것은 자유 시간이 가득한 배럴로 독자에게 운동으로 남습니다.


33

테스트를 실행할 때 -s옵션을 사용하십시오 . exampletest.py테스트가 실행될 때 모든 인쇄 문 은 콘솔에 인쇄됩니다.

py.test exampletest.py -s

31

pytest documentation 에 따르면 pytest 버전 3은 테스트에서 캡처를 일시적으로 비활성화 할 수 있습니다.

def test_disabling_capturing(capsys):
    print('this output is captured')
    with capsys.disabled():
        print('output not captured, going directly to sys.stdout')
    print('this output is also captured')

20

pytest는 개별 테스트에서 표준 출력을 캡처하여 기본적으로 인쇄되는 테스트 요약과 함께 특정 조건에서만 표시합니다.

추가 요약 정보 는 '-r'옵션을 사용하여 표시 할 수 있습니다.

pytest -rP

통과 된 테스트의 캡처 된 출력을 보여줍니다.

pytest -rx

실패한 테스트 (기본 동작)의 캡처 된 출력을 보여줍니다.

출력 형식은 -s보다 -r보다 더 예쁘다.


2
이것은 내가 찾고 있던 실제 답변입니다! 감사합니다. (표준 출력 오는 데 후에 시험 결과 것이 바람직하다들이 인터리빙되는 경우, 인쇄 된 라인의 값을 잃는다..)
bossylobster

18

시도 pytest -s -v test_login.py콘솔에 대한 추가 정보를 원하시면.

-v 짧아 --verbose

-s '모든 캡처 비활성화'를 의미




1
pytest.ini 파일을 사용하는 경우 다음을 사용할 수 있습니다. addopts = -s -v python_files = test_login.py
timj98

4

PyCharm IDE를 사용하는 경우 실행 도구 모음을 사용하여 해당 개별 테스트 또는 모든 테스트를 실행할 수 있습니다. 실행 도구 창에는 응용 프로그램에서 생성 된 출력이 표시되며 테스트 출력의 일부로 모든 인쇄 명령문을 볼 수 있습니다.


테스트가 진행되는 동안 PyCharm을 인쇄하는 방법을 알고 있습니까? (시험 통과 후)
Alexandre Huat

3

pytest --capture=tee-sys최근에 추가되었습니다. stdout / err의 출력을 볼 수있을뿐만 아니라 캡처 할 수 있습니다.


-4

다른 답변은 작동하지 않습니다. 캡처 출력을 볼 수있는 방법은 다음과 같은 플래그를 사용하고 있습니다 :

pytest --show-capture 모두


6
--show-capture=all기본값입니다. 추가해도 아무런 영향이 없습니다.
22시 09 분
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.