Skip to content

Commit 690afc2

Browse files
authored
feat: include skipped tests (#100)
1 parent d412ad8 commit 690afc2

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

pytest_mergify/__init__.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,30 @@ def pytest_runtest_protocol(
107107
self, item: _pytest.nodes.Item
108108
) -> typing.Generator[None, None, None]:
109109
if self.tracer:
110+
if item.get_closest_marker("skip") is not None:
111+
skip = True
112+
elif (skipif_marker := item.get_closest_marker("skipif")) is not None:
113+
condition = skipif_marker.args[0]
114+
if isinstance(condition, str):
115+
# Evaluate the condition in the test module's global namespace.
116+
# nosemgrep: python.lang.security.audit.eval-detected.eval-detected
117+
skip = eval(condition, item.module.__dict__) # type: ignore[attr-defined]
118+
else:
119+
skip = bool(condition)
120+
else:
121+
skip = False
122+
123+
if skip:
124+
skip_attributes = {"test.case.result.status": "skipped"}
125+
else:
126+
skip_attributes = {}
127+
110128
context = opentelemetry.trace.set_span_in_context(self.session_span)
111129
with self.tracer.start_as_current_span(
112130
item.name,
113131
attributes={
114132
**self._attributes_from_item(item),
133+
**skip_attributes,
115134
**{"test.scope": "case"},
116135
},
117136
context=context,

tests/test_spans.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import opentelemetry.trace
22
from opentelemetry.semconv.trace import SpanAttributes
33

4+
import pytest
45

56
from tests import conftest
67

@@ -107,6 +108,69 @@ def test_skipped():
107108
assert spans["test_skipped"].parent.span_id == session_span.context.span_id
108109

109110

111+
@pytest.mark.parametrize(
112+
"mark",
113+
[
114+
"skip",
115+
"skipif(True, reason='not needed')",
116+
"skipif(1 + 1, reason='with eval')",
117+
"skipif('1 + 1', reason='as str')",
118+
],
119+
)
120+
def test_mark_skipped(
121+
mark: str,
122+
pytester_with_spans: conftest.PytesterWithSpanT,
123+
) -> None:
124+
result, spans = pytester_with_spans(f"""
125+
import pytest
126+
@pytest.mark.{mark}
127+
def test_skipped():
128+
assert False
129+
""")
130+
session_span = spans["pytest session start"]
131+
132+
assert spans["test_skipped"].attributes == {
133+
"test.case.result.status": "skipped",
134+
"test.scope": "case",
135+
"code.function": "test_skipped",
136+
"code.lineno": 1,
137+
"code.filepath": "test_mark_skipped.py",
138+
}
139+
assert (
140+
spans["test_skipped"].status.status_code == opentelemetry.trace.StatusCode.UNSET
141+
)
142+
assert session_span.context is not None
143+
assert spans["test_skipped"].parent is not None
144+
assert spans["test_skipped"].parent.span_id == session_span.context.span_id
145+
146+
147+
def test_mark_not_skipped(
148+
pytester_with_spans: conftest.PytesterWithSpanT,
149+
) -> None:
150+
result, spans = pytester_with_spans("""
151+
import pytest
152+
@pytest.mark.skipif(False, reason='not skipped')
153+
def test_not_skipped():
154+
assert True
155+
""")
156+
session_span = spans["pytest session start"]
157+
158+
assert spans["test_not_skipped"].attributes == {
159+
"test.case.result.status": "passed",
160+
"test.scope": "case",
161+
"code.function": "test_not_skipped",
162+
"code.lineno": 1,
163+
"code.filepath": "test_mark_not_skipped.py",
164+
}
165+
assert (
166+
spans["test_not_skipped"].status.status_code
167+
== opentelemetry.trace.StatusCode.OK
168+
)
169+
assert session_span.context is not None
170+
assert spans["test_not_skipped"].parent is not None
171+
assert spans["test_not_skipped"].parent.span_id == session_span.context.span_id
172+
173+
110174
def test_span_resources_test_run_id(
111175
pytester_with_spans: conftest.PytesterWithSpanT,
112176
) -> None:

0 commit comments

Comments
 (0)