Ghi nhật ký trong các bài kiểm tra pytest


90

Tôi muốn đặt một số câu lệnh ghi nhật ký trong hàm thử nghiệm để kiểm tra một số biến trạng thái.

Tôi có đoạn mã sau:

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

Tôi nhận được kết quả sau:

[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 

Lưu ý rằng chỉ các thông báo ghi nhật ký từ '__name__ == __main__'khối mới được truyền đến bảng điều khiển.

Có cách nào để buộc pytestphát ra bản ghi vào bảng điều khiển từ các phương pháp thử nghiệm không?


3
Bạn có thể xem câu trả lời này , được đăng bởi người tạo của py.test. Anh ấy đề xuất một plugin pytest cung cấp mức độ linh hoạt cao.
chb

Câu trả lời:


30

Hoạt động cho tôi, đây là kết quả tôi nhận được: [snip -> ví dụ không chính xác]

Chỉnh sửa: Có vẻ như bạn phải chuyển -stùy chọn cho py.test để nó không bắt được stdout. Ở đây (chưa cài đặt py.test), nó đã đủ dùng python pytest.py -s pyt.py.

Đối với mã của bạn, bạn chỉ cần có để vượt qua -strong argsđể main:

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

Xem tài liệu py.test về việc thu lại đầu ra .


Lấy làm tiếc. Tôi dán mã một cách vội vàng. Vui lòng xóa 'khẳng định 0 == 1' khỏi hàm 'test_one' để nhận thấy 'sự cố'. Chỉ khi có một số lỗi (mà tôi buộc phải xác nhận sai), py.test dường như in thông tin ghi nhật ký.
siêu dò tìm

Không sao, tôi đã tìm ra cách khắc phục trên dòng lệnh, đang tìm cách lập trình.
TryPyPy

1
bạn cũng có thể chuyển hướng đầu ra ghi nhật ký đến một số tệp thay vì trình ghi lệnh ngầm định mặc định.
hpk42

@superselector hpk42 là người giỏi nhất, hãy lắng nghe. IIUC, trong mã của bạn, nó sẽ là logging.basicConfig(filename="somelog.txt", level=logging.DEBUG).
TryPyPy

116

Kể từ phiên bản 3.3, pytesthỗ trợ ghi nhật ký trực tiếp, có nghĩa là tất cả các bản ghi nhật ký được phát ra trong các bài kiểm tra sẽ được in ra thiết bị đầu cuối ngay lập tức. Tính năng này được ghi lại trong phần Live Logs . Ghi nhật ký trực tiếp bị tắt theo mặc định; để kích hoạt nó, hãy đặt log_cli = 1trong pytest.inicấu hình 1 . Ghi nhật ký trực tiếp hỗ trợ phát ra thiết bị đầu cuối và tệp; các tùy chọn liên quan cho phép tùy chỉnh hồ sơ:

thiết bị đầu cuối:

  • log_cli_level
  • log_cli_format
  • log_cli_date_format

tập tin:

  • log_file
  • log_file_level
  • log_file_format
  • log_file_date_format

Lưu ý : log_clikhông thể chuyển cờ từ dòng lệnh và phải được đặt trong pytest.ini. Tất cả các tùy chọn khác có thể được chuyển từ dòng lệnh hoặc thiết lập trong tệp cấu hình. Như đã chỉ ra bởi Kévin Barré trong nhận xét này , việc ghi đè các tùy chọn ini từ dòng lệnh có thể được thực hiện thông qua -o/--overridetùy chọn. Vì vậy, thay vì khai báo log_clitrong pytest.ini, bạn có thể chỉ cần gọi:

$ pytest -o log_cli=true ...

Ví dụ

Tệp thử nghiệm đơn giản được sử dụng để chứng minh:

# 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

Như bạn thấy, không cần cấu hình bổ sung; pytestsẽ tự động thiết lập trình ghi nhật ký, dựa trên các tùy chọn được chỉ định trong pytest.inihoặc chuyển từ dòng lệnh.

Ghi nhật ký trực tiếp vào thiết bị đầu cuối, INFOcấp độ, đầu ra ưa thích

Cấu hình trong 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

Chạy thử nghiệm:

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

Ghi nhật ký trực tiếp vào thiết bị đầu cuối và tệp, chỉ thông báo và CRITICALcấp trong thiết bị đầu cuối, đầu ra ưa thích trong pytest.logtệp

Cấu hình trong 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

Chạy thử nghiệm:

$ 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 Mặc dù bạn có thể cấu hình pytestsetup.cfgdưới [tool:pytest]phần, không bị cám dỗ để làm điều đó khi bạn muốn cung cấp định dạng logging tùy chỉnh trực tiếp. Các công cụ khác đọc setup.cfgcó thể coi những thứ như %(message)snội suy chuỗi và thất bại. Sử dụng pytest.iniđể tránh sai sót.


18
Về lưu ý log_cliphải có trong pytest.ini , có vẻ như bạn có thể sử dụng -otùy chọn để ghi đè giá trị từ dòng lệnh. pytest -o log_cli=true --log-cli-level=DEBUGlàm việc cho tôi.
Kévin Barré,

@ KévinBarré nhận xét rất tốt và một gợi ý rất hữu ích nói chung, cảm ơn! Đã cập nhật câu trả lời.
hoefling

Đây chắc chắn là câu trả lời chính xác khi sử dụng ghi nhật ký. Mặc dù tôi thích phân biệt các bản ghi bên trong các bài kiểm tra và các bản ghi bên trong hệ thống đang được thử nghiệm mà chúng nên được xem xét riêng biệt.
CMCDragonkai

@CMCDragonkai thật không may, pytestvấn đề đó có phần hạn chế. Tuy nhiên, điều này có thể thực hiện được với cấu hình ghi nhật ký đặc biệt cho các thử nghiệm trong ứng dụng của bạn; tắt truyền trong các trình ghi nhật ký của bạn và thêm một "trình xử lý kiểm tra" ghi nhật ký vào một tệp được chỉ định. Bằng cách này, pytestchỉ ghi nhật ký các bản ghi đến từ các bài kiểm tra, trong khi trình xử lý tùy chỉnh quan tâm đến các bản ghi SuT.
hoefling

1
@OfekAgmon nếu bạn muốn lưu trữ pytestđầu ra, bạn có thể sử dụng --result-logđối số (mặc dù lưu ý rằng nó không được dùng nữa, đây là các lựa chọn thay thế ). Tuy nhiên, bạn không thể lưu trữ pytestđầu ra và đầu ra ghi nhật ký trực tiếp trong cùng một tệp.
hoefling
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.