पाइस्टेस्ट टेस्ट के भीतर लॉगिंग करना


94

मैं कुछ राज्य चर की जांच करने के लिए परीक्षण फ़ंक्शन के भीतर कुछ लॉगिंग स्टेटमेंट डालना चाहूंगा।

मेरे पास निम्नलिखित कोड स्निपेट हैं:

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 के निर्माता द्वारा पोस्ट किए गए इस उत्तर पर आप एक नज़र डाल सकते हैं । वह एक पाइस्टेस्ट प्लगइन का सुझाव देता है जो उच्च स्तर की बहुमुखी प्रतिभा प्रदान करता है।
chb

जवाबों:


30

मेरे लिए काम करता है, यहाँ मुझे आउटपुट मिलता है: [स्निप -> उदाहरण गलत था]

संपादित करें: ऐसा लगता है कि आपको -spy.test के विकल्प को पास करना होगा ताकि यह stdout पर कब्जा न करे। यहां (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 लॉगिंग जानकारी को प्रिंट करने के लिए लगता है।
सुपरसेंटर

कोई समस्या नहीं, मुझे पता चला कि कमांड लाइन पर कैसे तय किया जाए, एक प्रोग्रामेटिक तरीके की तलाश में।
ट्रीपाइ

1
आप डिफ़ॉल्ट अंतर्निहित स्टाडर के बजाय लॉगिंग आउटपुट को कुछ फ़ाइल पर पुनर्निर्देशित कर सकते हैं।
hpk42

@superselector hpk42 py.test आदमी है, सुनो। IIUC, आपके कोड में यह होगा logging.basicConfig(filename="somelog.txt", level=logging.DEBUG)
TryPyPy

128

संस्करण 3.3 के बाद से, pytestलाइव लॉगिंग का समर्थन करता है, जिसका अर्थ है कि परीक्षणों में उत्सर्जित सभी लॉग रिकॉर्ड तुरंत टर्मिनल पर प्रिंट किए जाएंगे। फीचर को लाइव लॉग्स सेक्शन के तहत प्रलेखित किया गया है । लाइव लॉगिंग डिफ़ॉल्ट रूप से अक्षम है; इसे सक्षम करने के लिए, 1 या 2 कॉन्फिगर log_cli = 1में सेट करें । लाइव लॉगिंग टर्मिनल और फ़ाइल के लिए उत्सर्जन का समर्थन करता है; प्रासंगिक विकल्प रिकॉर्ड को अनुकूलित करने की अनुमति देते हैं:pyproject.tomlpytest.ini

टर्मिनल:

  • 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। अन्य सभी विकल्पों को कमांड लाइन से पास किया जा सकता है या कॉन्फ़िगरेशन फ़ाइल में सेट किया जा सकता है। जैसा कि केविन बैर्रे ने इस टिप्पणी में बताया है , कमांड लाइन से इनर ऑप्शन को ओवरराइड करके -o/--overrideविकल्प के माध्यम से किया जा सकता है । घोषित करने के बजाय log_cliमें pytest.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स्तर, फैंसी आउटपुट के लिए लाइव लॉगिंग

में विन्यास pyproject.toml:

[tool.pytest.ini_options]
log_cli = true
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.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फ़ाइल में फैंसी आउटपुट

में विन्यास pyproject.toml:

[tool.pytest.ini_options]
log_cli = true
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.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 pyproject.toml संस्करण 6.0 के बाद से समर्थित है और सबसे अच्छा विकल्प आईएमओ है। चश्मे के लिए पीईपी 518 देखें ।

2 आप भी कॉन्फ़िगर कर सकते हैं pytestमें setup.cfgके तहत [tool:pytest]खंड, ऐसा करने के लिए परीक्षा नहीं है जा कि जब आप कस्टम लाइव लॉगिंग प्रारूप उपलब्ध कराना चाहते हैं। पढ़ने के अन्य उपकरण स्ट्रिंग इंटरपोलेशन और असफल setup.cfgजैसे सामान का इलाज कर %(message)sसकते हैं। सबसे अच्छा विकल्प pyproject.tomlवैसे भी उपयोग कर रहा है, लेकिन अगर आपको विरासत में आई-शैली प्रारूप का उपयोग करने के लिए मजबूर किया जाता है, तो pytest.iniत्रुटियों से बचने के लिए छड़ी ।


21
उस नोट के बारे में जो pytest.inilog_cli में होना चाहिए , ऐसा लगता है कि आप कमांड लाइन से मान को ओवरराइड करने के लिए विकल्प का उपयोग कर सकते हैं । मेरे लिये कार्य करता है। -opytest -o log_cli=true --log-cli-level=DEBUG
केविन बर्रे

@ KévinBarré बहुत अच्छी टिप्पणी और सामान्य रूप से बहुत उपयोगी संकेत, धन्यवाद! उत्तर अपडेट किया गया।
बजे

लॉगिंग का उपयोग करते समय यह निश्चित रूप से सही उत्तर है। हालांकि मुझे ऐसे लॉग्स को अलग करना पसंद है जो परीक्षणों के अंदर हैं, और लॉग जो परीक्षण के तहत सिस्टम के अंदर हैं जिन्हें अलग से माना जाना चाहिए।
CMCDragonkai

@CMCDragonkai दुर्भाग्य से, pytestउस मामले में कुछ हद तक सीमित है। हालांकि, यह आपके ऐप में परीक्षणों के लिए विशेष लॉगिंग कॉन्फ़िगरेशन के साथ उल्लेखनीय होना चाहिए; अपने लॉगर्स में प्रचार बंद करें और एक "परीक्षण हैंडलर" जोड़ें जो एक निर्दिष्ट फ़ाइल में लॉग करता है। इस तरह, pytestकेवल परीक्षण से आने वाले रिकॉर्ड को लॉग करता है, जबकि कस्टम हैंडलर SuT लॉग के बारे में ध्यान रखता है।
फहराया

1
@OfekAgmon यदि आप pytestआउटपुट स्टोर करना चाहते हैं , तो आप --result-logतर्क का उपयोग कर सकते हैं (हालांकि ध्यान दें कि यह पदावनत है, यहाँ विकल्प हैं )। आप pytestआउटपुट और लाइव लॉगिंग आउटपुट को एक ही फाइल में स्टोर नहीं कर सकते , हालाँकि।
फहराया
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.