Skip to content

Commit

Permalink
chore: remove setup/call/teardown steps
Browse files Browse the repository at this point in the history
This creates 3x more spans for each test which is too verbose.

Change-Id: I231dbdb610669e6aa691e5f08a3b261a1b7a13e4
  • Loading branch information
jd committed Dec 27, 2024
1 parent 84b6fe3 commit c7a5b64
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 140 deletions.
62 changes: 14 additions & 48 deletions pytest_mergify/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,59 +123,25 @@ def pytest_runtest_protocol(
else:
yield

@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_setup(
self, item: _pytest.nodes.Item
) -> typing.Generator[None, None, None]:
if self.tracer:
with self.tracer.start_as_current_span(
f"{item.nodeid}::setup",
attributes=self._attributes_from_item(item)
| {"test.type": "test.setup"},
):
yield
else:
yield

@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_call(
self, item: _pytest.nodes.Item
) -> typing.Generator[None, None, None]:
if self.tracer:
with self.tracer.start_as_current_span(
name=f"{item.nodeid}::call",
attributes=self._attributes_from_item(item)
| {"test.type": "test.call"},
):
yield
else:
yield

@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_teardown(
self, item: _pytest.nodes.Item
) -> typing.Generator[None, None, None]:
if self.tracer:
with self.tracer.start_as_current_span(
name=f"{item.nodeid}::teardown",
attributes=self._attributes_from_item(item)
| {"test.type": "test.teardown"},
):
# Since there is no pytest_fixture_teardown hook, we have to be a
# little clever to capture the spans for each fixture's teardown.
# The pytest_fixture_post_finalizer hook is called at the end of a
# fixture's teardown, but we don't know when the fixture actually
# began tearing down.
#
# Instead start a span here for the first fixture to be torn down,
# but give it a temporary name, since we don't know which fixture it
# will be. Then, in pytest_fixture_post_finalizer, when we do know
# which fixture is being torn down, update the name and attributes
# to the actual fixture, end the span, and create the span for the
# next fixture in line to be torn down.
self._fixture_teardown_span = self.tracer.start_span("fixture teardown")
yield

# Since there is no pytest_fixture_teardown hook, we have to be a
# little clever to capture the spans for each fixture's teardown.
# The pytest_fixture_post_finalizer hook is called at the end of a
# fixture's teardown, but we don't know when the fixture actually
# began tearing down.
#
# Instead start a span here for the first fixture to be torn down,
# but give it a temporary name, since we don't know which fixture it
# will be. Then, in pytest_fixture_post_finalizer, when we do know
# which fixture is being torn down, update the name and attributes
# to the actual fixture, end the span, and create the span for the
# next fixture in line to be torn down.
self._fixture_teardown_span = self.tracer.start_span("fixture teardown")
yield
# The last call to pytest_fixture_post_finalizer will create
# a span that is unneeded, so delete it.
del self._fixture_teardown_span
Expand Down
92 changes: 0 additions & 92 deletions tests/test_spans.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ def test_span(
assert set(spans.keys()) == {
"pytest session start",
"test_span.py::test_pass",
"test_span.py::test_pass::setup",
"test_span.py::test_pass::call",
"test_span.py::test_pass::teardown",
}


Expand Down Expand Up @@ -45,15 +42,6 @@ def test_test(
result, spans = pytester_with_spans()
session_span = spans["pytest session start"]

expected_spans = (
"test_test.py::test_pass",
"test_test.py::test_pass::setup",
"test_test.py::test_pass::call",
"test_test.py::test_pass::teardown",
)
for name in expected_spans:
assert name in spans

assert spans["test_test.py::test_pass"].attributes == {
"test.type": "test",
"code.function": "test_pass",
Expand All @@ -71,57 +59,13 @@ def test_test(
spans["test_test.py::test_pass"].parent.span_id == session_span.context.span_id
)

assert spans["test_test.py::test_pass::setup"].attributes == {
"test.type": "test.setup",
"code.function": "test_pass",
"code.lineno": 0,
"code.filepath": "test_test.py",
"test.case.name": "test_test.py::test_pass",
}
assert (
spans["test_test.py::test_pass::setup"].status.status_code
== opentelemetry.trace.StatusCode.UNSET
)

assert spans["test_test.py::test_pass::call"].attributes == {
"test.type": "test.call",
"code.function": "test_pass",
"code.lineno": 0,
"code.filepath": "test_test.py",
"test.case.name": "test_test.py::test_pass",
}
assert (
spans["test_test.py::test_pass::call"].status.status_code
== opentelemetry.trace.StatusCode.UNSET
)

assert spans["test_test.py::test_pass::teardown"].attributes == {
"test.type": "test.teardown",
"code.function": "test_pass",
"code.lineno": 0,
"code.filepath": "test_test.py",
"test.case.name": "test_test.py::test_pass",
}
assert (
spans["test_test.py::test_pass::teardown"].status.status_code
== opentelemetry.trace.StatusCode.UNSET
)


def test_test_failure(
pytester_with_spans: conftest.PytesterWithSpanT,
) -> None:
result, spans = pytester_with_spans("def test_error(): assert False, 'foobar'")
session_span = spans["pytest session start"]

expected_spans = (
"test_test_failure.py::test_error",
"test_test_failure.py::test_error::setup",
"test_test_failure.py::test_error::call",
)
for name in expected_spans:
assert name in spans

assert spans["test_test_failure.py::test_error"].attributes == {
"test.type": "test",
"code.function": "test_error",
Expand Down Expand Up @@ -151,42 +95,6 @@ def test_test_failure(
== session_span.context.span_id
)

assert spans["test_test_failure.py::test_error::setup"].attributes == {
"test.type": "test.setup",
"code.function": "test_error",
"code.lineno": 0,
"code.filepath": "test_test_failure.py",
"test.case.name": "test_test_failure.py::test_error",
}
assert (
spans["test_test_failure.py::test_error::setup"].status.status_code
== opentelemetry.trace.StatusCode.UNSET
)

assert spans["test_test_failure.py::test_error::call"].attributes == {
"test.type": "test.call",
"code.function": "test_error",
"code.lineno": 0,
"code.filepath": "test_test_failure.py",
"test.case.name": "test_test_failure.py::test_error",
}
assert (
spans["test_test_failure.py::test_error::call"].status.status_code
== opentelemetry.trace.StatusCode.UNSET
)

assert spans["test_test_failure.py::test_error::teardown"].attributes == {
"test.type": "test.teardown",
"code.function": "test_error",
"code.lineno": 0,
"code.filepath": "test_test_failure.py",
"test.case.name": "test_test_failure.py::test_error",
}
assert (
spans["test_test_failure.py::test_error::teardown"].status.status_code
== opentelemetry.trace.StatusCode.UNSET
)


def test_fixture(
pytester_with_spans: conftest.PytesterWithSpanT,
Expand Down

0 comments on commit c7a5b64

Please sign in to comment.