from __future__ import annotations import pathlib import _pytest.terminal import pytest _pytest.terminal._color_for_type['incompatible'] = 'red' _pytest.terminal._color_for_type['passable'] = 'yellow' _pytest.terminal._color_for_type['compatible'] = 'green' _pytest.terminal._color_for_type['exact'] = 'green' @pytest.hookimpl def pytest_report_teststatus(report, config): """Customizes the reporting of test statuses.""" if report.when != 'call': return None if isinstance(report, pytest.CollectReport) or report.outcome in ('skipped'): return None props = dict(report.user_properties) ahash = props.get('ahash:', -1) dhash = props.get('dhash:', -1) phash = props.get('phash:', -1) if ahash == dhash == phash == 0: if report.outcome == 'failed': return 'failed', 'E', ('EXACT', {'red': True}) return 'exact', 'E', ('EXACT', {'green': True}) if ahash >= 10 or dhash >= 10 or phash >= 10: return 'incompatible', 'I', ('INCOMPATIBLE', {'red': True}) if 4 < ahash < 10 or 4 < dhash < 10 or 4 < phash < 10: return 'passable', 'P', ('PASSABLE', {'yellow': True}) if ahash <= 4 or dhash <= 4 or phash <= 4: return 'compatible', 'C', ('COMPATIBLE', {'green': True}) def pytest_terminal_summary(terminalreporter, exitstatus, config): incompatible = terminalreporter._get_reports_to_display('incompatible') passable = terminalreporter._get_reports_to_display('passable') compatible = terminalreporter._get_reports_to_display('compatible') exact = terminalreporter._get_reports_to_display('exact') total = len(incompatible) + len(passable) + len(compatible) + len(exact) if total < 1: return incompatible_percent = int((len(incompatible)/total)*100) passable_percent = int((len(passable)/total)*100) compatible_percent = int((len(compatible)/total)*100) exact_percent = int((len(exact)/total)*100) final_percent = ((len(exact)+len(compatible))/total)*100 parts = ( (f'incompatible: {incompatible_percent:02d}%', {'red': True}), (f'passable: {passable_percent:02d}%', {'yellow': True}), (f'compatible: {compatible_percent:02d}%', {'green': True}), (f'exact: {exact_percent:02d}%', {'green': True}), ( f'final: {final_percent:02.2f}%', { 'green' if final_percent > 80 else 'red': True, }, ), ) line_parts = [] for text, markup in parts: with_markup = terminalreporter._tw.markup(text, **markup) line_parts.append(with_markup) msg = ', '.join(line_parts) terminalreporter.write_line(msg) def pytest_addoption(parser): parser.addoption( '--hasher', default='go run ./hashImage -file {}', help="The commandline image hasher to test ('go run ./hashImage -file {}')", ) parser.addoption( '--image-dir', default='_examples/images', help='The file path to a directory of images to test', ) parser.addoption( '--fail-skip', action='store_true', help="skip images that can't be decoded", ) def pytest_generate_tests(metafunc): if 'file' in metafunc.fixturenames: file = metafunc.config.getoption('--image-dir') files = [] cwd = pathlib.Path('').absolute() for p in pathlib.Path(file).iterdir(): if not p.is_file(): continue p = p.absolute() if p.is_relative_to(cwd): files.append(str(p.relative_to(cwd))) else: files.append(str(p.absolute())) metafunc.parametrize('file', files)