How to create new log file for each run of tests in pytest?
Asked Answered
L

4

5

I have created a pytest.ini file,

addopts = --resultlog=log.txt

This creates a log file, but I would like to create a new log file everytime I run the tests.

Ling answered 23/7, 2019 at 13:57 Comment(0)
L
4

Answering my own question. As hoefling mentioned --result-log is deprecated, I had to find a way to do it without using that flag. Here's how I did it,

conftest.py

from datetime import datetime
import logging

log = logging.getLogger(__name__)

def pytest_assertrepr_compare(op, left, right):
    """ This function will print log everytime the assert fails"""
    log.error('Comparing Foo instances:    vals: %s != %s \n' % (left, right))
    return ["Comparing Foo instances:", " vals: %s != %s" % (left, right)]

def pytest_configure(config):
    """ Create a log file if log_file is not mentioned in *.ini file"""
    if not config.option.log_file:
        timestamp = datetime.strftime(datetime.now(), '%Y-%m-%d_%H-%M-%S')
        config.option.log_file = 'log.' + timestamp

pytest.ini

[pytest]
log_cli = true
log_cli_level = CRITICAL
log_cli_format = %(message)s
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_my_code.py

import logging
log = logging.getLogger(__name__)

def test_my_code():
    ****test code
Ling answered 29/7, 2019 at 14:27 Comment(1)
Beware that live logging is not the same as the --result-log. The former only persists the logs emitted by your code, the latter writes a copy of the complete test run output to file.Furthest
F
7

Note

--result-log argument is deprecated and scheduled for removal in version 6.0 (see Deprecations and Removals: Result log). The possible replacement implementation is discussed in issue #4488, so watch out for the next major version bump - the code below will stop working with pytest==6.0.

Answer

You can modify the resultlog in the pytest_configure hookimpl. Example: put the code below in the conftest.py file in your project root dir:

import datetime


def pytest_configure(config):
    if not config.option.resultlog:
        timestamp = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d_%H-%M-%S')
        config.option.resultlog = 'log.' + timestamp

Now if --result-log is not passed explicitly (so you have to remove addopts = --resultlog=log.txt from your pytest.ini), pytest will create a log file ending with a timestamp. Passing --result-log with a log file name will override this behaviour.

Furthest answered 23/7, 2019 at 14:45 Comment(0)
L
4

Answering my own question. As hoefling mentioned --result-log is deprecated, I had to find a way to do it without using that flag. Here's how I did it,

conftest.py

from datetime import datetime
import logging

log = logging.getLogger(__name__)

def pytest_assertrepr_compare(op, left, right):
    """ This function will print log everytime the assert fails"""
    log.error('Comparing Foo instances:    vals: %s != %s \n' % (left, right))
    return ["Comparing Foo instances:", " vals: %s != %s" % (left, right)]

def pytest_configure(config):
    """ Create a log file if log_file is not mentioned in *.ini file"""
    if not config.option.log_file:
        timestamp = datetime.strftime(datetime.now(), '%Y-%m-%d_%H-%M-%S')
        config.option.log_file = 'log.' + timestamp

pytest.ini

[pytest]
log_cli = true
log_cli_level = CRITICAL
log_cli_format = %(message)s
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_my_code.py

import logging
log = logging.getLogger(__name__)

def test_my_code():
    ****test code
Ling answered 29/7, 2019 at 14:27 Comment(1)
Beware that live logging is not the same as the --result-log. The former only persists the logs emitted by your code, the latter writes a copy of the complete test run output to file.Furthest
A
2

You can have different pytest run logs by naming the log file the time when test execution starts.

pytest tests --log-file $(date '+%F_%H:%M:%S') 

This will create a log file for each test run. And the name of the test run would be the timestamp.

$(date '+%F_%H:%M:%S') is the bash command to get current timestamp in DATE_Hr:Min:Sec format.

Ajax answered 29/7, 2019 at 20:47 Comment(0)
E
0

Expanding on @SilentGuy's helpful solution, as answered in this similar question, you can add to the filename both username and timestamp via:

pytest . -vv | tee ./logs/$(whoami)_"$(date +%Y%m%d_%H%M%S)".log

where

  • . runs all tests in test/
  • -vv returns very verbose results
  • whoami resolves to your username on linux/windows
  • the date section produces YYYYMMDD_HHMMSS
Elwell answered 17/5, 2023 at 19:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.