<p>由于版本3.3,<code>pytest</code>支持实时日志记录,这意味着测试中发出的所有日志记录将立即打印到终端。该特性记录在<a href="https://docs.pytest.org/en/latest/logging.html#live-logs" rel="noreferrer">Live Logs</a>部分下。默认情况下禁用实时日志记录;要启用它,请在<code>pytest.ini</code>配置中设置<code>log_cli = 1</code>。实时日志记录支持发送到终端和文件;相关选项允许自定义记录:</p>
<h3>终端:</h3>
<ul>
<li><code>log_cli_level</code></li>
<li><code>log_cli_format</code></li>
<li><code>log_cli_date_format</code></li>
</ul>
<h3>文件:</h3>
<ul>
<li><code>log_file</code></li>
<li><code>log_file_level</code></li>
<li><code>log_file_format</code></li>
<li><code>log_file_date_format</code></li>
</ul>
<p><strong>注意:<s><code>log_cli</code>无法从命令行传递标志,必须在<code>pytest.ini</code>中设置<strong>。所有其他选项都可以从命令行传递或在配置文件中设置。</s>如<a href="https://stackoverflow.com/questions/4673373/logging-within-py-test-tests/51633600?noredirect=1#comment91175953_51633600">this comment</a>中的<a href="https://stackoverflow.com/users/7505103/k%c3%a9vin-barr%c3%a9">Kévin Barré</a>所指出,从命令行重写ini选项可以通过<code>-o/--override</code>选项完成。因此,与其在<code>pytest.ini</code>中声明<code>log_cli</code>,您只需调用:</p>
<pre><code>$ pytest -o log_cli=true ...
</code></pre>
<h2>实例</h2>
<p>用于演示的简单测试文件:</p>
<pre><code># 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
</code></pre>
<p>如您所见,不需要额外的配置;<code>pytest</code>将根据<code>pytest.ini</code>中指定的选项或从命令行传递的选项自动设置记录器。</p>
<h3>到终端的实时日志,<code>INFO</code>级别,奇特的输出</h3>
<p><code>pytest.ini</code>中的配置:</p>
<pre><code>[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
</code></pre>
<p>运行测试:</p>
<pre><code>$ 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 =============================
</code></pre>
<h3>终端和文件的实时日志记录,终端中只有消息级,文件中有奇特的输出
<p><code>pytest.ini</code>中的配置:</p>
<pre><code>[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
</code></pre>
<p>试运行:</p>
<pre><code>$ 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)
</code></pre>
<hr/>
<p><sup>1</sup>尽管您可以在<code>[tool:pytest]</code>部分下的<code>setup.cfg</code>中配置<code>pytest</code>,但是当您希望提供自定义实时日志格式时,不要尝试这样做。其他读取<code>setup.cfg</code>的工具可能会将<code>%(message)s</code>之类的内容视为字符串插值而失败。使用<code>pytest.ini</code>来避免错误。</p>