-
Notifications
You must be signed in to change notification settings - Fork 0
/
pytest_json_fixtures.py
89 lines (78 loc) · 3.22 KB
/
pytest_json_fixtures.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
# -*- coding: utf-8 -*-
import inspect
import json
import sys
from pathlib import Path
from typing import Set, Tuple
import pytest
from _pytest.compat import getlocation
from _pytest.python import _pretty_fixture_path
def pytest_addoption(parser):
group = parser.getgroup('json-fixtures')
group.addoption(
'--json-fixtures',
action='store_true',
dest='json-fixtures',
default=False,
help='JSON output for the --fixtures flag.'
)
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_collection_modifyitems(session, config, items):
if config.getoption("json-fixtures"):
items.clear()
curdir = Path.cwd()
verbose = config.getvalue("verbose")
seen: Set[Tuple[str, str]] = set()
available = []
fixtures_from_module = {}
for argname, fixturedefs in session._fixturemanager._arg2fixturedefs.items():
assert fixturedefs is not None
if not fixturedefs:
continue
for fixturedef in fixturedefs:
loc = getlocation(fixturedef.func, str(curdir))
if (fixturedef.argname, loc) in seen:
continue
seen.add((fixturedef.argname, loc))
available.append(
(
len(fixturedef.baseid),
fixturedef.func.__module__,
_pretty_fixture_path(fixturedef.func),
fixturedef.argname,
fixturedef,
)
)
available.sort()
currentmodule = None
fixtures = []
for baseid, module, prettypath, argname, fixturedef in available:
if currentmodule != module:
if not module.startswith("_pytest."):
if f"fixtures defined from {currentmodule}" in fixtures_from_module:
fixtures.append(
{
f"fixtures defined from {currentmodule}":
fixtures_from_module[f"fixtures defined from {currentmodule}"]
}
)
currentmodule = module
fixtures_from_module[f"fixtures defined from {currentmodule}"] = []
if verbose <= 0 and argname.startswith("_"):
continue
fixture = {"name": argname, "scope": fixturedef.scope, "path": prettypath}
doc = inspect.getdoc(fixturedef.func)
if doc:
write_docstring(fixture, doc.split("\n\n")[0] if verbose <= 0 else doc)
else:
fixture["docstring"] = "no docstring available"
if not module.startswith("_pytest.") and f"fixtures defined from {currentmodule}" in fixtures_from_module:
fixtures_from_module[f"fixtures defined from {currentmodule}"].append(fixture)
else:
fixtures.append(fixture)
json.dump(fixtures, sys.stdout, sort_keys=True, indent=4)
outcome = yield
def write_docstring(fixture, doc):
fixture["docstring"] = ""
for line in doc.split("\n"):
fixture["docstring"] = fixture["docstring"] + line