-
Notifications
You must be signed in to change notification settings - Fork 232
/
Copy pathconftest.py
109 lines (78 loc) · 3.12 KB
/
conftest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import json
import logging
from pathlib import Path
import pytest
BASELINE_DIRECTORY = Path(__file__).parent.resolve() / Path("tests") / Path("baselines") / Path("fixture")
def walk_path(path: Path):
"""
Taken from https://stackoverflow.com/a/76236680
Path.walk() is not available until python 3.12
"""
subdirs = [d for d in path.iterdir() if d.is_dir()]
files = [f for f in path.iterdir() if f.is_file()]
yield path, subdirs, files
for s in subdirs:
yield from walk_path(s)
class Baseline:
def __init__(self, session):
self.rebase = session.config.option.rebase
self.references = {}
if BASELINE_DIRECTORY.exists():
for root, dirs, files in walk_path(BASELINE_DIRECTORY):
for name in files:
with (root / name).open() as f:
self.references.update(json.load(f))
def get_reference(self, addr, context=[]):
reference = self.references.setdefault(addr, {})
for c in context:
reference = reference.setdefault(c, {})
return reference
def finalize(self):
if self.rebase:
# aggregate refs by test file
refsbyfile = {}
for case, ref in self.references.items():
key = case.split("::")[0]
reffile = BASELINE_DIRECTORY / Path(key).with_suffix(".json")
refsbyfile.setdefault(reffile, {})[case] = ref
# dump aggregated refs into their own files
for reffile, refs in refsbyfile.items():
reffile.parent.mkdir(parents=True, exist_ok=True)
with reffile.open("w+") as f:
json.dump(refs, f, indent=2, sort_keys=True)
class BaselineRequest:
def __init__(self, request):
self.baseline = request.session.stash["baseline"]
self.addr = request.node.nodeid
def assertRef(self, compare, context=[], **kwargs):
reference = self.baseline.get_reference(self.addr, context)
if self.baseline.rebase:
reference.update(**kwargs)
for key, actual in kwargs.items():
ref = reference.get(key, None)
logging.getLogger().info(f"{'.'.join(context + [key])}:actual = {actual}")
logging.getLogger().info(f"{'.'.join(context + [key])}:ref = {ref}")
assert compare(actual, ref)
class Secret:
"""
Taken from: https://stackoverflow.com/a/67393351
"""
def __init__(self, value):
self.value = value
def __repr__(self):
return "Secret(********)"
def __str___(self):
return "*******"
def pytest_addoption(parser):
parser.addoption("--token", action="store", default=None)
parser.addoption("--rebase", action="store_true", help="rebase baseline references from current run")
@pytest.fixture
def token(request):
return Secret(request.config.option.token)
def pytest_sessionstart(session):
session.stash["baseline"] = Baseline(session)
def pytest_sessionfinish(session):
session.stash["baseline"].finalize()
@pytest.fixture
def baseline(request):
return BaselineRequest(request)