Cách phổ biến của mocking ra đối tượng logger (xem câu trả lời của chap lộng lẫy Simeon Visser của) là hơi khó khăn ở chỗ nó đòi hỏi các thử nghiệm để thử ra đăng nhập trong tất cả những nơi nó được thực hiện. Điều này là khó xử nếu việc ghi nhật ký đến từ nhiều hơn một mô-đun, hoặc trong mã bạn không sở hữu. Nếu module đăng nhập đến từ tên thay đổi, nó sẽ phá vỡ các bài kiểm tra của bạn.
Gói 'testfixtures' lộng lẫy bao gồm các công cụ để thêm trình xử lý ghi nhật ký nắm bắt tất cả thông điệp nhật ký được tạo, bất kể chúng đến từ đâu. Các tin nhắn được chụp sau đó có thể được thẩm vấn bằng thử nghiệm. Trong hình thức của nó đơn giản nhất:
Giả sử mã dưới kiểm tra, trong đó ghi:
import logging
logger = logging.getLogger()
logger.info('a message')
logger.error('an error')
Xét nghiệm này sẽ là:
from testfixtures import LogCapture
with LogCapture() as l:
call_code_under_test()
l.check(
('root', 'INFO', 'a message'),
('root', 'ERROR', 'an error'),
)
Từ 'root' cho thấy khai thác gỗ đã được gửi thông qua một logger tạo ra bằng cách sử dụng logging.getLogger()
(tức là không có args.) Nếu bạn vượt qua một arg để getLogger (__name__
là thông thường), arg đó sẽ được sử dụng thay cho 'root'.
Kiểm tra không quan tâm mô-đun nào đã tạo nhật ký. Nó có thể là một mô-đun phụ được gọi là mã của chúng tôi dưới sự kiểm tra, bao gồm cả mã bên thứ 3.
Bài kiểm tra xác nhận về thông điệp nhật ký thực tế được tạo, trái ngược với kỹ thuật chế nhạo, xác nhận về các số thập phân đã được chuyển. Chúng sẽ khác nếu cuộc gọi logging.info sử dụng các chuỗi định dạng '% s' với các đối số bổ sung mà bạn không tự mở rộng (ví dụ: sử dụng logging.info('total=%s', len(items))
thay vì logging.info('total=%s' % len(items))
, mà bạn nên làm. chẳng hạn như 'Sentry' để hoạt động đúng - họ có thể thấy rằng "total = 12" và "total = 43" là hai trường hợp của cùng một thông điệp tường trình. Đó là lý do tại sao pylint cảnh báo về dạng sau của cuộc gọi logging.info
.)
LogCapture bao gồm các cơ sở để lọc nhật ký và tương tự. Gói phụ huynh 'testfixtures' của nó, được viết bởi Chris Withers, một chap lộng lẫy khác, bao gồm nhiều công cụ kiểm tra hữu ích khác.Tài liệu là ở đây: http://pythonhosted.org/testfixtures/logging.html
Điều nhỏ ... từ Python 3.3 trở đi, việc nhập cho thử nghiệm phải là 'từ bản vá nhập unittest.mock'. Nếu không, vẫn còn tốt! –
@Simeon Visser làm thế nào để làm điều đó với giả lập, nếu bên trong cuộc gọi đăng nhập, chúng tôi đang đi qua một ngoại lệ? Một cái gì đó như "logger.exception (KeyError ('test'))" Bằng cách này, "assert_called_with" sẽ không bắt được nó vì tôi đoán các tham chiếu cho đối tượng KeyError là khác nhau. (nghĩa là chúng không còn là chuỗi đơn giản nữa). – SpiXel
@SpiXel: bạn có thể xem nội dung của mock_logger.error.call_args_list và đưa ra các xác nhận về các đối số. Ví dụ, nó sẽ là một cái gì đó như: 'assert" Test "trong str (my_logging_argument)' hoặc 'self.assertEqual (str (my_logging_argument)," KeyError ('test') "'. Xem: https: //docs.python .org/3/library/unittest.mock.html # unittest.mock.Mock.call_args_list –