pytest에서 콘솔로 인쇄하는 방법은 무엇입니까?


175

와 함께 TDD (테스트 중심 개발)를 사용하려고합니다 pytest. 내가 사용할 때 콘솔에 pytest없습니다 .printprint

나는 pytest my_tests.py그것을 실행하는 데 사용 하고 있습니다.

documentation: 그것은 기본적으로 작동한다고 말할 것 http://pytest.org/latest/capture.html

그러나:

import myapplication as tum

class TestBlogger:

    @classmethod
    def setup_class(self):
        self.user = "alice"
        self.b = tum.Blogger(self.user)
        print "This should be printed, but it won't be!"

    def test_inherit(self):
        assert issubclass(tum.Blogger, tum.Site)
        links = self.b.get_links(posts)
        print len(links)   # This won't print either.

표준 출력 콘솔에 아무것도 인쇄되지 않습니다 (정상 진행 상태 및 몇 번의 테스트 통과 / 실패).

그리고 내가 테스트하는 스크립트에는 인쇄가 포함되어 있습니다.

class Blogger(Site):
    get_links(self, posts):
        print len(posts)   # It won't get printed in the test.

unittest모듈 에서는 기본적으로 모든 것이 기본적으로 인쇄되므로 정확히 필요합니다. 그러나 pytest다른 이유로 사용 하고 싶습니다 .

인쇄 문을 표시하는 방법을 아는 사람이 있습니까?


1
stdout을 덮어 쓰고있을 수 있습니다. 사용하면 어떻게됩니까 sys.stdout.write("Test")? 어때요 sys.__stdout__.write("Test")? 후자는 항상 시스템 정의 stdout에 작성해야하며 콘솔이어야합니다. 두 명령이 서로 다른 작업을 수행하면 stdout이 변경됩니다. 그들이 똑같은 일을하면 문제는 다른 것입니다.
TheSoundDefense

답변:


205

기본적 py.test으로 표준 출력 결과를 캡처하여 인쇄 방법을 제어 할 수 있습니다. 그렇지 않은 경우 테스트에서 해당 텍스트를 인쇄 한 컨텍스트없이 많은 텍스트를 분출합니다.

그러나 테스트에 실패하면 결과 보고서에 특정 테스트에서 표준으로 인쇄 된 내용을 보여주는 섹션이 포함됩니다.

예를 들어

def test_good():
    for i in range(1000):
        print(i)

def test_bad():
    print('this should fail!')
    assert False

결과는 다음과 같습니다.

>>> py.test tmp.py
============================= test session starts ==============================
platform darwin -- Python 2.7.6 -- py-1.4.20 -- pytest-2.5.2
plugins: cache, cov, pep8, xdist
collected 2 items

tmp.py .F

=================================== FAILURES ===================================
___________________________________ test_bad ___________________________________

    def test_bad():
        print('this should fail!')
>       assert False
E       assert False

tmp.py:7: AssertionError
------------------------------- Captured stdout --------------------------------
this should fail!
====================== 1 failed, 1 passed in 0.04 seconds ======================

Captured stdout섹션을 참고 하십시오.

print실행 된 명령문 을 보려면 -s플래그를에 전달하면 됩니다 py.test. 그러나 때때로 구문 분석하기가 어려울 수 있습니다.

>>> py.test tmp.py -s
============================= test session starts ==============================
platform darwin -- Python 2.7.6 -- py-1.4.20 -- pytest-2.5.2
plugins: cache, cov, pep8, xdist
collected 2 items

tmp.py 0
1
2
3
... and so on ...
997
998
999
.this should fail!
F

=================================== FAILURES ===================================
___________________________________ test_bad ___________________________________

    def test_bad():
        print('this should fail!')
>       assert False
E       assert False

tmp.py:7: AssertionError
====================== 1 failed, 1 passed in 0.02 seconds ======================

2
실용적. 잘 했어!
cmc

1
흠 ... 여전히 내 인쇄물을 기록하지 않습니다
Tim Boland

68

-s옵션을 사용하면 너무 많은 모든 기능의 출력이 인쇄됩니다.

특정 출력이 필요한 경우 언급 한 문서 페이지에는 몇 가지 제안이 있습니다.

  1. assert False, "dumb assert to make PyTest print my stuff"함수 끝에 삽입 하면 테스트 실패로 인해 출력이 표시됩니다.

  2. PyTest에 의해 전달 된 특수 객체가 있으며 출력을 파일에 기록하여 나중에 검사 할 수 있습니다.

    def test_good1(capsys):
        for i in range(5):
            print i
        out, err = capsys.readouterr()
        open("err.txt", "w").write(err)
        open("out.txt", "w").write(out)
    

    별도의 탭에서 outerr파일을 열고 편집기에서 자동으로 새로 고치거나 간단한 py.test; cat out.txt쉘 명령을 수행하여 테스트를 실행할 수 있습니다.

그것은 해킹을하는 해킹 방법이지만, 필요한 것 일 수도 있습니다. 결국 TDD는 물건을 엉망으로 만들고 준비가되면 깨끗하고 조용하게 둡니다 :-).


불행히도 pytest 3.8.1로 버전 1을 사용해 보았습니다. 불행히도 테스트 함수 블록 만 인쇄하지만 print 문의 출력은 출력하지 않습니다. (더 이상의 비법은?
UV

@UV- print()함수 를 사용하는 대신 assert 문에 쉼표 뒤에 인쇄하려는 변수 또는 메시지를 넣어야합니다 . 예를 들어 pytest 보고서 assert False, what_are_you의 값을 '인쇄'합니다 what_are_you.
Mart Van de Ven

43

짧은 답변

-s옵션을 사용하십시오 :

pytest -s

자세한 답변

에서 워드 프로세서 :

테스트 실행 중에 stdoutstderr로 전송 된 출력 이 캡처됩니다. 테스트 또는 설정 방법이 실패하면 캡처 된 출력에 따라 일반적으로 실패 추적이 표시됩니다.

pytest옵션이 --capture=method있는 method: 당 시험 방법을 캡처하고, 다음 중 하나가 될 수 fd, sys또는 no. pytest또한 -s바로 가기 --capture=no옵션이 있으며 콘솔에서 인쇄 문을 볼 수있는 옵션입니다.

pytest --capture=no     # show print statements in console
pytest -s               # equivalent to previous command

캡처 방법 설정 또는 캡처 비활성화

pytest캡처를 수행 할 수 있는 두 가지 방법이 있습니다.

  1. 파일 디스크립터 (FD) 레벨 캡처 (기본값) : 운영 체제 파일 디스크립터 1 및 2에 대한 모든 쓰기가 캡처됩니다.

  2. sys level capturing : sys.stdout 및 sys.stderr는 Python 파일에 쓰기 만 캡처됩니다. 파일 디스크립터에 대한 쓰기 캡처는 수행되지 않습니다.

pytest -s            # disable all capturing
pytest --capture=sys # replace sys.stdout/stderr with in-mem files
pytest --capture=fd  # also point filedescriptors 1 and 2 to temp file

17

PyTest문자 그대로 모든 것을 음소거 할 때 건너 뛴 테스트에 대한 중요한 경고를 인쇄해야했습니다 .

신호를 보내기 위해 테스트에 실패하고 싶지 않았으므로 다음과 같이 해킹을 수행했습니다.

def test_2_YellAboutBrokenAndMutedTests():
    import atexit
    def report():
        print C_patch.tidy_text("""
In silent mode PyTest breaks low level stream structure I work with, so
I cannot test if my functionality work fine. I skipped corresponding tests.
Run `py.test -s` to make sure everything is tested.""")
    if sys.stdout != sys.__stdout__:
        atexit.register(report)

atexit모듈을 사용 하면 출력 스트림 PyTest 해제 한 물건을 인쇄 할 수 있습니다 . 출력은 다음과 같습니다.

============================= test session starts ==============================
platform linux2 -- Python 2.7.3, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
rootdir: /media/Storage/henaro/smyth/Alchemist2-git/sources/C_patch, inifile: 
collected 15 items 

test_C_patch.py .....ssss....s.

===================== 10 passed, 5 skipped in 0.15 seconds =====================
In silent mode PyTest breaks low level stream structure I work with, so
I cannot test if my functionality work fine. I skipped corresponding tests.
Run `py.test -s` to make sure everything is tested.
~/.../sources/C_patch$

PyTest자동 모드 일 때도 메시지가 인쇄 되고를 사용 하여 작업을 실행하면 인쇄 되지py.test -s 않으므로 모든 것이 이미 훌륭하게 테스트되었습니다.


1
맞춤형 테스트 측정 항목을 출력하는 데 적합합니다.
z0r


2

원래 PyTestVSCode의 콘솔에서 인쇄 하는 방법을 찾기 위해 여기 에 왔으며 단위 테스트를 실행 / 디버깅합니다. 다음 launch.json구성 으로 수행 할 수 있습니다 . .venv가상 환경 폴더가 주어 집니다.

    "version": "0.2.0",
    "configurations": [
        {
            "name": "PyTest",
            "type": "python",
            "request": "launch",
            "stopOnEntry": false,
            "pythonPath": "${config:python.pythonPath}",
            "module": "pytest",
            "args": [
                "-sv"
            ],
            "cwd": "${workspaceRoot}",
            "env": {},
            "envFile": "${workspaceRoot}/.venv",
            "debugOptions": [
                "WaitOnAbnormalExit",
                "WaitOnNormalExit",
                "RedirectOutput"
            ]
        }
    ]
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.