Commit 6960e188 authored by Dom Sekotill's avatar Dom Sekotill
Browse files

Add support for setup & teardown methods

parent eb83192f
Loading
Loading
Loading
Loading
Loading
+32 −4
Original line number Diff line number Diff line
@@ -37,14 +37,42 @@ class DynamicContextPlugin(CoveragePlugin):
	"""

	def dynamic_context(self, frame: FrameType) -> str|None:  # noqa: D102
		if not frame.f_code.co_name.startswith("test"):
		name = frame.f_code.co_name
		if name.startswith("test"):
			return self.test_context(frame, "run")
		if name == "setUp":
			return self.test_context(frame, "setup")
		if name == "tearDown":
			return self.test_context(frame, "teardown")
		if name == "setUpClass":
			return self.testcase_context(frame, "testcase-setup")
		if name == "tearDownClass":
			return self.testcase_context(frame, "testcase-teardown")
		return None

	def test_context(self, frame: FrameType, stage: str) -> str|None:
		"""
		Return a context string for test-case test setup and teardown methods, or None
		"""
		try:
			inst = frame.f_locals["self"]
		except KeyError:
			return None
		if isinstance(inst, TestCase):
			return str(inst)
		if isinstance(inst, TestCase) and inst._testMethodName != "runTest":
			cls = type(inst)
			return f"{stage} :: {inst._testMethodName} ({cls.__module__}.{cls.__name__})"
		return None

	def testcase_context(self, frame: FrameType, stage: str) -> str|None:
		"""
		Return a context string for test-case setup and teardown methods, or None
		"""
		try:
			cls = frame.f_locals["cls"]
		except KeyError:
			return None
		if issubclass(cls, TestCase):
			return f"{stage} :: {cls.__name__} ({cls.__module__})"
		return None