From a617e50b4ca0ffea59d27cf70f7451a3cdb2aa57 Mon Sep 17 00:00:00 2001 From: Krzysztof Laskowski Date: Sun, 18 Feb 2024 23:42:29 +0100 Subject: [PATCH 01/16] ci: test only master and pull-requests --- .appveyor.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.appveyor.yml b/.appveyor.yml index e5035ee..b690ae3 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,6 +1,10 @@ version: '{build}-{branch}' build: false +branches: + only: + - master + cache: - '%LOCALAPPDATA%\pip\Cache' From 7c6e9641dd73197a3c1c4d4e47505e1cf388e888 Mon Sep 17 00:00:00 2001 From: Krzysztof Laskowski Date: Sun, 18 Feb 2024 01:40:51 +0100 Subject: [PATCH 02/16] deps: removed dependency on "future" package --- docs/requirements.txt | 1 - pytest_logger/plugin.py | 7 +++---- setup.py | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index fd6d2f5..91e8e80 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,3 @@ -future==0.18.3 py==1.11.0 pytest==7.4.4 sphinx==7.2.6 diff --git a/pytest_logger/plugin.py b/pytest_logger/plugin.py index 0ac4ef6..3402479 100644 --- a/pytest_logger/plugin.py +++ b/pytest_logger/plugin.py @@ -8,7 +8,6 @@ import datetime import argparse from builtins import object, int -from past.builtins import basestring def pytest_addhooks(pluginmanager): @@ -328,7 +327,7 @@ def _sanitize_nodeid(node_id): def _sanitize_level(level, raises=True): - if isinstance(level, basestring): + if isinstance(level, str): try: return int(level) except ValueError: @@ -422,7 +421,7 @@ def bad_level(level): def _loggers_from_logcfg(logcfg, logopt): def to_stdout(loggers, opt): def one(loggers, one): - if isinstance(one, basestring): + if isinstance(one, str): return one, next(row for row in loggers if one in row[0])[1] else: return one @@ -440,7 +439,7 @@ def to_file(loggers): def _loggers_from_hooks(item): def to_loggers(configs_lists): def to_logger_and_level(cfg): - if isinstance(cfg, basestring): + if isinstance(cfg, str): name, level = cfg, logging.NOTSET else: name, level = cfg diff --git a/setup.py b/setup.py index da4ed68..1b8a016 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ def read(fname): long_description=read('README.rst'), long_description_content_type='text/x-rst', packages=['pytest_logger'], - install_requires=['pytest>=3.2', 'future', 'py'], + install_requires=['pytest>=3.2', 'py'], keywords='py.test pytest logging', classifiers=[ 'Development Status :: 5 - Production/Stable', From d178456ede909903ea711f462955728e4f12803f Mon Sep 17 00:00:00 2001 From: Krzysztof Laskowski Date: Mon, 19 Feb 2024 02:47:23 +0100 Subject: [PATCH 03/16] deps: removed dependency on "py" package - no need to import Source from py library (it's enough to dedent) - no need to use obsolete py.path.local, using pathlib.Path instead --- docs/requirements.txt | 1 - pytest_logger/plugin.py | 32 ++++++++++++++++---------------- setup.py | 2 +- tests/test_pytest_logger.py | 11 +++++------ 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 91e8e80..db6029f 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,3 @@ -py==1.11.0 pytest==7.4.4 sphinx==7.2.6 sphinx_rtd_theme==2.0.0 diff --git a/pytest_logger/plugin.py b/pytest_logger/plugin.py index 3402479..a67b364 100644 --- a/pytest_logger/plugin.py +++ b/pytest_logger/plugin.py @@ -1,13 +1,14 @@ import os import sys import re -import py import pytest import logging import time import datetime import argparse +import shutil from builtins import object, int +from pathlib import Path def pytest_addhooks(pluginmanager): @@ -107,13 +108,13 @@ def pytest_runtest_makereport(self, item, call): logger = getattr(item, '_logger', None) if logger: if self._logsdir and self._split_by_outcome_subdir and tr.outcome in self._split_by_outcome_outcomes: - split_by_outcome_logdir = self._logsdir.join(self._split_by_outcome_subdir, tr.outcome) + split_by_outcome_logdir = self._logsdir / self._split_by_outcome_subdir / tr.outcome nodeid = _sanitize_nodeid(item.nodeid) nodepath = os.path.dirname(nodeid) - split_by_outcome_logdir.join(nodepath).ensure(dir=1) - destdir_relpath = os.path.relpath(str(self._logsdir.join(nodeid)), - str(split_by_outcome_logdir.join(nodepath))) - _refresh_link(destdir_relpath, str(split_by_outcome_logdir.join(nodeid))) + outcomedir = split_by_outcome_logdir / nodepath + outcomedir.mkdir(parents=True, exist_ok=True) + destdir_relpath = os.path.relpath(self._logsdir / nodeid, outcomedir) + _refresh_link(destdir_relpath, split_by_outcome_logdir / nodeid) if call.when == 'teardown': logger.on_makereport() @@ -356,21 +357,20 @@ def _make_logsdir_tmpdir(tmpdirhandler): if logsdir.basename.startswith('popen-gw'): logsdir = logsdir.join('..') logsdir = logsdir.join('logs').ensure(dir=1) - return logsdir + return Path(logsdir) -def _make_logsdir_dir(dstname, cleandir=True): - logsdir = py.path.local(dstname) - if cleandir: - if logsdir.check(): - logsdir.remove() - logsdir.mkdir() - return logsdir +def _make_logsdir_dir(dstname): + shutil.rmtree(dstname, ignore_errors=True) + os.mkdir(dstname) + return Path(dstname) def _make_logdir(item): plugin = item.config.pluginmanager.getplugin('_logger') - return plugin.logsdir().join(_sanitize_nodeid(item.nodeid)).ensure(dir=1) + logdir = plugin.logsdir() / _sanitize_nodeid(item.nodeid) + logdir.mkdir(parents=True) + return logdir def _enable(handlers): @@ -485,7 +485,7 @@ def make_handler(logdir, logger_and_level, fmt): name, level = logger_and_level logger = logging.getLogger(name) name = name or 'logs' - logfile = str(logdir.join(name)) + logfile = str(logdir / name) handler = logging.FileHandler(filename=logfile, mode='w', delay=True) handler.setFormatter(fmt) handler.setLevel(level) diff --git a/setup.py b/setup.py index 1b8a016..4df26ef 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ def read(fname): long_description=read('README.rst'), long_description_content_type='text/x-rst', packages=['pytest_logger'], - install_requires=['pytest>=3.2', 'py'], + install_requires=['pytest>=3.2'], keywords='py.test pytest logging', classifiers=[ 'Development Status :: 5 - Production/Stable', diff --git a/tests/test_pytest_logger.py b/tests/test_pytest_logger.py index f14aac3..74f93ca 100644 --- a/tests/test_pytest_logger.py +++ b/tests/test_pytest_logger.py @@ -2,8 +2,7 @@ import sys import pytest import platform -from py.code import Source -from _pytest.pytester import LineMatcher +import textwrap win32 = sys.platform == 'win32' win32py2 = win32 and sys.version_info[0] == 2 @@ -11,7 +10,7 @@ def makefile(testdir, path, content): - return testdir.tmpdir.ensure(*path).write('\n'.join(Source(content))) + return testdir.tmpdir.ensure(*path).write(textwrap.dedent(content)) def ls(dir, filepath=''): @@ -64,10 +63,10 @@ def test_case(): return filename -class FileLineMatcher(LineMatcher): +class FileLineMatcher(pytest.LineMatcher): def __init__(self, dir, filepath): lines = dir.join(filepath).read().splitlines() - LineMatcher.__init__(self, lines) + pytest.LineMatcher.__init__(self, lines) def test_logdir_fixture(testdir): @@ -566,7 +565,7 @@ def test_logsdir_cleanup(testdir, conftest_py, test_case_py): logger_logsdir={0} """.format(logsdir)) - logsdir.ensure('tmpfile').write('\n'.join(Source('this shall be removed'))) + logsdir.ensure('tmpfile').write(textwrap.dedent('this shall be removed')) logsdir.join('tmpdir') result = testdir.runpytest('-s') From 25211d84d79777d549303f3bb06b6fd18639346d Mon Sep 17 00:00:00 2001 From: Krzysztof Laskowski Date: Sun, 18 Feb 2024 01:58:29 +0100 Subject: [PATCH 04/16] modernize: no need to import object and int from builtins anymore --- pytest_logger/plugin.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/pytest_logger/plugin.py b/pytest_logger/plugin.py index a67b364..1648b22 100644 --- a/pytest_logger/plugin.py +++ b/pytest_logger/plugin.py @@ -7,7 +7,6 @@ import datetime import argparse import shutil -from builtins import object, int from pathlib import Path @@ -51,12 +50,12 @@ def pytest_configure(config): config.pluginmanager.register(LoggerPlugin(config, early_logger._logcfg), '_logger') -class EarlyLoggerPlugin(object): +class EarlyLoggerPlugin: def __init__(self, logcfg): self._logcfg = logcfg -class LoggerPlugin(object): +class LoggerPlugin: def __init__(self, config, logcfg): self._config = config self._logdirlinks = config.hook.pytest_logger_logdirlink(config=config) @@ -119,7 +118,7 @@ def pytest_runtest_makereport(self, item, call): logger.on_makereport() -class LoggerState(object): +class LoggerState: def __init__(self, item, stdoutloggers, fileloggers, formatter): self._put_newlines = bool(item.config.option.capture == 'no' and stdoutloggers) self.handlers = _make_handlers(stdoutloggers, fileloggers, item, formatter) @@ -142,7 +141,7 @@ def on_makereport(self): _disable(self.handlers) -class RootEnabler(object): +class RootEnabler: def __init__(self, enabled): self._enabled = enabled self._root_level = logging.root.level @@ -157,7 +156,7 @@ def disable(self): logging.root.setLevel(self._root_level) -class Loggers(object): +class Loggers: def __init__(self, stdout, file_): self.stdout = stdout self.file = file_ @@ -166,7 +165,7 @@ def __bool__(self): return bool(self.stdout) or bool(self.file) -class LoggerConfig(object): +class LoggerConfig: """Configuration of logging to stdout and filesystem.""" def __init__(self): @@ -230,7 +229,7 @@ def split_by_outcome(self, outcomes=None, subdir='by_outcome'): self._split_by_outcome_subdir = subdir -class LoggerHookspec(object): +class LoggerHookspec: def pytest_logger_config(self, logger_config): """ called before cmdline options parsing. Accepts terse configuration of both stdout and file logging, adds cmdline options to manipulate From 81c516e4b55a0e0be4d5e3695cb0b73f0773330d Mon Sep 17 00:00:00 2001 From: Krzysztof Laskowski Date: Mon, 19 Feb 2024 03:29:31 +0100 Subject: [PATCH 05/16] modernize: pytester instead of obsolete testdir --- tests/test_pytest_logger.py | 365 ++++++++++++++++++------------------ 1 file changed, 178 insertions(+), 187 deletions(-) diff --git a/tests/test_pytest_logger.py b/tests/test_pytest_logger.py index 74f93ca..9140275 100644 --- a/tests/test_pytest_logger.py +++ b/tests/test_pytest_logger.py @@ -3,42 +3,41 @@ import pytest import platform import textwrap +from pathlib import Path + win32 = sys.platform == 'win32' win32py2 = win32 and sys.version_info[0] == 2 win32pypy = win32 and platform.python_implementation() == 'PyPy' -def makefile(testdir, path, content): - return testdir.tmpdir.ensure(*path).write(textwrap.dedent(content)) - - -def ls(dir, filepath=''): - return sorted([x.basename for x in dir.join(filepath).listdir()]) +def makefile(path: Path, content: str): + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(textwrap.dedent(content)) + return path -def basetemp(testdir): - return testdir.tmpdir.join('..', 'basetemp') +def ls(dir: Path, filepath=''): + return sorted(os.listdir(dir / filepath)) -def outdir(testdir, dst): - return testdir.tmpdir.join('..', dst) +def basetemp(pytester): + return pytester.path.parent / 'basetemp' @pytest.fixture(autouse=True) -def set_classic_output(monkeypatch, testdir): - runpytest = testdir.runpytest +def set_classic_output(monkeypatch, pytester): + runpytest = pytester.runpytest def wrapper(*args, **kwargs): return runpytest('--override-ini=console_output_style=classic', *args, **kwargs) - monkeypatch.setattr(testdir, 'runpytest', wrapper) + monkeypatch.setattr(pytester, 'runpytest', wrapper) @pytest.fixture -def conftest_py(testdir): - filename = 'conftest.py' - makefile(testdir, [filename], """ +def conftest_py(pytester): + return makefile(pytester.path / 'conftest.py', """ import logging def pytest_logger_fileloggers(item): return [ @@ -46,13 +45,11 @@ def pytest_logger_fileloggers(item): ('bar', logging.ERROR), ] """) - return filename @pytest.fixture -def test_case_py(testdir): - filename = 'test_case.py' - makefile(testdir, [filename], """ +def test_case_py(pytester): + return makefile(pytester.path / 'test_case.py', """ import logging def test_case(): for lgr in (logging.getLogger(name) for name in ['foo', 'bar', 'baz']): @@ -60,17 +57,15 @@ def test_case(): lgr.warning('this is warning') lgr.info('this is info') """) - return filename class FileLineMatcher(pytest.LineMatcher): - def __init__(self, dir, filepath): - lines = dir.join(filepath).read().splitlines() - pytest.LineMatcher.__init__(self, lines) + def __init__(self, path: Path): + super().__init__(path.read_text().splitlines()) -def test_logdir_fixture(testdir): - makefile(testdir, ['test_foo1.py'], """ +def test_logdir_fixture(pytester): + makefile(pytester.path / 'test_foo1.py', """ import os def test_bar(logdir, tmpdir_factory): @@ -97,41 +92,41 @@ def test_par(logdir, param1, param2): def test_this_should_not_generate_logdir(): pass """) - makefile(testdir, ['subdir', 'test_foo2.py'], """ + makefile(pytester.path / 'subdir' / 'test_foo2.py', """ import os def test_bar(logdir): assert str(logdir).endswith(os.path.join('logs', 'subdir', 'test_foo2.py', 'test_bar')) """) - makefile(testdir, ['subdir', 'subsubdir', 'test_foo3.py'], """ + makefile(pytester.path / 'subdir' / 'subsubdir' / 'test_foo3.py', """ import os def test_bar(logdir): assert str(logdir).endswith(os.path.join('logs', 'subdir', 'subsubdir', 'test_foo3.py', 'test_bar')) """) - result = testdir.runpytest() + result = pytester.runpytest() assert result.ret == 0 - assert ls(basetemp(testdir), 'logs') == ['subdir', 'test_foo1.py'] - assert ls(basetemp(testdir), 'logs/subdir') == ['subsubdir', 'test_foo2.py'] - assert ls(basetemp(testdir), 'logs/subdir/subsubdir') == ['test_foo3.py'] - assert ls(basetemp(testdir), 'logs/subdir/subsubdir/test_foo3.py') == ['test_bar'] - assert ls(basetemp(testdir), 'logs/subdir/test_foo2.py') == ['test_bar'] - assert ls(basetemp(testdir), 'logs/test_foo1.py') == sorted([ + assert ls(basetemp(pytester), 'logs') == ['subdir', 'test_foo1.py'] + assert ls(basetemp(pytester), 'logs/subdir') == ['subsubdir', 'test_foo2.py'] + assert ls(basetemp(pytester), 'logs/subdir/subsubdir') == ['test_foo3.py'] + assert ls(basetemp(pytester), 'logs/subdir/subsubdir/test_foo3.py') == ['test_bar'] + assert ls(basetemp(pytester), 'logs/subdir/test_foo2.py') == ['test_bar'] + assert ls(basetemp(pytester), 'logs/test_foo1.py') == sorted([ 'test_bar', 'test_baz', 'TestInsideClass', 'test_par-abc-de', 'test_par-2-4.127', ]) - assert ls(basetemp(testdir), 'logs/test_foo1.py/TestInsideClass') == ['test_qez'] + assert ls(basetemp(pytester), 'logs/test_foo1.py/TestInsideClass') == ['test_qez'] -def test_stdout_handlers(testdir): - makefile(testdir, ['conftest.py'], """ +def test_stdout_handlers(pytester): + makefile(pytester.path / 'conftest.py', """ def pytest_logger_stdoutloggers(item): return ['foo'] """) - makefile(testdir, ['test_case.py'], """ + makefile(pytester.path / 'test_case.py', """ import logging def test_case(): logging.getLogger('foo').warning('this is warning') @@ -139,7 +134,7 @@ def test_case(): logging.getLogger('bar').warning('you do not see me: logger not handled') """) - result = testdir.runpytest() + result = pytester.runpytest() assert result.ret == 0 result.stdout.fnmatch_lines([ '', @@ -147,7 +142,7 @@ def test_case(): '', ]) - result = testdir.runpytest('-s') + result = pytester.runpytest('-s') assert result.ret == 0 result.stdout.fnmatch_lines([ '', @@ -158,8 +153,8 @@ def test_case(): ]) -def test_stdout_handlers_many_loggers(testdir): - makefile(testdir, ['conftest.py'], """ +def test_stdout_handlers_many_loggers(pytester): + makefile(pytester.path / 'conftest.py', """ import logging def pytest_logger_stdoutloggers(item): return [ @@ -168,7 +163,7 @@ def pytest_logger_stdoutloggers(item): ('baz', logging.FATAL) ] """) - makefile(testdir, ['test_case.py'], """ + makefile(pytester.path / 'test_case.py', """ import logging def test_case(): for lgr in (logging.getLogger(name) for name in ['foo', 'bar', 'baz']): @@ -177,7 +172,7 @@ def test_case(): lgr.warning('this is warning') """) - result = testdir.runpytest('-s') + result = pytester.runpytest('-s') assert result.ret == 0 result.stdout.fnmatch_lines([ '', @@ -193,9 +188,8 @@ def test_case(): ]) -def test_file_handlers(testdir, conftest_py, test_case_py): - - result = testdir.runpytest('-s') +def test_file_handlers(pytester, conftest_py, test_case_py): + result = pytester.runpytest('-s') assert result.ret == 0 result.stdout.fnmatch_lines([ '', @@ -203,22 +197,22 @@ def test_file_handlers(testdir, conftest_py, test_case_py): '', ]) - assert ls(basetemp(testdir), 'logs') == [test_case_py] - assert ls(basetemp(testdir), 'logs/{0}'.format(test_case_py)) == ['test_case'] - assert ls(basetemp(testdir), 'logs/{0}/test_case'.format(test_case_py)) == ['bar', 'foo'] + assert ls(basetemp(pytester), 'logs') == [test_case_py.name] + assert ls(basetemp(pytester), 'logs/{0}'.format(test_case_py.name)) == ['test_case'] + assert ls(basetemp(pytester), 'logs/{0}/test_case'.format(test_case_py.name)) == ['bar', 'foo'] - FileLineMatcher(basetemp(testdir), 'logs/{0}/test_case/foo'.format(test_case_py)).fnmatch_lines([ + FileLineMatcher(basetemp(pytester) / f'logs/{test_case_py.name}/test_case/foo').fnmatch_lines([ '* foo: this is error', '* foo: this is warning', ]) - FileLineMatcher(basetemp(testdir), 'logs/{0}/test_case/bar'.format(test_case_py)).fnmatch_lines([ + FileLineMatcher(basetemp(pytester) / f'logs/{test_case_py.name}/test_case/bar').fnmatch_lines([ '* bar: this is error', ]) @pytest.mark.skipif(win32py2, reason="python 2 on windows doesn't have symlink feature") -def test_split_logs_by_outcome(testdir): - makefile(testdir, ['conftest.py'], """ +def test_split_logs_by_outcome(pytester): + makefile(pytester.path / 'conftest.py', """ import logging def pytest_logger_fileloggers(item): return [ @@ -229,21 +223,21 @@ def pytest_logger_fileloggers(item): def pytest_logger_config(logger_config): logger_config.split_by_outcome(outcomes=['passed', 'failed']) """) - makefile(testdir, ['test_case.py'], """ - import pytest - import logging - def test_case_that_fails(): - for lgr in (logging.getLogger(name) for name in ['foo', 'bar', 'baz']): - lgr.error('this is error') - lgr.warning('this is warning') - pytest.fail('just checking') - - def test_case_that_passes(): - for lgr in (logging.getLogger(name) for name in ['foo', 'bar', 'baz']): - lgr.error('this is error') - lgr.warning('this is warning') - """) - result = testdir.runpytest('-s') + makefile(pytester.path / 'test_case.py', """ + import pytest + import logging + def test_case_that_fails(): + for lgr in (logging.getLogger(name) for name in ['foo', 'bar', 'baz']): + lgr.error('this is error') + lgr.warning('this is warning') + pytest.fail('just checking') + + def test_case_that_passes(): + for lgr in (logging.getLogger(name) for name in ['foo', 'bar', 'baz']): + lgr.error('this is error') + lgr.warning('this is warning') + """) + result = pytester.runpytest('-s') assert result.ret != 0 result.stdout.fnmatch_lines([ '', @@ -251,25 +245,25 @@ def test_case_that_passes(): '', ]) - assert 'by_outcome' in ls(basetemp(testdir).join('logs')) + assert 'by_outcome' in ls(basetemp(pytester) / 'logs') - assert 'failed' in ls(basetemp(testdir).join('logs', 'by_outcome')) - failedlogpath = basetemp(testdir).join('logs', 'by_outcome', 'failed', 'test_case.py', 'test_case_that_fails') - assert failedlogpath.islink() + assert 'failed' in ls(basetemp(pytester) / 'logs' / 'by_outcome') + failedlogpath = basetemp(pytester) / 'logs' / 'by_outcome' / 'failed' / 'test_case.py' / 'test_case_that_fails' + assert failedlogpath.is_symlink() failedlogdest = os.path.join( os.path.pardir, os.path.pardir, os.path.pardir, 'test_case.py', 'test_case_that_fails') assert os.readlink(str(failedlogpath)) == failedlogdest - assert 'passed' in ls(basetemp(testdir).join('logs', 'by_outcome')) - passedlogpath = basetemp(testdir).join('logs', 'by_outcome', 'passed', 'test_case.py', 'test_case_that_passes') - assert passedlogpath.islink() + assert 'passed' in ls(basetemp(pytester) / 'logs' / 'by_outcome') + passedlogpath = basetemp(pytester) / 'logs' / 'by_outcome' / 'passed' / 'test_case.py' / 'test_case_that_passes' + assert passedlogpath.is_symlink() passedlogdest = os.path.join( os.path.pardir, os.path.pardir, os.path.pardir, 'test_case.py', 'test_case_that_passes') assert os.readlink(str(passedlogpath)) == passedlogdest -def test_file_handlers_root(testdir): - makefile(testdir, ['conftest.py'], """ +def test_file_handlers_root(pytester): + makefile(pytester.path / 'conftest.py', """ import logging def pytest_logger_fileloggers(item): return [ @@ -277,7 +271,7 @@ def pytest_logger_fileloggers(item): ('foo', logging.WARNING), ] """) - makefile(testdir, ['test_case.py'], """ + makefile(pytester.path / 'test_case.py', """ import logging def test_case(): for lgr in (logging.getLogger(name) for name in ['foo', 'bar', 'baz']): @@ -285,7 +279,7 @@ def test_case(): lgr.warning('this is warning') """) - result = testdir.runpytest('-s') + result = pytester.runpytest('-s') assert result.ret == 0 result.stdout.fnmatch_lines([ @@ -294,50 +288,50 @@ def test_case(): '', ]) - assert ls(basetemp(testdir), 'logs') == ['test_case.py'] - assert ls(basetemp(testdir), 'logs/test_case.py') == ['test_case'] - assert ls(basetemp(testdir), 'logs/test_case.py/test_case') == ['foo', 'logs'] + assert ls(basetemp(pytester), 'logs') == ['test_case.py'] + assert ls(basetemp(pytester), 'logs/test_case.py') == ['test_case'] + assert ls(basetemp(pytester), 'logs/test_case.py/test_case') == ['foo', 'logs'] - FileLineMatcher(basetemp(testdir), 'logs/test_case.py/test_case/logs').fnmatch_lines([ + FileLineMatcher(basetemp(pytester) / 'logs/test_case.py/test_case/logs').fnmatch_lines([ '* foo: this is error', '* bar: this is error', '* baz: this is error', ]) - FileLineMatcher(basetemp(testdir), 'logs/test_case.py/test_case/foo').fnmatch_lines([ + FileLineMatcher(basetemp(pytester) / 'logs/test_case.py/test_case/foo').fnmatch_lines([ '* foo: this is error', '* foo: this is warning', ]) @pytest.mark.skipif(win32py2, reason="python 2 on windows doesn't have symlink feature") -def test_logdir_link(testdir): - makefile(testdir, ['conftest.py'], """ +def test_logdir_link(pytester): + makefile(pytester.path / 'conftest.py', """ import os def pytest_logger_fileloggers(item): return [''] def pytest_logger_logdirlink(config): return os.path.join(os.path.dirname(__file__), 'my_link_dir') """) - makefile(testdir, ['test_case.py'], """ + makefile(pytester.path / 'test_case.py', """ def test_case(): pass """) - result = testdir.runpytest('-s') + result = pytester.runpytest('-s') assert result.ret == 0 - assert 'my_link_dir' in ls(testdir.tmpdir) - assert ['test_case'] == ls(testdir.tmpdir, 'my_link_dir/test_case.py') + assert 'my_link_dir' in ls(pytester.path) + assert ['test_case'] == ls(pytester.path, 'my_link_dir/test_case.py') -def test_logsdir(testdir): - makefile(testdir, ['conftest.py'], """ +def test_logsdir(pytester): + makefile(pytester.path / 'conftest.py', """ import os def pytest_logger_fileloggers(item): return [''] def pytest_logger_logsdir(config): return os.path.join(os.path.dirname(__file__), 'my_logs_dir') """) - makefile(testdir, ['test_cases.py'], """ + makefile(pytester.path / 'test_cases.py', """ import pytest def test_simple(): @@ -353,18 +347,18 @@ def test_param(param1, param2): pass """) - result = testdir.runpytest('-s') + result = pytester.runpytest('-s') assert result.ret == 0 - assert 'my_logs_dir' in ls(testdir.tmpdir) - assert 'test_simple' in ls(testdir.tmpdir, 'my_logs_dir/test_cases.py') - assert 'test_param-x-a_b_c' in ls(testdir.tmpdir, 'my_logs_dir/test_cases.py') - assert 'test_param-y-d-e-f' in ls(testdir.tmpdir, 'my_logs_dir/test_cases.py') - assert 'test_param-z-g-h-i' in ls(testdir.tmpdir, 'my_logs_dir/test_cases.py') - assert 'test_param-v-j-1-k-1-l-1' in ls(testdir.tmpdir, 'my_logs_dir/test_cases.py') + assert 'my_logs_dir' in ls(pytester.path) + assert 'test_simple' in ls(pytester.path, 'my_logs_dir/test_cases.py') + assert 'test_param-x-a_b_c' in ls(pytester.path, 'my_logs_dir/test_cases.py') + assert 'test_param-y-d-e-f' in ls(pytester.path, 'my_logs_dir/test_cases.py') + assert 'test_param-z-g-h-i' in ls(pytester.path, 'my_logs_dir/test_cases.py') + assert 'test_param-v-j-1-k-1-l-1' in ls(pytester.path, 'my_logs_dir/test_cases.py') -def test_format(testdir): - makefile(testdir, ['conftest.py'], """ +def test_format(pytester): + makefile(pytester.path / 'conftest.py', """ import os import logging def pytest_logger_stdoutloggers(item): @@ -372,7 +366,7 @@ def pytest_logger_stdoutloggers(item): def pytest_logger_fileloggers(item): return [''] """) - makefile(testdir, ['test_case.py'], """ + makefile(pytester.path / 'test_case.py', """ import logging def test_case(): lgr = logging.getLogger('foo') @@ -384,7 +378,7 @@ def test_case(): lgr.log(35, 'this is 35') """) - result = testdir.runpytest('-s') + result = pytester.runpytest('-s') assert result.ret == 0 expected_lines = [ @@ -396,11 +390,11 @@ def test_case(): '*:*.* l35 foo: this is 35', ] result.stdout.fnmatch_lines(expected_lines) - FileLineMatcher(basetemp(testdir), 'logs/test_case.py/test_case/logs').fnmatch_lines(expected_lines) + FileLineMatcher(basetemp(pytester) / 'logs/test_case.py/test_case/logs').fnmatch_lines(expected_lines) -def test_multiple_conftests(testdir): - makefile(testdir, ['conftest.py'], """ +def test_multiple_conftests(pytester): + makefile(pytester.path / 'conftest.py', """ import os def pytest_logger_stdoutloggers(item): return ['foo'] @@ -409,7 +403,7 @@ def pytest_logger_fileloggers(item): def pytest_logger_logdirlink(config): return os.path.join(os.path.dirname(__file__), 'logs') """) - makefile(testdir, ['subdir', 'conftest.py'], """ + makefile(pytester.path / 'subdir' / 'conftest.py', """ import os def pytest_logger_stdoutloggers(item): return ['bar'] @@ -418,20 +412,20 @@ def pytest_logger_fileloggers(item): def pytest_logger_logdirlink(config): return os.path.join(os.path.dirname(__file__), 'logs') """) - makefile(testdir, ['subdir', 'test_case.py'], """ + makefile(pytester.path / 'subdir' / 'test_case.py', """ import logging def test_case(): for lgr in (logging.getLogger(name) for name in ['foo', 'bar']): lgr.warning('this is warning') """) - makefile(testdir, ['makes_nodeid_in_pytest29_contain_subdir_name', 'empty'], '') + makefile(pytester.path / 'makes_nodeid_in_pytest29_contain_subdir_name' / 'empty', '') - result = testdir.runpytest('subdir', 'makes_nodeid_in_pytest29_contain_subdir_name', '-s') + result = pytester.runpytest('subdir', 'makes_nodeid_in_pytest29_contain_subdir_name', '-s') assert result.ret == 0 if not win32py2: - assert ls(testdir.tmpdir, 'logs/subdir/test_case.py') == ['test_case'] - assert ls(testdir.tmpdir, 'subdir/logs/subdir/test_case.py') == ['test_case'] + assert ls(pytester.path, 'logs/subdir/test_case.py') == ['test_case'] + assert ls(pytester.path, 'subdir/logs/subdir/test_case.py') == ['test_case'] result.stdout.fnmatch_lines([ '', @@ -442,16 +436,16 @@ def test_case(): '' ]) - FileLineMatcher(basetemp(testdir), 'logs/subdir/test_case.py/test_case/foo').fnmatch_lines([ + FileLineMatcher(basetemp(pytester) / 'logs/subdir/test_case.py/test_case/foo').fnmatch_lines([ '* foo: this is warning', ]) - FileLineMatcher(basetemp(testdir), 'logs/subdir/test_case.py/test_case/bar').fnmatch_lines([ + FileLineMatcher(basetemp(pytester) / 'logs/subdir/test_case.py/test_case/bar').fnmatch_lines([ '* bar: this is warning', ]) -def test_skip_gracefully(testdir): - makefile(testdir, ['conftest.py'], """ +def test_skip_gracefully(pytester): + makefile(pytester.path / 'conftest.py', """ import os def pytest_logger_stdoutloggers(item): return ['foo'] @@ -460,23 +454,23 @@ def pytest_logger_fileloggers(item): def pytest_logger_logdirlink(config): return os.path.join(os.path.dirname(__file__), 'logs') """) - makefile(testdir, ['test_case.py'], """ + makefile(pytester.path / 'test_case.py', """ import pytest @pytest.mark.skipif(True, reason='') def test_case(): pass """) - result = testdir.runpytest('-s') + result = pytester.runpytest('-s') assert result.ret == 0 - assert 'logs' not in ls(testdir.tmpdir) + assert 'logs' not in ls(pytester.path) @pytest.mark.skipif(win32pypy, reason="pytest-xdist crashes on win32 under pypy") -def test_xdist(testdir): +def test_xdist(pytester): N = 8 - makefile(testdir, ['conftest.py'], """ + makefile(pytester.path / 'conftest.py', """ import os def pytest_logger_stdoutloggers(item): return ['foo'] @@ -486,27 +480,26 @@ def pytest_logger_logdirlink(config): return os.path.join(os.path.dirname(__file__), 'logs') """) for index in range(N): - makefile(testdir, ['test_case%s.py' % index], """ + makefile(pytester.path / f'test_case{index}.py', """ import logging def test_case{0}(): logging.getLogger('foo').warning('this is test {0}') """.format(index)) - result = testdir.runpytest('-n3') + result = pytester.runpytest('-n3') assert result.ret == 0 if not win32py2: - assert ls(testdir.tmpdir, 'logs') == ['test_case%s.py' % i for i in range(N)] + assert ls(pytester.path, 'logs') == ['test_case%s.py' % i for i in range(N)] for index in range(N): logfilename = 'logs/test_case{0}.py/test_case{0}/foo'.format(index) - FileLineMatcher(basetemp(testdir), logfilename).fnmatch_lines(['* wrn foo: this is test %s' % index]) - + FileLineMatcher(basetemp(pytester) / logfilename).fnmatch_lines(['* wrn foo: this is test %s' % index]) -def test_logsdir_option(testdir, conftest_py, test_case_py): - logsdir = outdir(testdir, 'myinilogs') - result = testdir.runpytest('-s', '--logger-logsdir={0}'.format(str(logsdir))) +def test_logsdir_option(pytester, conftest_py, test_case_py): + logsdir = pytester.path / 'myinilogs' + result = pytester.runpytest('-s', '--logger-logsdir={0}'.format(str(logsdir))) assert result.ret == 0 result.stdout.fnmatch_lines([ '', @@ -514,28 +507,27 @@ def test_logsdir_option(testdir, conftest_py, test_case_py): '', ]) - assert ls(logsdir) == [test_case_py] - assert ls(logsdir, test_case_py) == ['test_case'] - assert ls(logsdir, '{0}/test_case'.format(test_case_py)) == ['bar', 'foo'] + assert ls(logsdir) == [test_case_py.name] + assert ls(logsdir, test_case_py.name) == ['test_case'] + assert ls(logsdir, '{0}/test_case'.format(test_case_py.name)) == ['bar', 'foo'] - FileLineMatcher(logsdir, '{0}/test_case/foo'.format(test_case_py)).fnmatch_lines([ + FileLineMatcher(logsdir / '{0}/test_case/foo'.format(test_case_py.name)).fnmatch_lines([ '* foo: this is error', '* foo: this is warning', ]) - FileLineMatcher(logsdir, '{0}/test_case/bar'.format(test_case_py)).fnmatch_lines([ + FileLineMatcher(logsdir / '{0}/test_case/bar'.format(test_case_py.name)).fnmatch_lines([ '* bar: this is error', ]) -def test_logsdir_ini(testdir, conftest_py, test_case_py): - - logsdir = outdir(testdir, 'myinilogs') - makefile(testdir, ['pytest.ini'], """ +def test_logsdir_ini(pytester, conftest_py, test_case_py): + logsdir = pytester.path / 'myinilogs' + makefile(pytester.path / 'pytest.ini', """ [pytest] logger_logsdir={0} """.format(logsdir)) - result = testdir.runpytest('-s') + result = pytester.runpytest('-s') assert result.ret == 0 result.stdout.fnmatch_lines([ '', @@ -543,32 +535,31 @@ def test_logsdir_ini(testdir, conftest_py, test_case_py): '', ]) - assert ls(logsdir) == [test_case_py] - assert ls(logsdir, test_case_py) == ['test_case'] - assert ls(logsdir, '{0}/test_case'.format(test_case_py)) == ['bar', 'foo'] + assert ls(logsdir) == [test_case_py.name] + assert ls(logsdir, test_case_py.name) == ['test_case'] + assert ls(logsdir, '{0}/test_case'.format(test_case_py.name)) == ['bar', 'foo'] - FileLineMatcher(logsdir, '{0}/test_case/foo'.format(test_case_py)).fnmatch_lines([ + FileLineMatcher(logsdir / '{0}/test_case/foo'.format(test_case_py.name)).fnmatch_lines([ '* foo: this is error', '* foo: this is warning', ]) - FileLineMatcher(logsdir, '{0}/test_case/bar'.format(test_case_py)).fnmatch_lines([ + FileLineMatcher(logsdir / '{0}/test_case/bar'.format(test_case_py.name)).fnmatch_lines([ '* bar: this is error', ]) -def test_logsdir_cleanup(testdir, conftest_py, test_case_py): - - logsdir = outdir(testdir, 'myinilogs') +def test_logsdir_cleanup(pytester, conftest_py, test_case_py): + logsdir = pytester.path / 'myinilogs' - makefile(testdir, ['pytest.ini'], """ + makefile(pytester.path / 'pytest.ini', """ [pytest] logger_logsdir={0} """.format(logsdir)) + makefile(logsdir / 'tmpfile', """ + this shall be removed + """) - logsdir.ensure('tmpfile').write(textwrap.dedent('this shall be removed')) - logsdir.join('tmpdir') - - result = testdir.runpytest('-s') + result = pytester.runpytest('-s') assert result.ret == 0 result.stdout.fnmatch_lines([ '', @@ -576,28 +567,28 @@ def test_logsdir_cleanup(testdir, conftest_py, test_case_py): '', ]) - assert ls(logsdir) == [test_case_py] - assert ls(logsdir, test_case_py) == ['test_case'] - assert ls(logsdir, '{0}/test_case'.format(test_case_py)) == ['bar', 'foo'] + assert ls(logsdir) == [test_case_py.name] + assert ls(logsdir, test_case_py.name) == ['test_case'] + assert ls(logsdir, '{0}/test_case'.format(test_case_py.name)) == ['bar', 'foo'] - FileLineMatcher(logsdir, '{0}/test_case/foo'.format(test_case_py)).fnmatch_lines([ + FileLineMatcher(logsdir / '{0}/test_case/foo'.format(test_case_py.name)).fnmatch_lines([ '* foo: this is error', '* foo: this is warning', ]) - FileLineMatcher(logsdir, '{0}/test_case/bar'.format(test_case_py)).fnmatch_lines([ + FileLineMatcher(logsdir / '{0}/test_case/bar'.format(test_case_py.name)).fnmatch_lines([ '* bar: this is error', ]) -def test_logger_config(testdir, test_case_py): - makefile(testdir, ['conftest.py'], """ +def test_logger_config(pytester, test_case_py): + makefile(pytester.path / 'conftest.py', """ def pytest_logger_config(logger_config): logger_config.add_loggers(['foo', 'bar'], stdout_level='warning', file_level='info') logger_config.add_loggers(['baz'], stdout_level='error', file_level='warning') logger_config.set_log_option_default('foo,bar,baz') """) - result = testdir.runpytest('-s') + result = pytester.runpytest('-s') assert result.ret == 0 result.stdout.fnmatch_lines([ @@ -611,32 +602,32 @@ def pytest_logger_config(logger_config): '.', '', ]) - FileLineMatcher(basetemp(testdir), 'logs/test_case.py/test_case/foo').fnmatch_lines([ + FileLineMatcher(basetemp(pytester) / 'logs/test_case.py/test_case/foo').fnmatch_lines([ '* err foo: this is error', '* wrn foo: this is warning', '* inf foo: this is info', ]) - FileLineMatcher(basetemp(testdir), 'logs/test_case.py/test_case/bar').fnmatch_lines([ + FileLineMatcher(basetemp(pytester) / 'logs/test_case.py/test_case/bar').fnmatch_lines([ '* err bar: this is error', '* wrn bar: this is warning', '* inf bar: this is info', ]) - FileLineMatcher(basetemp(testdir), 'logs/test_case.py/test_case/baz').fnmatch_lines([ + FileLineMatcher(basetemp(pytester) / 'logs/test_case.py/test_case/baz').fnmatch_lines([ '* err baz: this is error', '* wrn baz: this is warning', ]) @pytest.mark.parametrize('log_option', ('', '--loggers=foo.info,baz')) -def test_logger_config_option(testdir, test_case_py, log_option): - makefile(testdir, ['conftest.py'], """ +def test_logger_config_option(pytester, test_case_py, log_option): + makefile(pytester.path / 'conftest.py', """ def pytest_logger_config(logger_config): logger_config.add_loggers(['foo', 'bar']) logger_config.add_loggers(['baz'], file_level='error') """) opts = ('-s', log_option) if log_option else ('-s',) - result = testdir.runpytest(*opts) + result = pytester.runpytest(*opts) assert result.ret == 0 if log_option: @@ -659,8 +650,8 @@ def pytest_logger_config(logger_config): @pytest.mark.parametrize('log_option', ('', '--loggers=foo.info,baz')) -def test_logger_config_formatter(testdir, test_case_py, log_option): - makefile(testdir, ['conftest.py'], """ +def test_logger_config_formatter(pytester, test_case_py, log_option): + makefile(pytester.path / 'conftest.py', """ import logging def pytest_logger_config(logger_config): @@ -670,7 +661,7 @@ def pytest_logger_config(logger_config): """) opts = ('-s', log_option) if log_option else ('-s',) - result = testdir.runpytest(*opts) + result = pytester.runpytest(*opts) assert result.ret == 0 if log_option: @@ -693,8 +684,8 @@ def pytest_logger_config(logger_config): @pytest.mark.parametrize('with_hook', (False, True)) -def test_logger_config_option_missing_without_hook(testdir, test_case_py, with_hook): - makefile(testdir, ['conftest.py'], """ +def test_logger_config_option_missing_without_hook(pytester, test_case_py, with_hook): + makefile(pytester.path / 'conftest.py', """ def pytest_addoption(parser): parser.addoption('--loggers') """ + (""" @@ -703,7 +694,7 @@ def pytest_logger_config(logger_config): logger_config.add_loggers(['baz'], stdout_level='error', file_level='warning') """ if with_hook else "")) - result = testdir.runpytest('-s', '--loggers=foo') + result = pytester.runpytest('-s', '--loggers=foo') assert result.ret == (3 if with_hook else 0) if with_hook: @@ -714,8 +705,8 @@ def pytest_logger_config(logger_config): @pytest.mark.parametrize('stdout_hook', (False, True)) @pytest.mark.parametrize('config_hook', (False, True)) -def test_error_both_hook_apis_used(testdir, test_case_py, stdout_hook, config_hook): - makefile(testdir, ['conftest.py'], (""" +def test_error_both_hook_apis_used(pytester, test_case_py, stdout_hook, config_hook): + makefile(pytester.path / 'conftest.py', (""" def pytest_logger_stdoutloggers(item): return ['foo'] """ if stdout_hook else '') + (""" @@ -723,7 +714,7 @@ def pytest_logger_config(logger_config): logger_config.add_loggers(['foo']) """ if config_hook else '')) - result = testdir.runpytest('-s') + result = pytester.runpytest('-s') assert result.ret == (1 if (stdout_hook and config_hook) else 0) if stdout_hook and config_hook: @@ -732,7 +723,7 @@ def pytest_logger_config(logger_config): ]) -def test_help_prints(testdir, test_case_py): +def test_help_prints(pytester, test_case_py): """ Pytest doesn't evaluate group.addoption(..., type=...) option when run with --help option. This causes log option string to remain as unchecked string instead of a list in expected format. @@ -741,13 +732,13 @@ def test_help_prints(testdir, test_case_py): To remedy this hack checking whether option has been parsed was made. This test ensures that it keeps working. """ - makefile(testdir, ['conftest.py'], (""" + makefile(pytester.path / 'conftest.py', """ def pytest_logger_config(logger_config): logger_config.add_loggers(['foo']) logger_config.set_log_option_default('foo') - """)) + """) - result = testdir.runpytest('-s', '--help') + result = pytester.runpytest('-s', '--help') assert result.ret == 0 @@ -760,14 +751,14 @@ def test_works_with_progress_percentage_prints(): assert False -def test_collects_teardown_logs(testdir): - makefile(testdir, ['conftest.py'], """ +def test_collects_teardown_logs(pytester): + makefile(pytester.path / 'conftest.py', """ def pytest_logger_config(logger_config): logger_config.add_loggers(['foo']) logger_config.set_log_option_default('foo') """) - makefile(testdir, ['test_bar.py'], """ + makefile(pytester.path / 'test_bar.py', """ import logging import pytest logger = logging.getLogger('foo') @@ -782,10 +773,10 @@ def test_bar(): logger.info('test_bar') """) - result = testdir.runpytest() + result = pytester.runpytest() assert result.ret == 0 - FileLineMatcher(basetemp(testdir), 'logs/test_bar.py/test_bar/foo').fnmatch_lines([ + FileLineMatcher(basetemp(pytester) / 'logs/test_bar.py/test_bar/foo').fnmatch_lines([ '* inf foo: setup', '* inf foo: test_bar', '* inf foo: teardown', From a7f40ebe9b56571bcbd165482ae15df5a2194471 Mon Sep 17 00:00:00 2001 From: Krzysztof Laskowski Date: Mon, 19 Feb 2024 03:58:29 +0100 Subject: [PATCH 06/16] modernize: windows & python2/pypy checks are no longer needed --- tests/test_pytest_logger.py | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/tests/test_pytest_logger.py b/tests/test_pytest_logger.py index 9140275..f78817d 100644 --- a/tests/test_pytest_logger.py +++ b/tests/test_pytest_logger.py @@ -1,16 +1,9 @@ import os -import sys import pytest -import platform import textwrap from pathlib import Path -win32 = sys.platform == 'win32' -win32py2 = win32 and sys.version_info[0] == 2 -win32pypy = win32 and platform.python_implementation() == 'PyPy' - - def makefile(path: Path, content: str): path.parent.mkdir(parents=True, exist_ok=True) path.write_text(textwrap.dedent(content)) @@ -210,7 +203,6 @@ def test_file_handlers(pytester, conftest_py, test_case_py): ]) -@pytest.mark.skipif(win32py2, reason="python 2 on windows doesn't have symlink feature") def test_split_logs_by_outcome(pytester): makefile(pytester.path / 'conftest.py', """ import logging @@ -303,7 +295,6 @@ def test_case(): ]) -@pytest.mark.skipif(win32py2, reason="python 2 on windows doesn't have symlink feature") def test_logdir_link(pytester): makefile(pytester.path / 'conftest.py', """ import os @@ -423,9 +414,8 @@ def test_case(): result = pytester.runpytest('subdir', 'makes_nodeid_in_pytest29_contain_subdir_name', '-s') assert result.ret == 0 - if not win32py2: - assert ls(pytester.path, 'logs/subdir/test_case.py') == ['test_case'] - assert ls(pytester.path, 'subdir/logs/subdir/test_case.py') == ['test_case'] + assert ls(pytester.path, 'logs/subdir/test_case.py') == ['test_case'] + assert ls(pytester.path, 'subdir/logs/subdir/test_case.py') == ['test_case'] result.stdout.fnmatch_lines([ '', @@ -467,7 +457,6 @@ def test_case(): assert 'logs' not in ls(pytester.path) -@pytest.mark.skipif(win32pypy, reason="pytest-xdist crashes on win32 under pypy") def test_xdist(pytester): N = 8 makefile(pytester.path / 'conftest.py', """ @@ -489,8 +478,7 @@ def test_case{0}(): result = pytester.runpytest('-n3') assert result.ret == 0 - if not win32py2: - assert ls(pytester.path, 'logs') == ['test_case%s.py' % i for i in range(N)] + assert ls(pytester.path, 'logs') == ['test_case%s.py' % i for i in range(N)] for index in range(N): logfilename = 'logs/test_case{0}.py/test_case{0}/foo'.format(index) From 7bd9a5d764d2f3cdd4f3822984bd5b4c4580f455 Mon Sep 17 00:00:00 2001 From: Krzysztof Laskowski Date: Mon, 19 Feb 2024 23:05:47 +0100 Subject: [PATCH 07/16] ci: github workflow tests for pytest --- .github/workflows/test.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d89ffd4..1924233 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,6 +19,8 @@ jobs: matrix: name: - ubuntu-py310-lintcov + - ubuntu-py310-pytest6 + - ubuntu-py310-pytest7 - ubuntu-py37 - ubuntu-py38 - ubuntu-py39 @@ -32,6 +34,12 @@ jobs: python: "3.10" tox_env: check,coverage coverage: true + - name: ubuntu-py310-pytest6 + python: "3.10" + tox_env: py310-pytest6 + - name: ubuntu-py310-pytest7 + python: "3.10" + tox_env: py310-pytest7 - name: ubuntu-py37 python: "3.7" tox_env: py37 From 898eef9fb3be13f60c30a4bf1b5c0444158d1b96 Mon Sep 17 00:00:00 2001 From: Krzysztof Laskowski Date: Mon, 19 Feb 2024 23:44:17 +0100 Subject: [PATCH 08/16] fix: pytest6 does not have LineMatcher exported as public type --- tests/test_pytest_logger.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test_pytest_logger.py b/tests/test_pytest_logger.py index f78817d..ed0173e 100644 --- a/tests/test_pytest_logger.py +++ b/tests/test_pytest_logger.py @@ -2,6 +2,10 @@ import pytest import textwrap from pathlib import Path +try: + from pytest import LineMatcher +except ImportError: + from _pytest.pytester import LineMatcher # for pytest 6 def makefile(path: Path, content: str): @@ -52,7 +56,7 @@ def test_case(): """) -class FileLineMatcher(pytest.LineMatcher): +class FileLineMatcher(LineMatcher): def __init__(self, path: Path): super().__init__(path.read_text().splitlines()) From fce6152a15d7aaccc7844551c4b0394f1f579bd7 Mon Sep 17 00:00:00 2001 From: Krzysztof Laskowski Date: Mon, 19 Feb 2024 23:44:53 +0100 Subject: [PATCH 09/16] fix: exception/warning in pytest6 during test teardown --- tests/test_pytest_logger.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_pytest_logger.py b/tests/test_pytest_logger.py index ed0173e..0c354f0 100644 --- a/tests/test_pytest_logger.py +++ b/tests/test_pytest_logger.py @@ -686,8 +686,8 @@ def pytest_logger_config(logger_config): logger_config.add_loggers(['baz'], stdout_level='error', file_level='warning') """ if with_hook else "")) - result = pytester.runpytest('-s', '--loggers=foo') - assert result.ret == (3 if with_hook else 0) + result = pytester.runpytest_subprocess('-s', '--loggers=foo') + assert result.ret == (1 if with_hook else 0) if with_hook: result.stderr.fnmatch_lines([ From 35f20ca96e3f94623c18234d6ac64bee2103be44 Mon Sep 17 00:00:00 2001 From: Krzysztof Laskowski Date: Tue, 20 Feb 2024 00:20:41 +0100 Subject: [PATCH 10/16] modernize: new-style hook wrapper for pytest_runtest_makereport --- pytest_logger/plugin.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pytest_logger/plugin.py b/pytest_logger/plugin.py index 1648b22..5ba8fd6 100644 --- a/pytest_logger/plugin.py +++ b/pytest_logger/plugin.py @@ -100,14 +100,13 @@ def pytest_runtest_teardown(self, item, nextitem): if logger: logger.on_teardown() - @pytest.hookimpl(hookwrapper=True) + @pytest.hookimpl(wrapper=True) def pytest_runtest_makereport(self, item, call): - outcome = yield - tr = outcome.get_result() + report = yield logger = getattr(item, '_logger', None) if logger: - if self._logsdir and self._split_by_outcome_subdir and tr.outcome in self._split_by_outcome_outcomes: - split_by_outcome_logdir = self._logsdir / self._split_by_outcome_subdir / tr.outcome + if self._logsdir and self._split_by_outcome_subdir and report.outcome in self._split_by_outcome_outcomes: + split_by_outcome_logdir = self._logsdir / self._split_by_outcome_subdir / report.outcome nodeid = _sanitize_nodeid(item.nodeid) nodepath = os.path.dirname(nodeid) outcomedir = split_by_outcome_logdir / nodepath @@ -116,6 +115,7 @@ def pytest_runtest_makereport(self, item, call): _refresh_link(destdir_relpath, split_by_outcome_logdir / nodeid) if call.when == 'teardown': logger.on_makereport() + return report class LoggerState: From 90595a54c72c7744c6f3b83643524586eebdc616 Mon Sep 17 00:00:00 2001 From: Krzysztof Laskowski Date: Tue, 20 Feb 2024 00:47:08 +0100 Subject: [PATCH 11/16] modernize: use f-strings instead of format --- tests/test_pytest_logger.py | 46 ++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/tests/test_pytest_logger.py b/tests/test_pytest_logger.py index 0c354f0..c6a9a22 100644 --- a/tests/test_pytest_logger.py +++ b/tests/test_pytest_logger.py @@ -195,8 +195,8 @@ def test_file_handlers(pytester, conftest_py, test_case_py): ]) assert ls(basetemp(pytester), 'logs') == [test_case_py.name] - assert ls(basetemp(pytester), 'logs/{0}'.format(test_case_py.name)) == ['test_case'] - assert ls(basetemp(pytester), 'logs/{0}/test_case'.format(test_case_py.name)) == ['bar', 'foo'] + assert ls(basetemp(pytester), f'logs/{test_case_py.name}') == ['test_case'] + assert ls(basetemp(pytester), f'logs/{test_case_py.name}/test_case') == ['bar', 'foo'] FileLineMatcher(basetemp(pytester) / f'logs/{test_case_py.name}/test_case/foo').fnmatch_lines([ '* foo: this is error', @@ -473,11 +473,11 @@ def pytest_logger_logdirlink(config): return os.path.join(os.path.dirname(__file__), 'logs') """) for index in range(N): - makefile(pytester.path / f'test_case{index}.py', """ + makefile(pytester.path / f'test_case{index}.py', f""" import logging - def test_case{0}(): - logging.getLogger('foo').warning('this is test {0}') - """.format(index)) + def test_case{index}(): + logging.getLogger('foo').warning('this is test {index}') + """) result = pytester.runpytest('-n3') assert result.ret == 0 @@ -485,13 +485,13 @@ def test_case{0}(): assert ls(pytester.path, 'logs') == ['test_case%s.py' % i for i in range(N)] for index in range(N): - logfilename = 'logs/test_case{0}.py/test_case{0}/foo'.format(index) + logfilename = f'logs/test_case{index}.py/test_case{index}/foo' FileLineMatcher(basetemp(pytester) / logfilename).fnmatch_lines(['* wrn foo: this is test %s' % index]) def test_logsdir_option(pytester, conftest_py, test_case_py): logsdir = pytester.path / 'myinilogs' - result = pytester.runpytest('-s', '--logger-logsdir={0}'.format(str(logsdir))) + result = pytester.runpytest('-s', f'--logger-logsdir={logsdir}') assert result.ret == 0 result.stdout.fnmatch_lines([ '', @@ -501,23 +501,23 @@ def test_logsdir_option(pytester, conftest_py, test_case_py): assert ls(logsdir) == [test_case_py.name] assert ls(logsdir, test_case_py.name) == ['test_case'] - assert ls(logsdir, '{0}/test_case'.format(test_case_py.name)) == ['bar', 'foo'] + assert ls(logsdir, f'{test_case_py.name}/test_case') == ['bar', 'foo'] - FileLineMatcher(logsdir / '{0}/test_case/foo'.format(test_case_py.name)).fnmatch_lines([ + FileLineMatcher(logsdir / f'{test_case_py.name}/test_case/foo').fnmatch_lines([ '* foo: this is error', '* foo: this is warning', ]) - FileLineMatcher(logsdir / '{0}/test_case/bar'.format(test_case_py.name)).fnmatch_lines([ + FileLineMatcher(logsdir / f'{test_case_py.name}/test_case/bar').fnmatch_lines([ '* bar: this is error', ]) def test_logsdir_ini(pytester, conftest_py, test_case_py): logsdir = pytester.path / 'myinilogs' - makefile(pytester.path / 'pytest.ini', """ + makefile(pytester.path / 'pytest.ini', f""" [pytest] - logger_logsdir={0} - """.format(logsdir)) + logger_logsdir={logsdir} + """) result = pytester.runpytest('-s') assert result.ret == 0 @@ -529,13 +529,13 @@ def test_logsdir_ini(pytester, conftest_py, test_case_py): assert ls(logsdir) == [test_case_py.name] assert ls(logsdir, test_case_py.name) == ['test_case'] - assert ls(logsdir, '{0}/test_case'.format(test_case_py.name)) == ['bar', 'foo'] + assert ls(logsdir, f'{test_case_py.name}/test_case') == ['bar', 'foo'] - FileLineMatcher(logsdir / '{0}/test_case/foo'.format(test_case_py.name)).fnmatch_lines([ + FileLineMatcher(logsdir / f'{test_case_py.name}/test_case/foo').fnmatch_lines([ '* foo: this is error', '* foo: this is warning', ]) - FileLineMatcher(logsdir / '{0}/test_case/bar'.format(test_case_py.name)).fnmatch_lines([ + FileLineMatcher(logsdir / f'{test_case_py.name}/test_case/bar').fnmatch_lines([ '* bar: this is error', ]) @@ -543,10 +543,10 @@ def test_logsdir_ini(pytester, conftest_py, test_case_py): def test_logsdir_cleanup(pytester, conftest_py, test_case_py): logsdir = pytester.path / 'myinilogs' - makefile(pytester.path / 'pytest.ini', """ + makefile(pytester.path / 'pytest.ini', f""" [pytest] - logger_logsdir={0} - """.format(logsdir)) + logger_logsdir={logsdir} + """) makefile(logsdir / 'tmpfile', """ this shall be removed """) @@ -561,13 +561,13 @@ def test_logsdir_cleanup(pytester, conftest_py, test_case_py): assert ls(logsdir) == [test_case_py.name] assert ls(logsdir, test_case_py.name) == ['test_case'] - assert ls(logsdir, '{0}/test_case'.format(test_case_py.name)) == ['bar', 'foo'] + assert ls(logsdir, f'{test_case_py.name}/test_case') == ['bar', 'foo'] - FileLineMatcher(logsdir / '{0}/test_case/foo'.format(test_case_py.name)).fnmatch_lines([ + FileLineMatcher(logsdir / f'{test_case_py.name}/test_case/foo').fnmatch_lines([ '* foo: this is error', '* foo: this is warning', ]) - FileLineMatcher(logsdir / '{0}/test_case/bar'.format(test_case_py.name)).fnmatch_lines([ + FileLineMatcher(logsdir / f'{test_case_py.name}/test_case/bar').fnmatch_lines([ '* bar: this is error', ]) From cf9a50fc0202465d4c5665c010b10b1a574c0ab0 Mon Sep 17 00:00:00 2001 From: Krzysztof Laskowski Date: Tue, 20 Feb 2024 00:51:00 +0100 Subject: [PATCH 12/16] modernize: use single argument ls --- tests/test_pytest_logger.py | 60 ++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/tests/test_pytest_logger.py b/tests/test_pytest_logger.py index c6a9a22..4a5b039 100644 --- a/tests/test_pytest_logger.py +++ b/tests/test_pytest_logger.py @@ -14,8 +14,8 @@ def makefile(path: Path, content: str): return path -def ls(dir: Path, filepath=''): - return sorted(os.listdir(dir / filepath)) +def ls(dir: Path): + return sorted(os.listdir(dir)) def basetemp(pytester): @@ -103,19 +103,19 @@ def test_bar(logdir): result = pytester.runpytest() assert result.ret == 0 - assert ls(basetemp(pytester), 'logs') == ['subdir', 'test_foo1.py'] - assert ls(basetemp(pytester), 'logs/subdir') == ['subsubdir', 'test_foo2.py'] - assert ls(basetemp(pytester), 'logs/subdir/subsubdir') == ['test_foo3.py'] - assert ls(basetemp(pytester), 'logs/subdir/subsubdir/test_foo3.py') == ['test_bar'] - assert ls(basetemp(pytester), 'logs/subdir/test_foo2.py') == ['test_bar'] - assert ls(basetemp(pytester), 'logs/test_foo1.py') == sorted([ + assert ls(basetemp(pytester) / 'logs') == ['subdir', 'test_foo1.py'] + assert ls(basetemp(pytester) / 'logs/subdir') == ['subsubdir', 'test_foo2.py'] + assert ls(basetemp(pytester) / 'logs/subdir/subsubdir') == ['test_foo3.py'] + assert ls(basetemp(pytester) / 'logs/subdir/subsubdir/test_foo3.py') == ['test_bar'] + assert ls(basetemp(pytester) / 'logs/subdir/test_foo2.py') == ['test_bar'] + assert ls(basetemp(pytester) / 'logs/test_foo1.py') == sorted([ 'test_bar', 'test_baz', 'TestInsideClass', 'test_par-abc-de', 'test_par-2-4.127', ]) - assert ls(basetemp(pytester), 'logs/test_foo1.py/TestInsideClass') == ['test_qez'] + assert ls(basetemp(pytester) / 'logs/test_foo1.py/TestInsideClass') == ['test_qez'] def test_stdout_handlers(pytester): @@ -194,9 +194,9 @@ def test_file_handlers(pytester, conftest_py, test_case_py): '', ]) - assert ls(basetemp(pytester), 'logs') == [test_case_py.name] - assert ls(basetemp(pytester), f'logs/{test_case_py.name}') == ['test_case'] - assert ls(basetemp(pytester), f'logs/{test_case_py.name}/test_case') == ['bar', 'foo'] + assert ls(basetemp(pytester) / 'logs') == [test_case_py.name] + assert ls(basetemp(pytester) / f'logs/{test_case_py.name}') == ['test_case'] + assert ls(basetemp(pytester) / f'logs/{test_case_py.name}/test_case') == ['bar', 'foo'] FileLineMatcher(basetemp(pytester) / f'logs/{test_case_py.name}/test_case/foo').fnmatch_lines([ '* foo: this is error', @@ -284,9 +284,9 @@ def test_case(): '', ]) - assert ls(basetemp(pytester), 'logs') == ['test_case.py'] - assert ls(basetemp(pytester), 'logs/test_case.py') == ['test_case'] - assert ls(basetemp(pytester), 'logs/test_case.py/test_case') == ['foo', 'logs'] + assert ls(basetemp(pytester) / 'logs') == ['test_case.py'] + assert ls(basetemp(pytester) / 'logs/test_case.py') == ['test_case'] + assert ls(basetemp(pytester) / 'logs/test_case.py/test_case') == ['foo', 'logs'] FileLineMatcher(basetemp(pytester) / 'logs/test_case.py/test_case/logs').fnmatch_lines([ '* foo: this is error', @@ -315,7 +315,7 @@ def test_case(): result = pytester.runpytest('-s') assert result.ret == 0 assert 'my_link_dir' in ls(pytester.path) - assert ['test_case'] == ls(pytester.path, 'my_link_dir/test_case.py') + assert ['test_case'] == ls(pytester.path / 'my_link_dir/test_case.py') def test_logsdir(pytester): @@ -345,11 +345,11 @@ def test_param(param1, param2): result = pytester.runpytest('-s') assert result.ret == 0 assert 'my_logs_dir' in ls(pytester.path) - assert 'test_simple' in ls(pytester.path, 'my_logs_dir/test_cases.py') - assert 'test_param-x-a_b_c' in ls(pytester.path, 'my_logs_dir/test_cases.py') - assert 'test_param-y-d-e-f' in ls(pytester.path, 'my_logs_dir/test_cases.py') - assert 'test_param-z-g-h-i' in ls(pytester.path, 'my_logs_dir/test_cases.py') - assert 'test_param-v-j-1-k-1-l-1' in ls(pytester.path, 'my_logs_dir/test_cases.py') + assert 'test_simple' in ls(pytester.path / 'my_logs_dir/test_cases.py') + assert 'test_param-x-a_b_c' in ls(pytester.path / 'my_logs_dir/test_cases.py') + assert 'test_param-y-d-e-f' in ls(pytester.path / 'my_logs_dir/test_cases.py') + assert 'test_param-z-g-h-i' in ls(pytester.path / 'my_logs_dir/test_cases.py') + assert 'test_param-v-j-1-k-1-l-1' in ls(pytester.path / 'my_logs_dir/test_cases.py') def test_format(pytester): @@ -418,8 +418,8 @@ def test_case(): result = pytester.runpytest('subdir', 'makes_nodeid_in_pytest29_contain_subdir_name', '-s') assert result.ret == 0 - assert ls(pytester.path, 'logs/subdir/test_case.py') == ['test_case'] - assert ls(pytester.path, 'subdir/logs/subdir/test_case.py') == ['test_case'] + assert ls(pytester.path / 'logs/subdir/test_case.py') == ['test_case'] + assert ls(pytester.path / 'subdir/logs/subdir/test_case.py') == ['test_case'] result.stdout.fnmatch_lines([ '', @@ -482,7 +482,7 @@ def test_case{index}(): result = pytester.runpytest('-n3') assert result.ret == 0 - assert ls(pytester.path, 'logs') == ['test_case%s.py' % i for i in range(N)] + assert ls(pytester.path / 'logs') == ['test_case%s.py' % i for i in range(N)] for index in range(N): logfilename = f'logs/test_case{index}.py/test_case{index}/foo' @@ -500,8 +500,8 @@ def test_logsdir_option(pytester, conftest_py, test_case_py): ]) assert ls(logsdir) == [test_case_py.name] - assert ls(logsdir, test_case_py.name) == ['test_case'] - assert ls(logsdir, f'{test_case_py.name}/test_case') == ['bar', 'foo'] + assert ls(logsdir / test_case_py.name) == ['test_case'] + assert ls(logsdir / f'{test_case_py.name}/test_case') == ['bar', 'foo'] FileLineMatcher(logsdir / f'{test_case_py.name}/test_case/foo').fnmatch_lines([ '* foo: this is error', @@ -528,8 +528,8 @@ def test_logsdir_ini(pytester, conftest_py, test_case_py): ]) assert ls(logsdir) == [test_case_py.name] - assert ls(logsdir, test_case_py.name) == ['test_case'] - assert ls(logsdir, f'{test_case_py.name}/test_case') == ['bar', 'foo'] + assert ls(logsdir / test_case_py.name) == ['test_case'] + assert ls(logsdir / f'{test_case_py.name}/test_case') == ['bar', 'foo'] FileLineMatcher(logsdir / f'{test_case_py.name}/test_case/foo').fnmatch_lines([ '* foo: this is error', @@ -560,8 +560,8 @@ def test_logsdir_cleanup(pytester, conftest_py, test_case_py): ]) assert ls(logsdir) == [test_case_py.name] - assert ls(logsdir, test_case_py.name) == ['test_case'] - assert ls(logsdir, f'{test_case_py.name}/test_case') == ['bar', 'foo'] + assert ls(logsdir / test_case_py.name) == ['test_case'] + assert ls(logsdir / f'{test_case_py.name}/test_case') == ['bar', 'foo'] FileLineMatcher(logsdir / f'{test_case_py.name}/test_case/foo').fnmatch_lines([ '* foo: this is error', From 5f31eccf9108c5a631f57b538ee446662491387c Mon Sep 17 00:00:00 2001 From: Krzysztof Laskowski Date: Tue, 20 Feb 2024 00:52:53 +0100 Subject: [PATCH 13/16] modernize: new output style used in tests --- tests/test_pytest_logger.py | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/tests/test_pytest_logger.py b/tests/test_pytest_logger.py index 4a5b039..79a8fea 100644 --- a/tests/test_pytest_logger.py +++ b/tests/test_pytest_logger.py @@ -22,16 +22,6 @@ def basetemp(pytester): return pytester.path.parent / 'basetemp' -@pytest.fixture(autouse=True) -def set_classic_output(monkeypatch, pytester): - runpytest = pytester.runpytest - - def wrapper(*args, **kwargs): - return runpytest('--override-ini=console_output_style=classic', *args, **kwargs) - - monkeypatch.setattr(pytester, 'runpytest', wrapper) - - @pytest.fixture def conftest_py(pytester): return makefile(pytester.path / 'conftest.py', """ @@ -135,7 +125,7 @@ def test_case(): assert result.ret == 0 result.stdout.fnmatch_lines([ '', - 'test_case.py .', + 'test_case.py . *', '', ]) @@ -734,15 +724,6 @@ def pytest_logger_config(logger_config): assert result.ret == 0 -@pytest.mark.skip("Since pytest v3.3 progress percentage is being displayed by default during test execution. " - "It interferes with most of the old test cases that assert stdout/err so to not change them, we are " - "now forcing classic output with a set_classic_output auto-use fixture which overrides pytest's " - "console_output_style. We could have at least one test that proves the plugin can work in the new" - "default mode as well.") -def test_works_with_progress_percentage_prints(): - assert False - - def test_collects_teardown_logs(pytester): makefile(pytester.path / 'conftest.py', """ def pytest_logger_config(logger_config): From 4b8c23907b3e3c61d577dd58e7639cc68535d36a Mon Sep 17 00:00:00 2001 From: Krzysztof Laskowski Date: Tue, 20 Feb 2024 03:29:17 +0100 Subject: [PATCH 14/16] issue-13: pytest_logger_logdirlink path can be relative --- pytest_logger/plugin.py | 8 ++++++-- tests/test_pytest_logger.py | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/pytest_logger/plugin.py b/pytest_logger/plugin.py index 5ba8fd6..cdf6216 100644 --- a/pytest_logger/plugin.py +++ b/pytest_logger/plugin.py @@ -57,8 +57,11 @@ def __init__(self, logcfg): class LoggerPlugin: def __init__(self, config, logcfg): + def prepare_logdirlink(path: Path): + return path if path.is_absolute() else config.rootpath / path + self._config = config - self._logdirlinks = config.hook.pytest_logger_logdirlink(config=config) + self._logdirlinks = [prepare_logdirlink(Path(d)) for d in config.hook.pytest_logger_logdirlink(config=config)] self._loggers = _loggers_from_logcfg(logcfg, config.getoption('loggers')) if logcfg._enabled else None self._formatter_class = logcfg._formatter_class or DefaultFormatter self._logsdir = None @@ -267,7 +270,8 @@ def pytest_logger_logdirlink(self, config): :arg config: pytest config object, holds e.g. options - :return string: Absolute path of requested link to logs directory. + :return string: Path of requested link to logs directory. + When relative, it's relative to pytest session rootdir """ @pytest.hookspec(firstresult=True) diff --git a/tests/test_pytest_logger.py b/tests/test_pytest_logger.py index 79a8fea..00c8d32 100644 --- a/tests/test_pytest_logger.py +++ b/tests/test_pytest_logger.py @@ -308,6 +308,25 @@ def test_case(): assert ['test_case'] == ls(pytester.path / 'my_link_dir/test_case.py') +def test_logdir_link_relative(pytester): + makefile(pytester.path / 'root' / 'conftest.py', """ + import os + def pytest_logger_fileloggers(item): + return [''] + def pytest_logger_logdirlink(config): + return '.logs' + """) + makefile(pytester.path / 'root' / 'test_case.py', """ + def test_case(): + pass + """) + + result = pytester.runpytest('--rootdir=root', 'root', '-s') + assert result.ret == 0 + assert '.logs' in ls(pytester.path / 'root') + assert ['test_case'] == ls(pytester.path / 'root' / '.logs' / 'test_case.py') + + def test_logsdir(pytester): makefile(pytester.path / 'conftest.py', """ import os From 645538535606426cf303e5c8af1dcc52ac2fa527 Mon Sep 17 00:00:00 2001 From: Krzysztof Laskowski Date: Tue, 20 Feb 2024 03:33:24 +0100 Subject: [PATCH 15/16] modernize: no need to use absolute paths --- tests/test_pytest_logger.py | 223 ++++++++++++++++++------------------ 1 file changed, 110 insertions(+), 113 deletions(-) diff --git a/tests/test_pytest_logger.py b/tests/test_pytest_logger.py index 00c8d32..0469e4c 100644 --- a/tests/test_pytest_logger.py +++ b/tests/test_pytest_logger.py @@ -8,23 +8,24 @@ from _pytest.pytester import LineMatcher # for pytest 6 -def makefile(path: Path, content: str): +BASETEMP = Path('../basetemp') +LOGSDIR = Path('myinilogs') + + +def makefile(path, content: str): + path = Path(path) path.parent.mkdir(parents=True, exist_ok=True) path.write_text(textwrap.dedent(content)) return path -def ls(dir: Path): - return sorted(os.listdir(dir)) - - -def basetemp(pytester): - return pytester.path.parent / 'basetemp' +def ls(path='.'): + return sorted(os.listdir(Path(path))) @pytest.fixture def conftest_py(pytester): - return makefile(pytester.path / 'conftest.py', """ + return makefile('conftest.py', """ import logging def pytest_logger_fileloggers(item): return [ @@ -36,7 +37,7 @@ def pytest_logger_fileloggers(item): @pytest.fixture def test_case_py(pytester): - return makefile(pytester.path / 'test_case.py', """ + return makefile('test_case.py', """ import logging def test_case(): for lgr in (logging.getLogger(name) for name in ['foo', 'bar', 'baz']): @@ -52,7 +53,7 @@ def __init__(self, path: Path): def test_logdir_fixture(pytester): - makefile(pytester.path / 'test_foo1.py', """ + makefile('test_foo1.py', """ import os def test_bar(logdir, tmpdir_factory): @@ -79,12 +80,12 @@ def test_par(logdir, param1, param2): def test_this_should_not_generate_logdir(): pass """) - makefile(pytester.path / 'subdir' / 'test_foo2.py', """ + makefile('subdir/test_foo2.py', """ import os def test_bar(logdir): assert str(logdir).endswith(os.path.join('logs', 'subdir', 'test_foo2.py', 'test_bar')) """) - makefile(pytester.path / 'subdir' / 'subsubdir' / 'test_foo3.py', """ + makefile('subdir/subsubdir/test_foo3.py', """ import os def test_bar(logdir): assert str(logdir).endswith(os.path.join('logs', 'subdir', 'subsubdir', 'test_foo3.py', 'test_bar')) @@ -93,27 +94,27 @@ def test_bar(logdir): result = pytester.runpytest() assert result.ret == 0 - assert ls(basetemp(pytester) / 'logs') == ['subdir', 'test_foo1.py'] - assert ls(basetemp(pytester) / 'logs/subdir') == ['subsubdir', 'test_foo2.py'] - assert ls(basetemp(pytester) / 'logs/subdir/subsubdir') == ['test_foo3.py'] - assert ls(basetemp(pytester) / 'logs/subdir/subsubdir/test_foo3.py') == ['test_bar'] - assert ls(basetemp(pytester) / 'logs/subdir/test_foo2.py') == ['test_bar'] - assert ls(basetemp(pytester) / 'logs/test_foo1.py') == sorted([ + assert ls(BASETEMP / 'logs') == ['subdir', 'test_foo1.py'] + assert ls(BASETEMP / 'logs/subdir') == ['subsubdir', 'test_foo2.py'] + assert ls(BASETEMP / 'logs/subdir/subsubdir') == ['test_foo3.py'] + assert ls(BASETEMP / 'logs/subdir/subsubdir/test_foo3.py') == ['test_bar'] + assert ls(BASETEMP / 'logs/subdir/test_foo2.py') == ['test_bar'] + assert ls(BASETEMP / 'logs/test_foo1.py') == sorted([ 'test_bar', 'test_baz', 'TestInsideClass', 'test_par-abc-de', 'test_par-2-4.127', ]) - assert ls(basetemp(pytester) / 'logs/test_foo1.py/TestInsideClass') == ['test_qez'] + assert ls(BASETEMP / 'logs/test_foo1.py/TestInsideClass') == ['test_qez'] def test_stdout_handlers(pytester): - makefile(pytester.path / 'conftest.py', """ + makefile('conftest.py', """ def pytest_logger_stdoutloggers(item): return ['foo'] """) - makefile(pytester.path / 'test_case.py', """ + makefile('test_case.py', """ import logging def test_case(): logging.getLogger('foo').warning('this is warning') @@ -141,7 +142,7 @@ def test_case(): def test_stdout_handlers_many_loggers(pytester): - makefile(pytester.path / 'conftest.py', """ + makefile('conftest.py', """ import logging def pytest_logger_stdoutloggers(item): return [ @@ -150,7 +151,7 @@ def pytest_logger_stdoutloggers(item): ('baz', logging.FATAL) ] """) - makefile(pytester.path / 'test_case.py', """ + makefile('test_case.py', """ import logging def test_case(): for lgr in (logging.getLogger(name) for name in ['foo', 'bar', 'baz']): @@ -184,21 +185,21 @@ def test_file_handlers(pytester, conftest_py, test_case_py): '', ]) - assert ls(basetemp(pytester) / 'logs') == [test_case_py.name] - assert ls(basetemp(pytester) / f'logs/{test_case_py.name}') == ['test_case'] - assert ls(basetemp(pytester) / f'logs/{test_case_py.name}/test_case') == ['bar', 'foo'] + assert ls(BASETEMP / 'logs') == [test_case_py.name] + assert ls(BASETEMP / f'logs/{test_case_py.name}') == ['test_case'] + assert ls(BASETEMP / f'logs/{test_case_py.name}/test_case') == ['bar', 'foo'] - FileLineMatcher(basetemp(pytester) / f'logs/{test_case_py.name}/test_case/foo').fnmatch_lines([ + FileLineMatcher(BASETEMP / f'logs/{test_case_py.name}/test_case/foo').fnmatch_lines([ '* foo: this is error', '* foo: this is warning', ]) - FileLineMatcher(basetemp(pytester) / f'logs/{test_case_py.name}/test_case/bar').fnmatch_lines([ + FileLineMatcher(BASETEMP / f'logs/{test_case_py.name}/test_case/bar').fnmatch_lines([ '* bar: this is error', ]) def test_split_logs_by_outcome(pytester): - makefile(pytester.path / 'conftest.py', """ + makefile('conftest.py', """ import logging def pytest_logger_fileloggers(item): return [ @@ -209,7 +210,7 @@ def pytest_logger_fileloggers(item): def pytest_logger_config(logger_config): logger_config.split_by_outcome(outcomes=['passed', 'failed']) """) - makefile(pytester.path / 'test_case.py', """ + makefile('test_case.py', """ import pytest import logging def test_case_that_fails(): @@ -231,17 +232,17 @@ def test_case_that_passes(): '', ]) - assert 'by_outcome' in ls(basetemp(pytester) / 'logs') + assert 'by_outcome' in ls(BASETEMP / 'logs') - assert 'failed' in ls(basetemp(pytester) / 'logs' / 'by_outcome') - failedlogpath = basetemp(pytester) / 'logs' / 'by_outcome' / 'failed' / 'test_case.py' / 'test_case_that_fails' + assert 'failed' in ls(BASETEMP / 'logs' / 'by_outcome') + failedlogpath = BASETEMP / 'logs' / 'by_outcome' / 'failed' / 'test_case.py' / 'test_case_that_fails' assert failedlogpath.is_symlink() failedlogdest = os.path.join( os.path.pardir, os.path.pardir, os.path.pardir, 'test_case.py', 'test_case_that_fails') assert os.readlink(str(failedlogpath)) == failedlogdest - assert 'passed' in ls(basetemp(pytester) / 'logs' / 'by_outcome') - passedlogpath = basetemp(pytester) / 'logs' / 'by_outcome' / 'passed' / 'test_case.py' / 'test_case_that_passes' + assert 'passed' in ls(BASETEMP / 'logs' / 'by_outcome') + passedlogpath = BASETEMP / 'logs' / 'by_outcome' / 'passed' / 'test_case.py' / 'test_case_that_passes' assert passedlogpath.is_symlink() passedlogdest = os.path.join( os.path.pardir, os.path.pardir, os.path.pardir, 'test_case.py', 'test_case_that_passes') @@ -249,7 +250,7 @@ def test_case_that_passes(): def test_file_handlers_root(pytester): - makefile(pytester.path / 'conftest.py', """ + makefile('conftest.py', """ import logging def pytest_logger_fileloggers(item): return [ @@ -257,7 +258,7 @@ def pytest_logger_fileloggers(item): ('foo', logging.WARNING), ] """) - makefile(pytester.path / 'test_case.py', """ + makefile('test_case.py', """ import logging def test_case(): for lgr in (logging.getLogger(name) for name in ['foo', 'bar', 'baz']): @@ -274,68 +275,68 @@ def test_case(): '', ]) - assert ls(basetemp(pytester) / 'logs') == ['test_case.py'] - assert ls(basetemp(pytester) / 'logs/test_case.py') == ['test_case'] - assert ls(basetemp(pytester) / 'logs/test_case.py/test_case') == ['foo', 'logs'] + assert ls(BASETEMP / 'logs') == ['test_case.py'] + assert ls(BASETEMP / 'logs/test_case.py') == ['test_case'] + assert ls(BASETEMP / 'logs/test_case.py/test_case') == ['foo', 'logs'] - FileLineMatcher(basetemp(pytester) / 'logs/test_case.py/test_case/logs').fnmatch_lines([ + FileLineMatcher(BASETEMP / 'logs/test_case.py/test_case/logs').fnmatch_lines([ '* foo: this is error', '* bar: this is error', '* baz: this is error', ]) - FileLineMatcher(basetemp(pytester) / 'logs/test_case.py/test_case/foo').fnmatch_lines([ + FileLineMatcher(BASETEMP / 'logs/test_case.py/test_case/foo').fnmatch_lines([ '* foo: this is error', '* foo: this is warning', ]) def test_logdir_link(pytester): - makefile(pytester.path / 'conftest.py', """ + makefile('conftest.py', """ import os def pytest_logger_fileloggers(item): return [''] def pytest_logger_logdirlink(config): return os.path.join(os.path.dirname(__file__), 'my_link_dir') """) - makefile(pytester.path / 'test_case.py', """ + makefile('test_case.py', """ def test_case(): pass """) result = pytester.runpytest('-s') assert result.ret == 0 - assert 'my_link_dir' in ls(pytester.path) - assert ['test_case'] == ls(pytester.path / 'my_link_dir/test_case.py') + assert 'my_link_dir' in ls() + assert ['test_case'] == ls('my_link_dir/test_case.py') def test_logdir_link_relative(pytester): - makefile(pytester.path / 'root' / 'conftest.py', """ + makefile('root/conftest.py', """ import os def pytest_logger_fileloggers(item): return [''] def pytest_logger_logdirlink(config): return '.logs' """) - makefile(pytester.path / 'root' / 'test_case.py', """ + makefile('root/test_case.py', """ def test_case(): pass """) result = pytester.runpytest('--rootdir=root', 'root', '-s') assert result.ret == 0 - assert '.logs' in ls(pytester.path / 'root') - assert ['test_case'] == ls(pytester.path / 'root' / '.logs' / 'test_case.py') + assert '.logs' in ls('root') + assert ['test_case'] == ls('root/.logs/test_case.py') def test_logsdir(pytester): - makefile(pytester.path / 'conftest.py', """ + makefile('conftest.py', """ import os def pytest_logger_fileloggers(item): return [''] def pytest_logger_logsdir(config): return os.path.join(os.path.dirname(__file__), 'my_logs_dir') """) - makefile(pytester.path / 'test_cases.py', """ + makefile('test_cases.py', """ import pytest def test_simple(): @@ -353,16 +354,16 @@ def test_param(param1, param2): result = pytester.runpytest('-s') assert result.ret == 0 - assert 'my_logs_dir' in ls(pytester.path) - assert 'test_simple' in ls(pytester.path / 'my_logs_dir/test_cases.py') - assert 'test_param-x-a_b_c' in ls(pytester.path / 'my_logs_dir/test_cases.py') - assert 'test_param-y-d-e-f' in ls(pytester.path / 'my_logs_dir/test_cases.py') - assert 'test_param-z-g-h-i' in ls(pytester.path / 'my_logs_dir/test_cases.py') - assert 'test_param-v-j-1-k-1-l-1' in ls(pytester.path / 'my_logs_dir/test_cases.py') + assert 'my_logs_dir' in ls() + assert 'test_simple' in ls('my_logs_dir/test_cases.py') + assert 'test_param-x-a_b_c' in ls('my_logs_dir/test_cases.py') + assert 'test_param-y-d-e-f' in ls('my_logs_dir/test_cases.py') + assert 'test_param-z-g-h-i' in ls('my_logs_dir/test_cases.py') + assert 'test_param-v-j-1-k-1-l-1' in ls('my_logs_dir/test_cases.py') def test_format(pytester): - makefile(pytester.path / 'conftest.py', """ + makefile('conftest.py', """ import os import logging def pytest_logger_stdoutloggers(item): @@ -370,7 +371,7 @@ def pytest_logger_stdoutloggers(item): def pytest_logger_fileloggers(item): return [''] """) - makefile(pytester.path / 'test_case.py', """ + makefile('test_case.py', """ import logging def test_case(): lgr = logging.getLogger('foo') @@ -394,11 +395,11 @@ def test_case(): '*:*.* l35 foo: this is 35', ] result.stdout.fnmatch_lines(expected_lines) - FileLineMatcher(basetemp(pytester) / 'logs/test_case.py/test_case/logs').fnmatch_lines(expected_lines) + FileLineMatcher(BASETEMP / 'logs/test_case.py/test_case/logs').fnmatch_lines(expected_lines) def test_multiple_conftests(pytester): - makefile(pytester.path / 'conftest.py', """ + makefile('conftest.py', """ import os def pytest_logger_stdoutloggers(item): return ['foo'] @@ -407,7 +408,7 @@ def pytest_logger_fileloggers(item): def pytest_logger_logdirlink(config): return os.path.join(os.path.dirname(__file__), 'logs') """) - makefile(pytester.path / 'subdir' / 'conftest.py', """ + makefile('subdir/conftest.py', """ import os def pytest_logger_stdoutloggers(item): return ['bar'] @@ -416,19 +417,19 @@ def pytest_logger_fileloggers(item): def pytest_logger_logdirlink(config): return os.path.join(os.path.dirname(__file__), 'logs') """) - makefile(pytester.path / 'subdir' / 'test_case.py', """ + makefile('subdir/test_case.py', """ import logging def test_case(): for lgr in (logging.getLogger(name) for name in ['foo', 'bar']): lgr.warning('this is warning') """) - makefile(pytester.path / 'makes_nodeid_in_pytest29_contain_subdir_name' / 'empty', '') + makefile('makes_nodeid_in_pytest29_contain_subdir_name/empty', '') result = pytester.runpytest('subdir', 'makes_nodeid_in_pytest29_contain_subdir_name', '-s') assert result.ret == 0 - assert ls(pytester.path / 'logs/subdir/test_case.py') == ['test_case'] - assert ls(pytester.path / 'subdir/logs/subdir/test_case.py') == ['test_case'] + assert ls('logs/subdir/test_case.py') == ['test_case'] + assert ls('subdir/logs/subdir/test_case.py') == ['test_case'] result.stdout.fnmatch_lines([ '', @@ -439,16 +440,16 @@ def test_case(): '' ]) - FileLineMatcher(basetemp(pytester) / 'logs/subdir/test_case.py/test_case/foo').fnmatch_lines([ + FileLineMatcher(BASETEMP / 'logs/subdir/test_case.py/test_case/foo').fnmatch_lines([ '* foo: this is warning', ]) - FileLineMatcher(basetemp(pytester) / 'logs/subdir/test_case.py/test_case/bar').fnmatch_lines([ + FileLineMatcher(BASETEMP / 'logs/subdir/test_case.py/test_case/bar').fnmatch_lines([ '* bar: this is warning', ]) def test_skip_gracefully(pytester): - makefile(pytester.path / 'conftest.py', """ + makefile('conftest.py', """ import os def pytest_logger_stdoutloggers(item): return ['foo'] @@ -457,7 +458,7 @@ def pytest_logger_fileloggers(item): def pytest_logger_logdirlink(config): return os.path.join(os.path.dirname(__file__), 'logs') """) - makefile(pytester.path / 'test_case.py', """ + makefile('test_case.py', """ import pytest @pytest.mark.skipif(True, reason='') def test_case(): @@ -467,12 +468,12 @@ def test_case(): result = pytester.runpytest('-s') assert result.ret == 0 - assert 'logs' not in ls(pytester.path) + assert 'logs' not in ls() def test_xdist(pytester): N = 8 - makefile(pytester.path / 'conftest.py', """ + makefile('conftest.py', """ import os def pytest_logger_stdoutloggers(item): return ['foo'] @@ -482,7 +483,7 @@ def pytest_logger_logdirlink(config): return os.path.join(os.path.dirname(__file__), 'logs') """) for index in range(N): - makefile(pytester.path / f'test_case{index}.py', f""" + makefile(f'test_case{index}.py', f""" import logging def test_case{index}(): logging.getLogger('foo').warning('this is test {index}') @@ -491,16 +492,15 @@ def test_case{index}(): result = pytester.runpytest('-n3') assert result.ret == 0 - assert ls(pytester.path / 'logs') == ['test_case%s.py' % i for i in range(N)] + assert ls('logs') == ['test_case%s.py' % i for i in range(N)] for index in range(N): logfilename = f'logs/test_case{index}.py/test_case{index}/foo' - FileLineMatcher(basetemp(pytester) / logfilename).fnmatch_lines(['* wrn foo: this is test %s' % index]) + FileLineMatcher(BASETEMP / logfilename).fnmatch_lines(['* wrn foo: this is test %s' % index]) def test_logsdir_option(pytester, conftest_py, test_case_py): - logsdir = pytester.path / 'myinilogs' - result = pytester.runpytest('-s', f'--logger-logsdir={logsdir}') + result = pytester.runpytest('-s', f'--logger-logsdir={LOGSDIR}') assert result.ret == 0 result.stdout.fnmatch_lines([ '', @@ -508,24 +508,23 @@ def test_logsdir_option(pytester, conftest_py, test_case_py): '', ]) - assert ls(logsdir) == [test_case_py.name] - assert ls(logsdir / test_case_py.name) == ['test_case'] - assert ls(logsdir / f'{test_case_py.name}/test_case') == ['bar', 'foo'] + assert ls(LOGSDIR) == [test_case_py.name] + assert ls(LOGSDIR / test_case_py.name) == ['test_case'] + assert ls(LOGSDIR / test_case_py.name / 'test_case') == ['bar', 'foo'] - FileLineMatcher(logsdir / f'{test_case_py.name}/test_case/foo').fnmatch_lines([ + FileLineMatcher(LOGSDIR / f'{test_case_py.name}/test_case/foo').fnmatch_lines([ '* foo: this is error', '* foo: this is warning', ]) - FileLineMatcher(logsdir / f'{test_case_py.name}/test_case/bar').fnmatch_lines([ + FileLineMatcher(LOGSDIR / f'{test_case_py.name}/test_case/bar').fnmatch_lines([ '* bar: this is error', ]) def test_logsdir_ini(pytester, conftest_py, test_case_py): - logsdir = pytester.path / 'myinilogs' - makefile(pytester.path / 'pytest.ini', f""" + makefile('pytest.ini', f""" [pytest] - logger_logsdir={logsdir} + logger_logsdir={LOGSDIR} """) result = pytester.runpytest('-s') @@ -536,27 +535,25 @@ def test_logsdir_ini(pytester, conftest_py, test_case_py): '', ]) - assert ls(logsdir) == [test_case_py.name] - assert ls(logsdir / test_case_py.name) == ['test_case'] - assert ls(logsdir / f'{test_case_py.name}/test_case') == ['bar', 'foo'] + assert ls(LOGSDIR) == [test_case_py.name] + assert ls(LOGSDIR / test_case_py.name) == ['test_case'] + assert ls(LOGSDIR / f'{test_case_py.name}/test_case') == ['bar', 'foo'] - FileLineMatcher(logsdir / f'{test_case_py.name}/test_case/foo').fnmatch_lines([ + FileLineMatcher(LOGSDIR / f'{test_case_py.name}/test_case/foo').fnmatch_lines([ '* foo: this is error', '* foo: this is warning', ]) - FileLineMatcher(logsdir / f'{test_case_py.name}/test_case/bar').fnmatch_lines([ + FileLineMatcher(LOGSDIR / f'{test_case_py.name}/test_case/bar').fnmatch_lines([ '* bar: this is error', ]) def test_logsdir_cleanup(pytester, conftest_py, test_case_py): - logsdir = pytester.path / 'myinilogs' - - makefile(pytester.path / 'pytest.ini', f""" + makefile('pytest.ini', f""" [pytest] - logger_logsdir={logsdir} + logger_logsdir={LOGSDIR} """) - makefile(logsdir / 'tmpfile', """ + makefile(LOGSDIR / 'tmpfile', """ this shall be removed """) @@ -568,21 +565,21 @@ def test_logsdir_cleanup(pytester, conftest_py, test_case_py): '', ]) - assert ls(logsdir) == [test_case_py.name] - assert ls(logsdir / test_case_py.name) == ['test_case'] - assert ls(logsdir / f'{test_case_py.name}/test_case') == ['bar', 'foo'] + assert ls(LOGSDIR) == [test_case_py.name] + assert ls(LOGSDIR / test_case_py.name) == ['test_case'] + assert ls(LOGSDIR / f'{test_case_py.name}/test_case') == ['bar', 'foo'] - FileLineMatcher(logsdir / f'{test_case_py.name}/test_case/foo').fnmatch_lines([ + FileLineMatcher(LOGSDIR / f'{test_case_py.name}/test_case/foo').fnmatch_lines([ '* foo: this is error', '* foo: this is warning', ]) - FileLineMatcher(logsdir / f'{test_case_py.name}/test_case/bar').fnmatch_lines([ + FileLineMatcher(LOGSDIR / f'{test_case_py.name}/test_case/bar').fnmatch_lines([ '* bar: this is error', ]) def test_logger_config(pytester, test_case_py): - makefile(pytester.path / 'conftest.py', """ + makefile('conftest.py', """ def pytest_logger_config(logger_config): logger_config.add_loggers(['foo', 'bar'], stdout_level='warning', file_level='info') logger_config.add_loggers(['baz'], stdout_level='error', file_level='warning') @@ -603,17 +600,17 @@ def pytest_logger_config(logger_config): '.', '', ]) - FileLineMatcher(basetemp(pytester) / 'logs/test_case.py/test_case/foo').fnmatch_lines([ + FileLineMatcher(BASETEMP / 'logs/test_case.py/test_case/foo').fnmatch_lines([ '* err foo: this is error', '* wrn foo: this is warning', '* inf foo: this is info', ]) - FileLineMatcher(basetemp(pytester) / 'logs/test_case.py/test_case/bar').fnmatch_lines([ + FileLineMatcher(BASETEMP / 'logs/test_case.py/test_case/bar').fnmatch_lines([ '* err bar: this is error', '* wrn bar: this is warning', '* inf bar: this is info', ]) - FileLineMatcher(basetemp(pytester) / 'logs/test_case.py/test_case/baz').fnmatch_lines([ + FileLineMatcher(BASETEMP / 'logs/test_case.py/test_case/baz').fnmatch_lines([ '* err baz: this is error', '* wrn baz: this is warning', ]) @@ -621,7 +618,7 @@ def pytest_logger_config(logger_config): @pytest.mark.parametrize('log_option', ('', '--loggers=foo.info,baz')) def test_logger_config_option(pytester, test_case_py, log_option): - makefile(pytester.path / 'conftest.py', """ + makefile('conftest.py', """ def pytest_logger_config(logger_config): logger_config.add_loggers(['foo', 'bar']) logger_config.add_loggers(['baz'], file_level='error') @@ -652,7 +649,7 @@ def pytest_logger_config(logger_config): @pytest.mark.parametrize('log_option', ('', '--loggers=foo.info,baz')) def test_logger_config_formatter(pytester, test_case_py, log_option): - makefile(pytester.path / 'conftest.py', """ + makefile('conftest.py', """ import logging def pytest_logger_config(logger_config): @@ -686,7 +683,7 @@ def pytest_logger_config(logger_config): @pytest.mark.parametrize('with_hook', (False, True)) def test_logger_config_option_missing_without_hook(pytester, test_case_py, with_hook): - makefile(pytester.path / 'conftest.py', """ + makefile('conftest.py', """ def pytest_addoption(parser): parser.addoption('--loggers') """ + (""" @@ -707,7 +704,7 @@ def pytest_logger_config(logger_config): @pytest.mark.parametrize('stdout_hook', (False, True)) @pytest.mark.parametrize('config_hook', (False, True)) def test_error_both_hook_apis_used(pytester, test_case_py, stdout_hook, config_hook): - makefile(pytester.path / 'conftest.py', (""" + makefile('conftest.py', (""" def pytest_logger_stdoutloggers(item): return ['foo'] """ if stdout_hook else '') + (""" @@ -733,7 +730,7 @@ def test_help_prints(pytester, test_case_py): To remedy this hack checking whether option has been parsed was made. This test ensures that it keeps working. """ - makefile(pytester.path / 'conftest.py', """ + makefile('conftest.py', """ def pytest_logger_config(logger_config): logger_config.add_loggers(['foo']) logger_config.set_log_option_default('foo') @@ -744,13 +741,13 @@ def pytest_logger_config(logger_config): def test_collects_teardown_logs(pytester): - makefile(pytester.path / 'conftest.py', """ + makefile('conftest.py', """ def pytest_logger_config(logger_config): logger_config.add_loggers(['foo']) logger_config.set_log_option_default('foo') """) - makefile(pytester.path / 'test_bar.py', """ + makefile('test_bar.py', """ import logging import pytest logger = logging.getLogger('foo') @@ -768,7 +765,7 @@ def test_bar(): result = pytester.runpytest() assert result.ret == 0 - FileLineMatcher(basetemp(pytester) / 'logs/test_bar.py/test_bar/foo').fnmatch_lines([ + FileLineMatcher(BASETEMP / 'logs/test_bar.py/test_bar/foo').fnmatch_lines([ '* inf foo: setup', '* inf foo: test_bar', '* inf foo: teardown', From 9be6390f3f768d17e68c343a6b89b15aaffbaaec Mon Sep 17 00:00:00 2001 From: Krzysztof Laskowski Date: Wed, 21 Feb 2024 00:29:15 +0100 Subject: [PATCH 16/16] issue-12: documented logdir fixture --- pytest_logger/plugin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pytest_logger/plugin.py b/pytest_logger/plugin.py index cdf6216..247f95e 100644 --- a/pytest_logger/plugin.py +++ b/pytest_logger/plugin.py @@ -318,6 +318,7 @@ def format(self, record): @pytest.fixture def logdir(request): + """ Return a path to log directory for the test function """ return _make_logdir(request._pyfuncitem)