Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collect dependencies #56

Open
wants to merge 13 commits into
base: develop
Choose a base branch
from
55 changes: 49 additions & 6 deletions pytest_dependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
__version__ = "$VERSION"

import logging
from pathlib import Path

import py
import pytest
from _pytest.python import Module

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -32,7 +36,7 @@ class DependencyItemStatus(object):
Phases = ('setup', 'call', 'teardown')

def __init__(self):
self.results = { w:None for w in self.Phases }
self.results = {w: None for w in self.Phases}

def __str__(self):
l = ["%s: %s" % (w, self.results[w]) for w in self.Phases]
Expand Down Expand Up @@ -140,19 +144,22 @@ def depends(request, other, scope='module'):


def pytest_addoption(parser):
parser.addini("automark_dependency",
"Add the dependency marker to all tests automatically",
parser.addini("automark_dependency",
"Add the dependency marker to all tests automatically",
default=False)
parser.addini("collect_dependencies",
"Collect the dependent' tests",
default=False)
parser.addoption("--ignore-unknown-dependency",
action="store_true", default=False,
parser.addoption("--ignore-unknown-dependency",
action="store_true", default=False,
help="ignore dependencies whose outcome is not known")


def pytest_configure(config):
global _automark, _ignore_unknown
_automark = _get_bool(config.getini("automark_dependency"))
_ignore_unknown = config.getoption("--ignore-unknown-dependency")
config.addinivalue_line("markers",
config.addinivalue_line("markers",
"dependency(name=None, depends=[]): "
"mark a test to be used as a dependency for "
"other tests or to depend on other tests.")
Expand Down Expand Up @@ -184,3 +191,39 @@ def pytest_runtest_setup(item):
scope = marker.kwargs.get('scope', 'module')
manager = DependencyManager.getManager(item, scope=scope)
manager.checkDepend(depends, item)


def collect_dependencies(config, item, items):
dependencies = list()
markers = item.own_markers
for marker in markers:
depends = marker.kwargs.get('depends')
scope = marker.kwargs.get('scope')
if marker.name == 'dependency' and depends:
for depend in depends:
if scope == 'session' or scope == 'package':
depend_module, depend_func = depend.split("::", 1)
depend_path = py.path.local(Path(config.rootdir) / Path(depend_module))
depend_parent = Module.from_parent(item.parent, fspath=depend_path)
depend_nodeid = depend
else:
depend_func = depend
depend_parent = item.parent
depend_nodeid = '{}::{}'.format(depend_parent.nodeid, depend_func)
# assert depend_nodeid == depend_nodeid2
dependencies.append((depend_func, depend_nodeid, depend_parent))

for depend_func, depend_nodeid, depend_parent in dependencies:
list_of_items_nodeid = [item_i.nodeid for item_i in items]
if depend_nodeid not in list_of_items_nodeid:
item_to_add = pytest.Function.from_parent(name=depend_func, parent=depend_parent)
items.insert(0, item_to_add)
# recursive look for dependencies into item_to_add
collect_dependencies(config, item_to_add, items)
return


def pytest_collection_modifyitems(config, items):
if _get_bool(config.getini('collect_dependencies')):
for item in items:
collect_dependencies(config, item, items)
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
version = f.read()
except (OSError, IOError):
distutils.log.warn("warning: cannot determine version number")
version = "UNKNOWN"
version = "0.5.1.post20212102+ftesser-collect_dependencies-20211216"

doc_string = __doc__

Expand Down
2 changes: 1 addition & 1 deletion tests/test_04_automark.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def test_b():


def test_set_true(ctestdir):
"""A pytest.ini is present, automark_dependency is set to false.
"""A pytest.ini is present, automark_dependency is set to true.

Since automark_dependency is set to true, the outcome of test_a
will be recorded, even though it is not marked. As a result,
Expand Down
Loading