Skip to content

Commit 8f6388d

Browse files
authored
fix[pytest]: extract module name from DoctestItem (#2794)
* Find module name from Doctest Item when using pytest with doctest * Fix changelog * Add type checking for Doctest object
1 parent d1342cf commit 8f6388d

File tree

4 files changed

+40
-1
lines changed

4 files changed

+40
-1
lines changed

ddtrace/contrib/pytest/plugin.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from doctest import DocTest
12
import json
23
from typing import Dict
34

@@ -118,7 +119,10 @@ def pytest_runtest_protocol(item, nextitem):
118119
span.set_tag(SPAN_KIND, KIND)
119120
span.set_tag(test.FRAMEWORK, FRAMEWORK)
120121
span.set_tag(test.NAME, item.name)
121-
span.set_tag(test.SUITE, item.module.__name__)
122+
if hasattr(item, "module"):
123+
span.set_tag(test.SUITE, item.module.__name__)
124+
elif hasattr(item, "dtest") and isinstance(item.dtest, DocTest):
125+
span.set_tag(test.SUITE, item.dtest.globs["__name__"])
122126
span.set_tag(test.TYPE, SpanTypes.TEST.value)
123127

124128
# Parameterized test cases will have a `callspec` attribute attached to the pytest Item object.

docs/spelling_wordlist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ dbapi
4545
ddtrace
4646
deprecations
4747
django
48+
doctest
4849
dogpile
4950
dogpile.cache
5051
dogstatsd
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
fixes:
3+
- |
4+
Fixes an issue when using the pytest plugin with doctest which raises an ``AttributeError`` on ``DoctestItem``.

tests/contrib/pytest/test_pytest.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,36 @@ def test_service(ddspan, pytestconfig):
498498
for span in decoded_trace:
499499
assert span[b"meta"][b"_dd.origin"] == b"ciapp-test"
500500

501+
def test_pytest_doctest_module(self):
502+
"""Test that pytest with doctest works as expected."""
503+
py_file = self.testdir.makepyfile(
504+
"""
505+
'''
506+
This module supplies one function foo(). For example,
507+
>>> foo()
508+
42
509+
'''
510+
511+
def foo():
512+
'''Returns the answer to life, the universe, and everything.
513+
>>> foo()
514+
42
515+
'''
516+
return 42
517+
518+
def test_foo():
519+
assert foo() == 42
520+
"""
521+
)
522+
file_name = os.path.basename(py_file.strpath)
523+
rec = self.inline_run("--ddtrace", "--doctest-modules", file_name)
524+
rec.assertoutcome(passed=3)
525+
spans = self.pop_spans()
526+
527+
assert len(spans) == 3
528+
for span in spans:
529+
assert span.get_tag(test.SUITE) == file_name.partition(".py")[0]
530+
501531

502532
@pytest.mark.parametrize(
503533
"repository_url,repository_name",

0 commit comments

Comments
 (0)