| .. _logging: |
| |
| Logging |
| ------- |
| |
| .. versionadded:: 3.3 |
| .. versionchanged:: 3.4 |
| |
| pytest captures log messages of level ``WARNING`` or above automatically and displays them in their own section |
| for each failed test in the same manner as captured stdout and stderr. |
| |
| Running without options:: |
| |
| pytest |
| |
| Shows failed tests like so:: |
| |
| ----------------------- Captured stdlog call ---------------------- |
| test_reporting.py 26 WARNING text going to logger |
| ----------------------- Captured stdout call ---------------------- |
| text going to stdout |
| ----------------------- Captured stderr call ---------------------- |
| text going to stderr |
| ==================== 2 failed in 0.02 seconds ===================== |
| |
| By default each captured log message shows the module, line number, log level |
| and message. |
| |
| If desired the log and date format can be specified to |
| anything that the logging module supports by passing specific formatting options:: |
| |
| pytest --log-format="%(asctime)s %(levelname)s %(message)s" \ |
| --log-date-format="%Y-%m-%d %H:%M:%S" |
| |
| Shows failed tests like so:: |
| |
| ----------------------- Captured stdlog call ---------------------- |
| 2010-04-10 14:48:44 WARNING text going to logger |
| ----------------------- Captured stdout call ---------------------- |
| text going to stdout |
| ----------------------- Captured stderr call ---------------------- |
| text going to stderr |
| ==================== 2 failed in 0.02 seconds ===================== |
| |
| These options can also be customized through ``pytest.ini`` file: |
| |
| .. code-block:: ini |
| |
| [pytest] |
| log_format = %(asctime)s %(levelname)s %(message)s |
| log_date_format = %Y-%m-%d %H:%M:%S |
| |
| Further it is possible to disable reporting of captured content (stdout, |
| stderr and logs) on failed tests completely with:: |
| |
| pytest --show-capture=no |
| |
| |
| caplog fixture |
| ^^^^^^^^^^^^^^ |
| |
| Inside tests it is possible to change the log level for the captured log |
| messages. This is supported by the ``caplog`` fixture:: |
| |
| def test_foo(caplog): |
| caplog.set_level(logging.INFO) |
| pass |
| |
| By default the level is set on the root logger, |
| however as a convenience it is also possible to set the log level of any |
| logger:: |
| |
| def test_foo(caplog): |
| caplog.set_level(logging.CRITICAL, logger='root.baz') |
| pass |
| |
| The log levels set are restored automatically at the end of the test. |
| |
| It is also possible to use a context manager to temporarily change the log |
| level inside a ``with`` block:: |
| |
| def test_bar(caplog): |
| with caplog.at_level(logging.INFO): |
| pass |
| |
| Again, by default the level of the root logger is affected but the level of any |
| logger can be changed instead with:: |
| |
| def test_bar(caplog): |
| with caplog.at_level(logging.CRITICAL, logger='root.baz'): |
| pass |
| |
| Lastly all the logs sent to the logger during the test run are made available on |
| the fixture in the form of both the ``logging.LogRecord`` instances and the final log text. |
| This is useful for when you want to assert on the contents of a message:: |
| |
| def test_baz(caplog): |
| func_under_test() |
| for record in caplog.records: |
| assert record.levelname != 'CRITICAL' |
| assert 'wally' not in caplog.text |
| |
| For all the available attributes of the log records see the |
| ``logging.LogRecord`` class. |
| |
| You can also resort to ``record_tuples`` if all you want to do is to ensure, |
| that certain messages have been logged under a given logger name with a given |
| severity and message:: |
| |
| def test_foo(caplog): |
| logging.getLogger().info('boo %s', 'arg') |
| |
| assert caplog.record_tuples == [ |
| ('root', logging.INFO, 'boo arg'), |
| ] |
| |
| You can call ``caplog.clear()`` to reset the captured log records in a test:: |
| |
| def test_something_with_clearing_records(caplog): |
| some_method_that_creates_log_records() |
| caplog.clear() |
| your_test_method() |
| assert ['Foo'] == [rec.message for rec in caplog.records] |
| |
| |
| The ``caplog.records`` attribute contains records from the current stage only, so |
| inside the ``setup`` phase it contains only setup logs, same with the ``call`` and |
| ``teardown`` phases. |
| |
| To access logs from other stages, use the ``caplog.get_records(when)`` method. As an example, |
| if you want to make sure that tests which use a certain fixture never log any warnings, you can inspect |
| the records for the ``setup`` and ``call`` stages during teardown like so: |
| |
| .. code-block:: python |
| |
| |
| @pytest.fixture |
| def window(caplog): |
| window = create_window() |
| yield window |
| for when in ("setup", "call"): |
| messages = [ |
| x.message for x in caplog.get_records(when) if x.level == logging.WARNING |
| ] |
| if messages: |
| pytest.fail( |
| "warning messages encountered during testing: {}".format(messages) |
| ) |
| |
| |
| |
| The full API is available at :class:`_pytest.logging.LogCaptureFixture`. |
| |
| |
| .. _live_logs: |
| |
| Live Logs |
| ^^^^^^^^^ |
| |
| By setting the :confval:`log_cli` configuration option to ``true``, pytest will output |
| logging records as they are emitted directly into the console. |
| |
| You can specify the logging level for which log records with equal or higher |
| level are printed to the console by passing ``--log-cli-level``. This setting |
| accepts the logging level names as seen in python's documentation or an integer |
| as the logging level num. |
| |
| Additionally, you can also specify ``--log-cli-format`` and |
| ``--log-cli-date-format`` which mirror and default to ``--log-format`` and |
| ``--log-date-format`` if not provided, but are applied only to the console |
| logging handler. |
| |
| All of the CLI log options can also be set in the configuration INI file. The |
| option names are: |
| |
| * ``log_cli_level`` |
| * ``log_cli_format`` |
| * ``log_cli_date_format`` |
| |
| If you need to record the whole test suite logging calls to a file, you can pass |
| ``--log-file=/path/to/log/file``. This log file is opened in write mode which |
| means that it will be overwritten at each run tests session. |
| |
| You can also specify the logging level for the log file by passing |
| ``--log-file-level``. This setting accepts the logging level names as seen in |
| python's documentation(ie, uppercased level names) or an integer as the logging |
| level num. |
| |
| Additionally, you can also specify ``--log-file-format`` and |
| ``--log-file-date-format`` which are equal to ``--log-format`` and |
| ``--log-date-format`` but are applied to the log file logging handler. |
| |
| All of the log file options can also be set in the configuration INI file. The |
| option names are: |
| |
| * ``log_file`` |
| * ``log_file_level`` |
| * ``log_file_format`` |
| * ``log_file_date_format`` |
| |
| .. _log_release_notes: |
| |
| Release notes |
| ^^^^^^^^^^^^^ |
| |
| This feature was introduced as a drop-in replacement for the `pytest-catchlog |
| <https://pypi.org/project/pytest-catchlog/>`_ plugin and they conflict |
| with each other. The backward compatibility API with ``pytest-capturelog`` |
| has been dropped when this feature was introduced, so if for that reason you |
| still need ``pytest-catchlog`` you can disable the internal feature by |
| adding to your ``pytest.ini``: |
| |
| .. code-block:: ini |
| |
| [pytest] |
| addopts=-p no:logging |
| |
| |
| .. _log_changes_3_4: |
| |
| Incompatible changes in pytest 3.4 |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| |
| This feature was introduced in ``3.3`` and some **incompatible changes** have been |
| made in ``3.4`` after community feedback: |
| |
| * Log levels are no longer changed unless explicitly requested by the :confval:`log_level` configuration |
| or ``--log-level`` command-line options. This allows users to configure logger objects themselves. |
| * :ref:`Live Logs <live_logs>` is now disabled by default and can be enabled setting the |
| :confval:`log_cli` configuration option to ``true``. When enabled, the verbosity is increased so logging for each |
| test is visible. |
| * :ref:`Live Logs <live_logs>` are now sent to ``sys.stdout`` and no longer require the ``-s`` command-line option |
| to work. |
| |
| If you want to partially restore the logging behavior of version ``3.3``, you can add this options to your ``ini`` |
| file: |
| |
| .. code-block:: ini |
| |
| [pytest] |
| log_cli=true |
| log_level=NOTSET |
| |
| More details about the discussion that lead to this changes can be read in |
| issue `#3013 <https://github.com/pytest-dev/pytest/issues/3013>`_. |