I have a Pytest + Selenium project and I would like to use the logging module.
However, when I set up logging in conftest.py
like this
@pytest.fixture(params=["chrome"], scope="class")
def init_driver(request):
start = datetime.now()
logging.basicConfig(filename='.\\test.log', level=logging.INFO)
if request.param == "chrome":
options = ChromeOptions()
options.add_argument("--start-maximized")
web_driver = webdriver.Chrome(ChromeDriverManager().install(), options=options)
if request.param == "firefox":
web_driver = webdriver.Firefox(GeckoDriverManager().install())
request.cls.driver = web_driver
yield
end = datetime.now()
logging.info(f"{end}: --- DURATION: {end - start}")
web_driver.close()
looks like test.log
is not created at all and there are no error messages or other indications something went wrong.
How can I make this work?
Two facts first:
logging.basicConfig()
only has an effect if no logging configuration was done before invoking it (the target logger has no handlers registered).
pytest
registers custom handlers to the root logger to be able to capture log records emitted in your code, so you can test whether your program logging behaviour is correct.
This means that calling logging.basicConfig(filename='.\\test.log', level=logging.INFO)
in a fixture will do nothing, since the test run has already started and the root logger has handlers attached by pytest
. You thus have two options:
Disable the builtin logging
plugin completely. This will stop log records capturing - if you have tests where you are analyzing emitted logs (e.g. using the caplog
fixture), those will stop working. Invocation:
$ pytest -p no:logging ...
You can persist the flag in pyproject.toml
so it is applied automatically:
[tool.pytest.ini_options]
addopts = "-p no:logging"
Or in pytest.ini
:
[pytest]
addopts = -p no:logging
Configure and use live logging. The configuration in pyproject.toml
, equivalent to your logging.basicConfig()
call:
[tool.pytest.ini_options]
log_file = "test.log"
log_file_level = "INFO"
In pytest.ini
:
[pytest]
log_file = test.log
log_file_level = INFO
Of course, the logging.basicConfig()
line can be removed from the init_driver
fixture in this case.