ฉันจะเห็นผลงานพิมพ์ปกติที่สร้างขึ้นในระหว่างการใช้งาน pytest ได้อย่างไร?


400

บางครั้งฉันต้องการแทรกคำสั่งการพิมพ์บางอย่างในรหัสของฉันและดูสิ่งที่พิมพ์ออกมาเมื่อฉันออกกำลังกาย วิธีปกติของฉันในการ "ออกกำลังกาย" คือการทดสอบที่มีอยู่กับ pytest แต่เมื่อฉันเรียกใช้สิ่งเหล่านี้ฉันไม่สามารถเห็นเอาต์พุตมาตรฐานใด ๆ (อย่างน้อยก็จากใน PyCharm, IDE ของฉัน)

มีวิธีง่ายๆในการดูเอาต์พุตมาตรฐานในระหว่างการทดสอบ pytest หรือไม่?


เฉพาะในความล้มเหลวหรือเสมอ?

17
-s ปิดใช้งานการจับภาพต่อการทดสอบ
hpk42

3
@delnan - ฉันต้องการเห็นมันเสมอ
Des

คำตอบ:


565

-sสวิทช์ปิดการใช้งานการจับต่อการทดสอบ


86
-s=--capture=no
hobs

URL ไม่ทำงาน บางทีอันนี้อาจช่วยได้: docs.pytest.org/en/latest/capture.html
code_dredd

1
สิ่งนี้ทำให้เกิดการส่งออกที่จะ interleaved กับการส่งออก Pytest สิ่งที่คุณอาจต้องการคือสำหรับ Pytest เพื่อจับภาพเอาต์พุตตามปกติและแสดงเมื่อการทดสอบผ่านและล้มเหลว ดูstackoverflow.com/a/59156707/369977
pR0Ps

51

ในการแสดงความคิดเห็น upvotedกับคำตอบที่ได้รับการยอมรับ , โจถาม:

มีวิธีการพิมพ์ไปยังคอนโซลและจับผลลัพธ์เพื่อให้แสดงในรายงาน junit หรือไม่

ใน UNIX นี้ปกติจะเรียกว่าแท่นตั้งที ตามหลักการแล้วการยึดติดแทนที่จะเป็นค่าเริ่มต้น py.test Non-นึกคิดค่า py.test มิได้ปลั๊กอิน py.test ของบุคคลที่สามใด ๆ ที่มีอยู่ ( ... ที่ฉันรู้อยู่แล้ว ) สนับสนุน teeing - แม้จะมีงูหลามนิดสนับสนุน teeing ออกจากกล่อง

py.test การปะของลิงเพื่อทำสิ่งใดที่ไม่ได้รับการสนับสนุนนั้นไม่ใช่เรื่องเล็กน้อย ทำไม? เพราะ:

  • ฟังก์ชั่น py.test ส่วนใหญ่จะถูกล็อคไว้ด้านหลัง_pytestแพ็คเกจส่วนตัวที่ไม่ได้ตั้งใจให้นำเข้าจากภายนอก การพยายามทำเช่นนั้นโดยไม่ทราบว่าคุณกำลังทำอะไรอยู่โดยทั่วไปแล้วจะส่งผลให้เกิดpytestแพคเกจสาธารณะที่ทำให้เกิดข้อยกเว้นที่คลุมเครือขณะใช้งานจริง ขอบคุณมาก py.test สถาปัตยกรรมที่แข็งแกร่งจริงๆคุณไปถึงที่นั่น
  • แม้ว่าคุณจะทราบวิธีการลิงแปะ_pytestAPI ส่วนตัวอย่างปลอดภัยคุณต้องทำก่อนที่จะเรียกใช้pytestแพคเกจสาธารณะที่เรียกใช้โดยpy.testคำสั่งภายนอก คุณไม่สามารถทำสิ่งนี้ได้ในปลั๊กอิน (เช่นconftestโมดูลระดับบนสุดในชุดทดสอบของคุณ) เมื่อถึงเวลา py.test อย่างเกียจคร้านในการนำเข้าปลั๊กอินของคุณคลาส py.test ใด ๆ ที่คุณต้องการให้ลิงแพทช์มีความยาวตั้งแต่อินสแตนซ์ - และคุณไม่สามารถเข้าถึงอินสแตนซ์นั้น นี่หมายความว่าหากคุณต้องการให้ Monkey-patch ของคุณใช้อย่างมีความหมายคุณจะไม่สามารถเรียกใช้py.testคำสั่งภายนอกได้อย่างปลอดภัยอีกต่อไป คุณต้องปิดการทำงานของคำสั่งนั้นด้วย setuptools แบบกำหนดเองแทนtest คำสั่งที่ (ตามลำดับ):
    1. Monkey-patch _pytestAPI ส่วนตัว
    2. เรียกpytest.main()ฟังก์ชันสาธารณะเพื่อเรียกใช้py.testคำสั่ง

คำตอบนี้เป็นคำตอบของ Monkey-patches py.test -sและ--capture=noตัวเลือกในการจับ stderr แต่ไม่ใช่ stdout ตามค่าเริ่มต้นตัวเลือกเหล่านี้จะไม่จับ stderr หรือ stdout แน่นอนว่ามันค่อนข้างไม่น่าสนใจ แต่การเดินทางที่ยิ่งใหญ่ทุกครั้งเริ่มต้นด้วยการ prequel ที่น่าเบื่อทุกคนลืมในห้าปี

ทำไมต้องทำเช่นนี้? ตอนนี้ฉันจะบอกคุณ ชุดการทดสอบที่ขับเคลื่อนด้วย py.test ของฉันมีการทดสอบการทำงานที่ช้า การแสดง stdout ของการทดสอบเหล่านี้มีประโยชน์และให้ความมั่นใจป้องกันleycecไม่ให้เข้าถึงkillall -9 py.testเมื่อการทดสอบการใช้งานที่ยาวนานอีกครั้งไม่สามารถทำอะไรได้หลายสัปดาห์เมื่อสิ้นสุด อย่างไรก็ตามการแสดง stderr ของการทดสอบเหล่านี้จะป้องกัน py.test จากการรายงานข้อผิดพลาดการติดตามย้อนกลับเมื่อการทดสอบล้มเหลว ซึ่งไม่ช่วยเหลืออย่างสมบูรณ์ ดังนั้นเราบีบบังคับ py.test เพื่อจับ stderr แต่ไม่ใช่ stdout

ก่อนที่เราจะไปถึงคำตอบนี้จะถือว่าคุณมีtestคำสั่งsetuptools ที่กำหนดเองแล้วที่เรียก py.test หากไม่เป็นเช่นนั้นให้ดูที่ส่วนย่อยของการรวมด้วยตนเองของเพจแนวปฏิบัติที่ดีที่เป็นลายลักษณ์อักษรของ py.test

ไม่ได้ติดตั้งpytest รองชนะเลิศเป็น setuptools ของบุคคลที่สามปลั๊กอินให้ setuptools กำหนดเองtestคำสั่งนอกจากนี้ยังกล่าวอ้าง py.test หากติดตั้ง pytest-runner เรียบร้อยแล้วคุณอาจต้องถอนการติดตั้งแพ็คเกจ pip3 นั้นจากนั้นใช้แนวทางแบบแมนนวลที่เชื่อมโยงกับข้างต้น

สมมติว่าคุณทำตามคำแนะนำในการรวมด้วยตนเองที่ไฮไลต์ไว้ด้านบนตอนนี้ codebase ของคุณควรมี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)

หากต้องการเปิดใช้งาน Monkey-patch นี้ให้รัน py.test ดังนี้:

python setup.py test -a "-s"

Stderr แต่ไม่ใช่ stdout จะถูกบันทึกในขณะนี้ Nifty!

การขยายแผ่นแปะลิงด้านบนเป็นแท่นทีออฟ stdout และ stderr นั้นเหลือไว้สำหรับการออกกำลังกายให้กับผู้อ่านด้วยเวลาว่างแบบเต็มถัง


33

เมื่อรันการทดสอบให้ใช้-sตัวเลือก คำสั่งการพิมพ์ทั้งหมดexampletest.pyจะได้รับการพิมพ์บนคอนโซลเมื่อเรียกใช้การทดสอบ

py.test exampletest.py -s


20

pytest จะจับ stdout จากการทดสอบแต่ละรายการและแสดงเฉพาะในเงื่อนไขบางอย่างพร้อมกับบทสรุปของการทดสอบที่พิมพ์โดยค่าเริ่มต้น

ข้อมูลสรุปพิเศษสามารถแสดงโดยใช้ตัวเลือก '-r':

pytest -rP

แสดงผลลัพธ์ที่บันทึกไว้ของการทดสอบที่ผ่าน

pytest -rx

แสดงผลลัพธ์ที่บันทึกไว้ของการทดสอบที่ล้มเหลว (พฤติกรรมเริ่มต้น)

การจัดรูปแบบของเอาต์พุตจะสวยกว่าด้วย -r มากกว่าด้วย -s


2
นี่คือคำตอบที่แท้จริงที่ฉันกำลังมองหา! ขอบคุณ. (ให้ stdout มาหลังจากผลการทดสอบเป็นที่ต้องการเมื่อมีการสลับกันบรรทัดที่พิมพ์จะเสียค่า)
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 - แสดงให้เห็นว่าจับทั้งหมด


6
--show-capture=allเป็นค่าเริ่มต้น การเพิ่มมันไม่มีผลอะไรเลย
hoefling
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.