Skip to content

Commit 5dc0330

Browse files
pytestplugin/hooks: combine multiple lg_feature markers instead of overwriting previous ones
pytest allows setting markers via function decorators [1], class decorators [2] and "pytestmark" global to mark whole modules [2]. Additionally, each of these variants can specify multiple markers. labgrid's pytest plugin considered only the closest marker. Change that to allow combinations of multiple markers. This allows use cases like: import pytest pytestmark = pytest.mark.lg_feature("watchdog") @pytest.mark.lg_feature("barebox") def test_watchdog_barebox(barebox): .. Tests in this module are only run if the feature flag "watchdog" is available. The specific test "test_watchdog_barebox" is only run if the feature flag "barebox" is available additionally. [1] https://docs.pytest.org/en/latest/example/markers.html#adding-a-custom-marker-from-a-plugin [2] https://docs.pytest.org/en/latest/example/markers.html#marking-whole-classes-or-modules Signed-off-by: Bastian Krause <[email protected]>
1 parent f465656 commit 5dc0330

File tree

3 files changed

+78
-10
lines changed

3 files changed

+78
-10
lines changed

CHANGES.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Release 0.5.0 (unreleased)
44
New Features in 0.5.0
55
~~~~~~~~~~~~~~~~~~~~~
66
- Support for Eaton ePDU added, and can be used as a NetworkPowerPort.
7+
- Consider a combination of multiple "lg_feature" markers instead of
8+
considering only the closest marker.
79

810
Bug fixes in 0.5.0
911
~~~~~~~~~~~~~~~~~~

labgrid/pytestplugin/hooks.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,16 @@ def pytest_collection_modifyitems(config, items):
6161
have_feature = env.get_features() | env.get_target_features()
6262

6363
for item in items:
64-
marker = item.get_closest_marker("lg_feature")
65-
if not marker:
66-
continue
64+
want_feature = set()
6765

68-
arg = marker.args[0]
69-
if isinstance(arg, str):
70-
want_feature = set([arg])
71-
elif isinstance(arg, list):
72-
want_feature = set(arg)
73-
else:
74-
raise Exception("Unsupported feature argument type")
66+
for marker in item.iter_markers("lg_feature"):
67+
arg = marker.args[0]
68+
if isinstance(arg, str):
69+
want_feature.add(arg)
70+
elif isinstance(arg, list):
71+
want_feature.update(arg)
72+
else:
73+
raise Exception("Unsupported feature argument type")
7574
missing_feature = want_feature - have_feature
7675
if missing_feature:
7776
if len(missing_feature) == 1:

tests/test_flags.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,70 @@ def test(env):
112112
spawn.expect(pexpect.EOF)
113113
spawn.close()
114114
assert spawn.exitstatus == 0
115+
116+
def test_match_multi_feature_source(tmpdir):
117+
conf = tmpdir.join("config.yaml")
118+
conf.write(
119+
"""
120+
targets:
121+
test1:
122+
features:
123+
- test1
124+
- test2
125+
- test3
126+
drivers: {}
127+
"""
128+
)
129+
test = tmpdir.join("test.py")
130+
test.write(
131+
"""
132+
import pytest
133+
134+
pytestmark = pytest.mark.lg_feature("test1")
135+
136+
@pytest.mark.lg_feature("test2")
137+
class TestMulti:
138+
@pytest.mark.lg_feature("test3")
139+
def test(self, env):
140+
assert True
141+
"""
142+
)
143+
144+
with pexpect.spawn(f'pytest --lg-env {conf} {test}') as spawn:
145+
spawn.expect("1 passed")
146+
spawn.expect(pexpect.EOF)
147+
spawn.close()
148+
assert spawn.exitstatus == 0
149+
150+
def test_skip_multi_feature_source(tmpdir):
151+
conf = tmpdir.join("config.yaml")
152+
conf.write(
153+
"""
154+
targets:
155+
test1:
156+
features:
157+
- test1
158+
- test3
159+
drivers: {}
160+
"""
161+
)
162+
test = tmpdir.join("test.py")
163+
test.write(
164+
"""
165+
import pytest
166+
167+
pytestmark = pytest.mark.lg_feature("test1")
168+
169+
@pytest.mark.lg_feature("test2")
170+
class TestMulti:
171+
@pytest.mark.lg_feature("test3")
172+
def test(self, env):
173+
assert True
174+
"""
175+
)
176+
177+
with pexpect.spawn(f'pytest --lg-env {conf} {test}') as spawn:
178+
spawn.expect("1 skipped")
179+
spawn.expect(pexpect.EOF)
180+
spawn.close()
181+
assert spawn.exitstatus == 0

0 commit comments

Comments
 (0)