diff --git a/AUTHORS b/AUTHORS index 16918b40c..00157e8ab 100644 --- a/AUTHORS +++ b/AUTHORS @@ -345,6 +345,7 @@ Segev Finer Serhii Mozghovyi Seth Junot Shantanu Jain +Sharad Nair Shubham Adep Simon Gomizelj Simon Holesch diff --git a/changelog/11314.improvement.rst b/changelog/11314.improvement.rst new file mode 100644 index 000000000..272af21f5 --- /dev/null +++ b/changelog/11314.improvement.rst @@ -0,0 +1,2 @@ +Logging to a file using the ``--log-file`` option will use ``--log-level``, ``--log-format`` and ``--log-date-format`` as fallback +if ``--log-file-level``, ``--log-file-format`` and ``--log-file-date-format`` are not provided respectively. diff --git a/src/_pytest/logging.py b/src/_pytest/logging.py index 245b7aed0..bacca4b2a 100644 --- a/src/_pytest/logging.py +++ b/src/_pytest/logging.py @@ -303,13 +303,13 @@ def pytest_addoption(parser: Parser) -> None: add_option_ini( "--log-file-format", dest="log_file_format", - default=DEFAULT_LOG_FORMAT, + default=None, help="Log format used by the logging module", ) add_option_ini( "--log-file-date-format", dest="log_file_date_format", - default=DEFAULT_LOG_DATE_FORMAT, + default=None, help="Log date format used by the logging module", ) add_option_ini( @@ -635,7 +635,9 @@ class LoggingPlugin: self.report_handler.setFormatter(self.formatter) # File logging. - self.log_file_level = get_log_level_for_setting(config, "log_file_level") + self.log_file_level = get_log_level_for_setting( + config, "log_file_level", "log_level" + ) log_file = get_option_ini(config, "log_file") or os.devnull if log_file != os.devnull: directory = os.path.dirname(os.path.abspath(log_file)) diff --git a/testing/logging/test_reporting.py b/testing/logging/test_reporting.py index 8c1e4f8cc..5d10688a0 100644 --- a/testing/logging/test_reporting.py +++ b/testing/logging/test_reporting.py @@ -77,14 +77,14 @@ def test_root_logger_affected(pytester: Pytester) -> None: assert "warning text going to logger" not in stdout assert "info text going to logger" not in stdout - # The log file should contain the warning and the error log messages and - # not the info one, because the default level of the root logger is - # WARNING. + # The log file should only contain the error log messages and + # not the warning or info ones, because the root logger is set to + # ERROR using --log-level=ERROR. assert os.path.isfile(log_file) with open(log_file, encoding="utf-8") as rfh: contents = rfh.read() assert "info text going to logger" not in contents - assert "warning text going to logger" in contents + assert "warning text going to logger" not in contents assert "error text going to logger" in contents @@ -1331,3 +1331,62 @@ def test_date_format_percentf_tz_log(pytester: Pytester) -> None: result.stdout.re_match_lines( [r"^[0-9-]{10} [0-9:]{8}.[0-9]{6}[+-][0-9\.]+; WARNING; text"] ) + + +def test_log_file_cli_fallback_options(pytester: Pytester) -> None: + """Make sure that fallback values for log-file formats and level works.""" + pytester.makepyfile( + """ + import logging + logger = logging.getLogger() + + def test_foo(): + logger.info('info text going to logger') + logger.warning('warning text going to logger') + logger.error('error text going to logger') + + assert 0 + """ + ) + log_file = str(pytester.path.joinpath("pytest.log")) + result = pytester.runpytest( + "--log-level=ERROR", + "--log-format=%(asctime)s %(message)s", + "--log-date-format=%H:%M", + "--log-file=pytest.log", + ) + assert result.ret == 1 + + # The log file should only contain the error log messages + # not the warning or info ones and the format and date format + # should match the formats provided using --log-format and --log-date-format + assert os.path.isfile(log_file) + with open(log_file, encoding="utf-8") as rfh: + contents = rfh.read() + assert re.match(r"[0-9]{2}:[0-9]{2} error text going to logger\s*", contents) + assert "info text going to logger" not in contents + assert "warning text going to logger" not in contents + assert "error text going to logger" in contents + + # Try with a different format and date format to make sure that the formats + # are being used + result = pytester.runpytest( + "--log-level=ERROR", + "--log-format=%(asctime)s : %(message)s", + "--log-date-format=%H:%M:%S", + "--log-file=pytest.log", + ) + assert result.ret == 1 + + # The log file should only contain the error log messages + # not the warning or info ones and the format and date format + # should match the formats provided using --log-format and --log-date-format + assert os.path.isfile(log_file) + with open(log_file, encoding="utf-8") as rfh: + contents = rfh.read() + assert re.match( + r"[0-9]{2}:[0-9]{2}:[0-9]{2} : error text going to logger\s*", contents + ) + assert "info text going to logger" not in contents + assert "warning text going to logger" not in contents + assert "error text going to logger" in contents