Pytest testleri içinde oturum açma


94

Bazı durum değişkenlerini incelemek için test işlevi içine bazı günlük ifadeleri koymak istiyorum.

Aşağıdaki kod parçasına sahibim:

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 ')

Aşağıdaki çıktıyı alıyorum:

[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 

Yalnızca '__name__ == __main__'bloktan gelen günlük mesajlarının konsola iletildiğine dikkat edin.

pytestTest yöntemlerinden konsola günlüğe kaydetmeyi zorlamanın bir yolu var mı ?


3
Py.test'in yaratıcısı tarafından yayınlanan bu cevaba bir göz atabilirsiniz . Yüksek derecede çok yönlülük sağlayan en iyi eklenti önermektedir.
— chb

Yanıtlar:


30

Benim için çalışıyor, işte aldığım çıktı: [Snip -> örnek yanlıştı]

Düzenleme: Görünüşe göre -sstdout'u yakalamaması için py.test seçeneğini geçmeniz gerekiyor. Burada (py.test kurulu değil) kullanmak yeterliydi python pytest.py -s pyt.py.

Kodunuzdaki için tek ihtiyacınız geçmektir -siçinde argsiçin main:

 pytest.main(args=['-s', os.path.abspath(__file__)])

Çıktı yakalamayla ilgili py.test belgelerine bakın .


Afedersiniz. Kodu aceleyle yapıştırdım. 'Sorunu' fark etmek için lütfen 'test_one' işlevinden 'assert 0 == 1'i kaldırın. Yalnızca bazı başarısızlıklar olduğunda (yanlış bir iddiada bulunarak bunu zorladım), py.test günlük bilgilerini yazdırıyor gibi görünüyor.
— süper seçici

Sorun değil, programlı bir yol arayarak komut satırında nasıl düzelteceğimi öğrendim.
— TryPyPy

1
ayrıca günlük çıktısını varsayılan örtük stderr yerine bir dosyaya yeniden yönlendirebilirsiniz.
— hpk42

@superselector hpk42 py.test adamı, dinleyin. IIUC, sizin kodunuzda olacaktır logging.basicConfig(filename="somelog.txt", level=logging.DEBUG).
— TryPyPy

128

3.3 sürümünden bu yana, pytestcanlı günlük kaydını destekler, yani testlerde yayınlanan tüm günlük kayıtları hemen terminale yazdırılacaktır. Özellik, Canlı Günlükler bölümünde belgelenmiştir . Canlı günlük kaydı varsayılan olarak devre dışıdır; etkinleştirmek log_cli = 1için pyproject.toml1 veya pytest.ini2 yapılandırmasında ayarlayın. Canlı kayıt, terminale ve dosyaya yaymayı destekler; ilgili seçenekler kayıtların özelleştirilmesine izin verir:

terminal:

  • log_cli_level
  • log_cli_format
  • log_cli_date_format

dosya:

  • log_file
  • log_file_level
  • log_file_format
  • log_file_date_format

Not : log_clibayrak komut satırından geçirilemez ve ayarlanması gerekirpytest.ini . Diğer tüm seçenekler hem komut satırından geçirilebilir hem de yapılandırma dosyasında ayarlanabilir. As tarafından işaret Kévin Barré içinde bu yorumun yoluyla yapılabilir komut satırından ini seçenekleri geçersiz kılma, -o/--overrideopsiyon. Bunun yerine bildirmek log_clide pytest.ini, sadece çağırabilirsiniz:

$ pytest -o log_cli=true ...

Örnekler

Göstermek için kullanılan basit test dosyası:

# 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

Gördüğünüz gibi, ekstra bir konfigürasyona gerek yok; komut satırında pytestbelirtilen pytest.iniveya komut satırından iletilen seçeneklere göre kaydediciyi otomatik olarak kuracaktır .

Terminale, INFOseviyeye, süslü çıktıya canlı günlük kaydı

Yapılandırma 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"

Eski modeldeki aynı yapılandırma 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

Testi çalıştırmak:

$ 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 =============================

Terminal ve dosyaya canlı kayıt, terminalde sadece mesaj ve CRITICALseviye, pytest.logdosyada fantezi çıktı

Yapılandırma 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"

Eski modeldeki aynı yapılandırma 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

Test sürüşü:

$ 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 sürüm 6.0'dan beri desteklenmektedir ve en iyi seçenek IMO'dur. Özellikler için PEP 518'e bakın .

2 Ayrıca yapılandırmak rağmen pytestiçinde setup.cfgaltında [tool:pytest]bölümüne yapmak cazip değil özel canlı kayıt formatı sağlamak istediğinizde söyledi. Okumakta olan diğer araçlar , dizi enterpolasyonu setup.cfggibi şeyleri ele %(message)salıp başarısız olabilir. En iyi seçenek pyproject.tomlyine de kullanmaktır , ancak eski ini tarzı formatı kullanmak zorunda kalırsanız, pytest.inihataları önlemek için bağlı kalın.


21
Notta Hakkında log_cliolmalıdır pytest.ini , bunu kullanabilir görünüyor -okomut satırından geçersiz kılma değeri seçeneği. pytest -o log_cli=true --log-cli-level=DEBUGbenim için çalışıyor.
— Kévin Barré

@ KévinBarré çok güzel bir yorum ve genel olarak çok faydalı bir ipucu, teşekkürler! Cevap güncellendi.
— hoefling

Bu kesinlikle günlük kaydı kullanırken doğru cevaptır. Testlerin içindeki logları ve test edilen sistem içerisinde bulunan ve ayrı ayrı ele alınması gereken logları ayırt etmeyi sevmeme rağmen .
— CMCDragonkai

@CMCDragonkai maalesef pytestbu konuda biraz sınırlı. Ancak, bu, uygulamanızdaki testler için özel günlük kaydı yapılandırmasıyla yapılabilir; kaydedicilerinizdeki yaymayı kapatın ve belirli bir dosyaya günlük kaydeden bir "test işleyici" ekleyin. Bu şekilde, pytestyalnızca testlerden gelen kayıtları günlüğe kaydederken, özel işleyici SuT günlükleriyle ilgilenir.
— hoefling

1
@OfekAgmon pytestçıktıyı saklamak istiyorsanız, --result-logargümanı kullanabilirsiniz (kullanımdan kaldırıldığını unutmayın , alternatifler burada ). pytestYine de çıktı ve canlı günlük çıktısını aynı dosyada depolayamazsınız .
— hoefling
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.