| # -*- coding: utf-8 -*- |
| import logging |
| |
| import pytest |
| |
| logger = logging.getLogger(__name__) |
| sublogger = logging.getLogger(__name__ + ".baz") |
| |
| |
| def test_fixture_help(testdir): |
| result = testdir.runpytest("--fixtures") |
| result.stdout.fnmatch_lines(["*caplog*"]) |
| |
| |
| def test_change_level(caplog): |
| caplog.set_level(logging.INFO) |
| logger.debug("handler DEBUG level") |
| logger.info("handler INFO level") |
| |
| caplog.set_level(logging.CRITICAL, logger=sublogger.name) |
| sublogger.warning("logger WARNING level") |
| sublogger.critical("logger CRITICAL level") |
| |
| assert "DEBUG" not in caplog.text |
| assert "INFO" in caplog.text |
| assert "WARNING" not in caplog.text |
| assert "CRITICAL" in caplog.text |
| |
| |
| def test_change_level_undo(testdir): |
| """Ensure that 'set_level' is undone after the end of the test""" |
| testdir.makepyfile( |
| """ |
| import logging |
| |
| def test1(caplog): |
| caplog.set_level(logging.INFO) |
| # using + operator here so fnmatch_lines doesn't match the code in the traceback |
| logging.info('log from ' + 'test1') |
| assert 0 |
| |
| def test2(caplog): |
| # using + operator here so fnmatch_lines doesn't match the code in the traceback |
| logging.info('log from ' + 'test2') |
| assert 0 |
| """ |
| ) |
| result = testdir.runpytest_subprocess() |
| result.stdout.fnmatch_lines(["*log from test1*", "*2 failed in *"]) |
| assert "log from test2" not in result.stdout.str() |
| |
| |
| def test_with_statement(caplog): |
| with caplog.at_level(logging.INFO): |
| logger.debug("handler DEBUG level") |
| logger.info("handler INFO level") |
| |
| with caplog.at_level(logging.CRITICAL, logger=sublogger.name): |
| sublogger.warning("logger WARNING level") |
| sublogger.critical("logger CRITICAL level") |
| |
| assert "DEBUG" not in caplog.text |
| assert "INFO" in caplog.text |
| assert "WARNING" not in caplog.text |
| assert "CRITICAL" in caplog.text |
| |
| |
| def test_log_access(caplog): |
| caplog.set_level(logging.INFO) |
| logger.info("boo %s", "arg") |
| assert caplog.records[0].levelname == "INFO" |
| assert caplog.records[0].msg == "boo %s" |
| assert "boo arg" in caplog.text |
| |
| |
| def test_record_tuples(caplog): |
| caplog.set_level(logging.INFO) |
| logger.info("boo %s", "arg") |
| |
| assert caplog.record_tuples == [(__name__, logging.INFO, "boo arg")] |
| |
| |
| def test_unicode(caplog): |
| caplog.set_level(logging.INFO) |
| logger.info(u"bū") |
| assert caplog.records[0].levelname == "INFO" |
| assert caplog.records[0].msg == u"bū" |
| assert u"bū" in caplog.text |
| |
| |
| def test_clear(caplog): |
| caplog.set_level(logging.INFO) |
| logger.info(u"bū") |
| assert len(caplog.records) |
| assert caplog.text |
| caplog.clear() |
| assert not len(caplog.records) |
| assert not caplog.text |
| |
| |
| @pytest.fixture |
| def logging_during_setup_and_teardown(caplog): |
| caplog.set_level("INFO") |
| logger.info("a_setup_log") |
| yield |
| logger.info("a_teardown_log") |
| assert [x.message for x in caplog.get_records("teardown")] == ["a_teardown_log"] |
| |
| |
| def test_caplog_captures_for_all_stages(caplog, logging_during_setup_and_teardown): |
| assert not caplog.records |
| assert not caplog.get_records("call") |
| logger.info("a_call_log") |
| assert [x.message for x in caplog.get_records("call")] == ["a_call_log"] |
| |
| assert [x.message for x in caplog.get_records("setup")] == ["a_setup_log"] |
| |
| # This reachers into private API, don't use this type of thing in real tests! |
| assert set(caplog._item.catch_log_handlers.keys()) == {"setup", "call"} |