@@ -212,7 +212,7 @@ def test_1(self, item):
212212 assert json .loads (spans [0 ].meta [test .PARAMETERS ]) == {"arguments" : {"item" : "Could not encode" }, "metadata" : {}}
213213
214214 def test_skip (self ):
215- """Test parametrize case."""
215+ """Test skip case."""
216216 py_file = self .testdir .makepyfile (
217217 """
218218 import pytest
@@ -236,6 +236,62 @@ def test_body():
236236 assert spans [1 ].get_tag (test .STATUS ) == test .Status .SKIP .value
237237 assert spans [1 ].get_tag (test .SKIP_REASON ) == "body"
238238
239+ def test_skip_module_with_xfail_cases (self ):
240+ """Test Xfail test cases for a module that is skipped entirely, which should be treated as skip tests."""
241+ py_file = self .testdir .makepyfile (
242+ """
243+ import pytest
244+
245+ pytestmark = pytest.mark.skip(reason="reason")
246+
247+ @pytest.mark.xfail(reason="XFail Case")
248+ def test_xfail():
249+ pass
250+
251+ @pytest.mark.xfail(condition=False, reason="XFail Case")
252+ def test_xfail_conditional():
253+ pass
254+ """
255+ )
256+ file_name = os .path .basename (py_file .strpath )
257+ rec = self .inline_run ("--ddtrace" , file_name )
258+ rec .assertoutcome (skipped = 2 )
259+ spans = self .pop_spans ()
260+
261+ assert len (spans ) == 2
262+ assert spans [0 ].get_tag (test .STATUS ) == test .Status .SKIP .value
263+ assert spans [0 ].get_tag (test .SKIP_REASON ) == "reason"
264+ assert spans [1 ].get_tag (test .STATUS ) == test .Status .SKIP .value
265+ assert spans [1 ].get_tag (test .SKIP_REASON ) == "reason"
266+
267+ def test_skipif_module (self ):
268+ """Test XFail test cases for a module that is skipped entirely with the skipif marker."""
269+ py_file = self .testdir .makepyfile (
270+ """
271+ import pytest
272+
273+ pytestmark = pytest.mark.skipif(True, reason="reason")
274+
275+ @pytest.mark.xfail(reason="XFail")
276+ def test_xfail():
277+ pass
278+
279+ @pytest.mark.xfail(condition=False, reason="XFail Case")
280+ def test_xfail_conditional():
281+ pass
282+ """
283+ )
284+ file_name = os .path .basename (py_file .strpath )
285+ rec = self .inline_run ("--ddtrace" , file_name )
286+ rec .assertoutcome (skipped = 2 )
287+ spans = self .pop_spans ()
288+
289+ assert len (spans ) == 2
290+ assert spans [0 ].get_tag (test .STATUS ) == test .Status .SKIP .value
291+ assert spans [0 ].get_tag (test .SKIP_REASON ) == "reason"
292+ assert spans [1 ].get_tag (test .STATUS ) == test .Status .SKIP .value
293+ assert spans [1 ].get_tag (test .SKIP_REASON ) == "reason"
294+
239295 def test_xfail_fails (self ):
240296 """Test xfail (expected failure) which fails, should be marked as pass."""
241297 py_file = self .testdir .makepyfile (
@@ -245,18 +301,25 @@ def test_xfail_fails(self):
245301 @pytest.mark.xfail(reason="test should fail")
246302 def test_should_fail():
247303 assert 0
304+
305+ @pytest.mark.xfail(condition=True, reason="test should xfail")
306+ def test_xfail_conditional():
307+ assert 0
248308 """
249309 )
250310 file_name = os .path .basename (py_file .strpath )
251311 rec = self .inline_run ("--ddtrace" , file_name )
252312 # pytest records xfail as skipped
253- rec .assertoutcome (skipped = 1 )
313+ rec .assertoutcome (skipped = 2 )
254314 spans = self .pop_spans ()
255315
256- assert len (spans ) == 1
316+ assert len (spans ) == 2
257317 assert spans [0 ].get_tag (test .STATUS ) == test .Status .PASS .value
258318 assert spans [0 ].get_tag (test .RESULT ) == test .Status .XFAIL .value
259319 assert spans [0 ].get_tag (test .XFAIL_REASON ) == "test should fail"
320+ assert spans [1 ].get_tag (test .STATUS ) == test .Status .PASS .value
321+ assert spans [1 ].get_tag (test .RESULT ) == test .Status .XFAIL .value
322+ assert spans [1 ].get_tag (test .XFAIL_REASON ) == "test should xfail"
260323
261324 def test_xpass_not_strict (self ):
262325 """Test xpass (unexpected passing) with strict=False, should be marked as pass."""
@@ -265,19 +328,26 @@ def test_xpass_not_strict(self):
265328 import pytest
266329
267330 @pytest.mark.xfail(reason="test should fail")
268- def test_should_fail():
331+ def test_should_fail_but_passes():
332+ pass
333+
334+ @pytest.mark.xfail(condition=True, reason="test should not xfail")
335+ def test_should_not_fail():
269336 pass
270337 """
271338 )
272339 file_name = os .path .basename (py_file .strpath )
273340 rec = self .inline_run ("--ddtrace" , file_name )
274- rec .assertoutcome (passed = 1 )
341+ rec .assertoutcome (passed = 2 )
275342 spans = self .pop_spans ()
276343
277- assert len (spans ) == 1
344+ assert len (spans ) == 2
278345 assert spans [0 ].get_tag (test .STATUS ) == test .Status .PASS .value
279346 assert spans [0 ].get_tag (test .RESULT ) == test .Status .XPASS .value
280347 assert spans [0 ].get_tag (test .XFAIL_REASON ) == "test should fail"
348+ assert spans [1 ].get_tag (test .STATUS ) == test .Status .PASS .value
349+ assert spans [1 ].get_tag (test .RESULT ) == test .Status .XPASS .value
350+ assert spans [1 ].get_tag (test .XFAIL_REASON ) == "test should not xfail"
281351
282352 def test_xpass_strict (self ):
283353 """Test xpass (unexpected passing) with strict=True, should be marked as fail."""
@@ -298,8 +368,8 @@ def test_should_fail():
298368 assert len (spans ) == 1
299369 assert spans [0 ].get_tag (test .STATUS ) == test .Status .FAIL .value
300370 assert spans [0 ].get_tag (test .RESULT ) == test .Status .XPASS .value
301- # Note: xpass (strict=True) does not mark the reason with result.wasxfail but into result.longrepr,
302- # however this provides the entire traceback/error into longrepr.
371+ # Note: XFail (strict=True) does not mark the reason with result.wasxfail but into result.longrepr,
372+ # however it provides the entire traceback/error into longrepr.
303373 assert "test should fail" in spans [0 ].get_tag (test .XFAIL_REASON )
304374
305375 def test_tags (self ):
0 commit comments