पाइस्टेस्ट में कंसोल को कैसे प्रिंट करें?


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
शायद स्टडआउट को अधिलेखित किया जा रहा है। यदि आप उपयोग करते हैं तो क्या होता है sys.stdout.write("Test")? कैसे के बारे में sys.__stdout__.write("Test")? उत्तरार्द्ध को हमेशा सिस्टम-परिभाषित स्टडआउट को लिखना चाहिए, जो कंसोल होना चाहिए। यदि दोनों कमांड अलग-अलग काम करते हैं, तो स्टडआउट को बदला जा रहा है; यदि वे एक ही काम करते हैं, तो समस्या कुछ और है।
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
हम्म ... अभी भी मेरे प्रिंट स्टेटमेंट लॉग ऑन नहीं करते हैं
टिम बोलांड

68

-sविकल्प का उपयोग करने से सभी फ़ंक्शन का आउटपुट प्रिंट होगा, जो बहुत अधिक हो सकता है।

यदि आपको विशेष आउटपुट की आवश्यकता है, तो आपके द्वारा उल्लिखित डॉक्टर पृष्ठ कुछ सुझाव प्रदान करता है:

  1. assert False, "dumb assert to make PyTest print my stuff"अपने फ़ंक्शन के अंत में सम्मिलित करें , और आप असफल परीक्षण के कारण अपना आउटपुट देखेंगे।

  2. आपके पास Pyest द्वारा विशेष ऑब्जेक्ट पास किया गया है, और आप बाद में निरीक्षण करने के लिए फ़ाइल में आउटपुट लिख सकते हैं, जैसे

    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)

    आप एक अलग टैब में outऔर errफ़ाइलों को खोल सकते हैं और संपादक को आपके लिए इसे स्वचालित रूप से ताज़ा कर सकते हैं, या py.test; cat out.txtअपना परीक्षण चलाने के लिए एक सरल शेल कमांड कर सकते हैं।

यह सामान करने के लिए हैक करने का तरीका है, लेकिन यह वह सामान है जिसकी आपको आवश्यकता है: आखिरकार, TDD का मतलब है कि आप सामान के साथ गड़बड़ करते हैं और तैयार होने पर इसे साफ और मौन छोड़ देते हैं।


मैं संस्करण 1 की कोशिश की। सबसे शक्तिशाली 3.8.1 के साथ। यह दुर्भाग्य से केवल टेस्ट फंक्शन ब्लॉक को प्रिंट करता है, लेकिन प्रिंट स्टेटमेंट से आउटपुट नहीं :( इसके लिए कोई और ट्रिक?
UV

@ यूयूवी - print()फ़ंक्शन का उपयोग करने के बजाय , आपको चर या संदेश का मतलब एमा के बयान में कॉमा के बाद प्रिंट करना चाहिए । जैसे कि pytest रिपोर्ट में assert False, what_are_you'प्रिंट आउट' होगा what_are_you
मार्ट वान डे वेन

43

संक्षिप्त जवाब

-sविकल्प का उपयोग करें :

pytest -s

विस्तृत जवाब

से डॉक्स :

परीक्षण निष्पादन के दौरान स्टडआउट और स्टेडर को भेजे गए किसी भी आउटपुट को पकड़ लिया जाता है। यदि एक परीक्षण या एक सेटअप विधि विफल रहती है तो कैप्चर किए गए आउटपुट के अनुसार आमतौर पर विफलता ट्रेसबैक के साथ दिखाया जाएगा।

pytestविकल्प है --capture=method, जिसमें method: प्रति-परीक्षा पद्धति पर कब्जा है, और निम्न में से एक हो सकता है fd, sysया nopytestयह भी विकल्प है -sजो एक शॉर्टकट है --capture=no, और यह विकल्प है जो आपको कंसोल में अपने प्रिंट स्टेटमेंट को देखने की अनुमति देगा।

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

कैप्चरिंग विधियों को सेट करना या कैप्चरिंग अक्षम करना

वहाँ दो तरीके हैं जिसमें pytestकैप्चरिंग कर सकते हैं:

  1. फ़ाइल डिस्क्रिप्टर (FD) लेवल कैप्चरिंग (डिफ़ॉल्ट): ऑपरेटिंग सिस्टम फाइल डिस्क्रिप्टर 1 और 2 पर जाने वाले सभी लिखते हैं।

  2. sys लेवल कैप्चरिंग : केवल पायथन फाइल को लिखता है sys.stdout और sys.stderr को कैप्चर किया जाएगा। वसीयतनामे को दर्ज करने वालों पर कोई कब्जा नहीं किया जाता है।

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
कस्टम परीक्षण मीट्रिक के आउटपुट के लिए बिल्कुल सही।
zrr

5

सबसे प्यारे डॉक्स के अनुसार , pytest --capture=sysकाम करना चाहिए। यदि आप किसी परीक्षण के अंदर मानक को कैप्चर करना चाहते हैं, तो कैप्स की स्थिरता का संदर्भ लें।


यह मेरे लिए काम है जब टर्मिनल में प्रिंट वैरिएबल की जरूरत है ...
सुकमा सपुतरा

2

मैं मूल रूप से यहां आया था कि PyTestवहां से यूनिट टेस्ट को चलाने / डिबगिंग करते समय VSCode के कंसोल में प्रिंट कैसे बनाया जाए । यह निम्नलिखित 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"
            ]
        }
    ]
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.