def _load_unittest_test_cases()

in testslide/cli.py [0:0]


def _load_unittest_test_cases(import_module_names: List[str]) -> None:
    """
    Beta!
    Search for all unittest.TestCase classes that have tests defined, and import them
    as TestSlide contexts and examples. This is useful if you mix unittest.TestCase
    tests and TestSlide at the same file, or if you want to just use TestSlide's test
    runner for existing unittest.TestCase tests.
    """
    global _unittest_testcase_loaded
    if _unittest_testcase_loaded:
        return
    _unittest_testcase_loaded = True

    for test_case in _get_all_test_cases(import_module_names):

        test_method_names = [
            test_method_name
            for test_method_name in dir(test_case)
            if test_method_name.startswith("test")
            or test_method_name.startswith("ftest")
            or test_method_name.startswith("xtest")
            # FIXME: debug why ismethod is not properly filtering methods. Using
            # callabdle as a workaround.
            # if inspect.ismethod(getattr(test_case, test_method_name))
            if callable(getattr(test_case, test_method_name))
        ]

        if not test_method_names:
            continue

        # This extra method is needed so context_code is evaluated with different
        # values of test_case.
        def get_context_code(
            test_case: unittest.TestCase,
        ) -> Callable[[testslide.dsl._DSLContext], None]:
            def context_code(context: testslide.dsl._DSLContext) -> None:

                for test_method_name in test_method_names:

                    @contextmanager
                    def test_result() -> Iterator[_TestSlideTestResult]:
                        result = _TestSlideTestResult()
                        yield result
                        result.aggregated_exceptions.raise_correct_exception()

                    @contextmanager
                    def setup_and_teardown() -> Iterator[None]:
                        test_case.setUpClass()
                        yield
                        test_case.tearDownClass()

                    # Same trick as above.
                    def gen_example_code(test_method_name: str) -> Callable:
                        def example_code(self: Any) -> None:
                            with test_result() as result:
                                with setup_and_teardown():
                                    test_case(methodName=test_method_name)(  # type: ignore
                                        result=result
                                    )

                        return example_code

                    # Regular example
                    if test_method_name.startswith("test"):
                        context.example(test_method_name)(
                            gen_example_code(test_method_name)
                        )
                    # Focused example
                    if test_method_name.startswith("ftest"):
                        context.fexample(test_method_name)(
                            gen_example_code(test_method_name)
                        )
                    # Skipped example
                    if test_method_name.startswith("xtest"):
                        context.xexample(test_method_name)(
                            gen_example_code(test_method_name)
                        )

            return context_code

        testslide.dsl.context("{}.{}".format(test_case.__module__, test_case.__name__))(  # type: ignore
            get_context_code(test_case)
        )