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.
Since version 3.3, pytest supports live logging, meaning that all the log records emitted in tests will be printed to the terminal immediately. The feature is documented under Live Logs section.
Verbosity. The -v flag controls the verbosity of pytest output in various aspects: test session progress, assertion details when tests fail, fixtures details with --fixtures , etc.
Since version 3.3, pytest
supports live logging, meaning that all the log records emitted in tests will be printed to the terminal immediately. The feature is documented under Live Logs section. Live logging is disabled by default; to enable it, set log_cli = 1
in the pyproject.toml
1 or pytest.ini
2 config. Live logging supports emitting to terminal and file; the relevant options allow records customizing:
log_cli_level
log_cli_format
log_cli_date_format
log_file
log_file_level
log_file_format
log_file_date_format
Note: As pointed out by Kévin Barré in this comment, overriding ini options from command line can be done via the log_cli
flag can't be passed from command line and must be set in pytest.ini
. All the other options can be both passed from command line or set in the config file.-o/--override
option. So instead of declaring log_cli
in pytest.ini
, you can simply call:
$ pytest -o log_cli=true ...
Simple test file used for demonstrating:
# 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
As you can see, no extra configuration needed; pytest
will setup the logger automatically, based on options specified in pytest.ini
or passed from command line.
INFO
level, fancy outputConfiguration in 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"
The identical configuration in legacy 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
Running the test:
$ 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 =============================
CRITICAL
level in terminal, fancy output in pytest.log
fileConfiguration in 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"
The identical configuration in legacy 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 run:
$ 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)
1pyproject.toml
supported since version 6.0 and is the best option IMO. See PEP 518 for the specs.
2 Although you can also configure pytest
in setup.cfg
under the [tool:pytest]
section, don't be tempted to do that when you want to provide custom live logging format. Other tools reading setup.cfg
might treat stuff like %(message)s
as string interpolation and fail. The best choice is using pyproject.toml
anyway, but if you are forced to use the legacy ini-style format, stick to pytest.ini
to avoid errors.
Works for me, here's the output I get: [snip -> example was incorrect]
Edit: It seems that you have to pass the -s
option to py.test so it won't capture stdout. Here (py.test not installed), it was enough to use python pytest.py -s pyt.py
.
For your code, all you need is to pass -s
in args
to main
:
pytest.main(args=['-s', os.path.abspath(__file__)])
See the py.test documentation on capturing output.
Using pytest --log-cli-level=DEBUG
works fine with pytest-6.2.2
To turn logger output on use send --capture=no
flag from command line.
--capture=no
will show all outputs from logger and print statements. If you would like to capture outputs from logger and not print statements use --capture=sys
pytest --capture=no tests/system/test_backoffice.py
Here is more information about "Capturing of the stdout/stderr output"
By default logger output level is "WARNING"
To change log output level use --log-cli-level
flag.
pytest --capture=no --log-cli-level=DEBUG tests/system/test_backoffice.py
If you want to filter logs with the command line, you can pass --log-cli-level (pytest --log-cli-level) and logs will be shown from the level you specified and above
(e.g. pytest --log-cli-level=INFO will show INFO and above logs(WARNING, ERROR, CRITICAL))
note that: default --log-cli-level is a WARNING if you don't specify it (https://docs.pytest.org/en/6.2.x/logging.html)
But if you dont want to use --log-cli-level every time use pytest, you can set log-level in your pytest config file (pytest.ini/tox.ini/setup.cfg)
e.g.
put log-level=INFO in pytest.ini (or other config files i mentioned)
when you run pytest, you only see INFO and above logs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With