from pathlib import Path from django.apps import apps from django.test.runner import DiscoverRunner class AppDiscoverRunner(DiscoverRunner): def load_tests_for_label(self, label, discover_kwargs): if label.startswith("apps."): try: app_config = apps.get_app_config(label.split(".", 1)[1]) except LookupError: return super().load_tests_for_label(label, discover_kwargs) test_dir = Path(app_config.path) / "tests" if test_dir.exists(): repo_root = Path(__file__).resolve().parent.parent discover_kwargs = dict(discover_kwargs) discover_kwargs["top_level_dir"] = str(repo_root) return self.test_loader.discover( start_dir=str(test_dir), **discover_kwargs, ) return super().load_tests_for_label(label, discover_kwargs) def build_suite(self, test_labels=None, extra_tests=None, **kwargs): if test_labels: return super().build_suite( test_labels, extra_tests=extra_tests, **kwargs, ) suite = self.test_suite() repo_root = Path(__file__).resolve().parent.parent for app_config in apps.get_app_configs(): test_dir = Path(app_config.path) / "tests" if app_config.name.startswith("apps.") and test_dir.exists(): suite.addTests( self.test_loader.discover( start_dir=str(test_dir), pattern=self.pattern, top_level_dir=str(repo_root), ) ) if extra_tests: suite.addTests(extra_tests) return suite