diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 40b68ced..3f0a4f34 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -206,7 +206,7 @@ jobs: - name: Enforce transcription benchmark contract gate run: > uv run --frozen --python 3.12 --extra dev pytest -q - tests/test_transcription_profiling.py + tests/suites/unit/internal/transcription/test_transcription_profiling.py build: runs-on: ubuntu-latest diff --git a/.github/workflows/linux-selfhosted-gpu-validation.yml b/.github/workflows/linux-selfhosted-gpu-validation.yml index 67403a74..1ee9dbe0 100644 --- a/.github/workflows/linux-selfhosted-gpu-validation.yml +++ b/.github/workflows/linux-selfhosted-gpu-validation.yml @@ -146,9 +146,9 @@ jobs: - name: Run CUDA-focused policy/runtime tests run: > uv run --python ${{ inputs.python_version }} --extra dev pytest -q - tests/test_torch_inference.py - tests/test_feature_runtime_policy.py - tests/test_transcription_runtime_policy.py + tests/suites/unit/utils/test_torch_inference.py + tests/suites/unit/repr/test_feature_runtime_policy.py + tests/suites/unit/transcription/test_transcription_runtime_policy.py tests/suites/integration/test_transcript_extractor.py - name: Medium profile train and predict (CUDA lane) @@ -254,11 +254,11 @@ jobs: - name: Run XPU-focused policy/runtime tests run: > uv run --python ${{ inputs.python_version }} --extra dev pytest -q - tests/test_torch_inference.py - tests/test_feature_runtime_policy.py - tests/test_transcription_runtime_policy.py - tests/test_emotion2vec_backend.py - tests/test_accurate_research_inference.py + tests/suites/unit/utils/test_torch_inference.py + tests/suites/unit/repr/test_feature_runtime_policy.py + tests/suites/unit/transcription/test_transcription_runtime_policy.py + tests/suites/unit/repr/test_emotion2vec_backend.py + tests/suites/integration/runtime/test_accurate_research_inference.py - name: Medium profile train and predict (XPU lane) env: diff --git a/.github/workflows/macos15-mps-validation.yml b/.github/workflows/macos15-mps-validation.yml index 9f57315d..53a9a071 100644 --- a/.github/workflows/macos15-mps-validation.yml +++ b/.github/workflows/macos15-mps-validation.yml @@ -97,13 +97,13 @@ jobs: - name: Run MPS-focused runtime policy tests run: > uv run --python ${{ inputs.python_version }} --extra dev pytest -q - tests/test_torch_inference.py - tests/test_feature_runtime_policy.py - tests/test_transcription_runtime_policy.py - tests/test_stable_whisper_mps_compat.py - tests/test_transcription_mps_admission.py - tests/test_transcription_runtime_failures.py - tests/test_transcription_backends.py + tests/suites/unit/utils/test_torch_inference.py + tests/suites/unit/repr/test_feature_runtime_policy.py + tests/suites/unit/transcription/test_transcription_runtime_policy.py + tests/suites/unit/transcription/test_stable_whisper_mps_compat.py + tests/suites/unit/transcription/test_transcription_mps_admission.py + tests/suites/unit/transcription/test_transcription_runtime_failures.py + tests/suites/unit/transcription/test_transcription_backends.py - name: Medium profile train and predict (MPS lane) env: diff --git a/README.md b/README.md index 2eac948d..8ca59599 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,11 @@ If your change touches `ser/api.py`, `ser/_internal/api/*`, or `ser/__main__.py` ```bash make import-lint -uv run pytest -q tests/test_import_lint_policy.py tests/test_api_import_boundary.py tests/test_api.py tests/test_cli.py +uv run pytest -q \ + tests/suites/integration/architecture/test_import_lint_policy.py \ + tests/suites/integration/architecture/test_api_import_boundary.py \ + tests/suites/integration/api/test_api.py \ + tests/suites/integration/cli/test_cli.py ``` ## Acknowledgments diff --git a/docs/codebase-architecture.md b/docs/codebase-architecture.md index 530b71ef..3d1fe404 100644 --- a/docs/codebase-architecture.md +++ b/docs/codebase-architecture.md @@ -271,7 +271,7 @@ Strengths: - narrow public API in [`ser/api.py`](../ser/api.py) - stable public config facade in [`ser/config.py`](../ser/config.py) -- boundary tests in [`tests/test_api_import_boundary.py`](../tests/test_api_import_boundary.py) +- boundary tests in [`tests/suites/integration/architecture/test_api_import_boundary.py`](../tests/suites/integration/architecture/test_api_import_boundary.py) - documented hotspot inventory in [`docs/refactor-hotspot-checks.md`](refactor-hotspot-checks.md) - CI lanes enforcing lint, typing, tests, contracts, and build in [`.github/workflows/ci.yml`](../.github/workflows/ci.yml) diff --git a/docs/subsystem-dependency-map.md b/docs/subsystem-dependency-map.md index 6a53fe0a..bbe066fb 100644 --- a/docs/subsystem-dependency-map.md +++ b/docs/subsystem-dependency-map.md @@ -230,7 +230,7 @@ smaller abstract service boundaries. Public modules allowed to import `_internal` directly by design are defined in [`boundary_policy.toml`](../boundary_policy.toml). That file is authoritative: -[`tests/test_api_import_boundary.py`](../tests/test_api_import_boundary.py) +[`tests/suites/integration/architecture/test_api_import_boundary.py`](../tests/suites/integration/architecture/test_api_import_boundary.py) loads it directly, and `make import-lint` enforces the same contract. Each `[[public_internal_import]]` entry in `boundary_policy.toml` carries both diff --git a/pyproject.toml b/pyproject.toml index 3d4d44bc..99d53215 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -151,7 +151,7 @@ ignore = ["E501"] "ser/_internal/cli/data.py" = ["TID251"] "ser/_internal/cli/diagnostics.py" = ["TID251"] "ser/_internal/cli/runtime.py" = ["TID251"] -"tests/test_api.py" = ["TID251"] +"tests/suites/integration/api/test_api.py" = ["TID251"] [tool.ruff.format] quote-style = "double" diff --git a/scripts/run_import_lint.sh b/scripts/run_import_lint.sh index 95ce8b83..1b5e14e7 100755 --- a/scripts/run_import_lint.sh +++ b/scripts/run_import_lint.sh @@ -9,5 +9,5 @@ readonly IMPORT_LINT_PATHS=( uv run --frozen --extra dev ruff check --select TID251 "${IMPORT_LINT_PATHS[@]}" uv run --frozen --extra dev pytest -q \ - tests/test_api_import_boundary.py \ - tests/test_import_lint_policy.py + tests/suites/integration/architecture/test_api_import_boundary.py \ + tests/suites/integration/architecture/test_import_lint_policy.py diff --git a/tests/conftest.py b/tests/conftest.py index 9fd5dc9c..4763d626 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,4 @@ -"""Shared pytest fixtures for repository-aware test infrastructure.""" +"""Shared pytest fixtures and suite semantics for repository-aware test infrastructure.""" from __future__ import annotations @@ -8,6 +8,55 @@ pytest_plugins = ("tests.fixtures.settings",) +_UNIT_SUITE_PREFIX = ("tests", "suites", "unit") +_INTEGRATION_SUITE_PREFIX = ("tests", "suites", "integration") +_ARCHITECTURE_SUITE_PREFIX = ("tests", "suites", "integration", "architecture") +_SMOKE_SUITE_PREFIX = ("tests", "suites", "smoke") +_RESET_AMBIENT_SETTINGS_FIXTURE = "reset_ambient_settings" + + +def _matches_suite_prefix(path: Path, prefix: tuple[str, ...]) -> bool: + """Returns whether a collected path belongs to the given suite prefix.""" + parts = path.parts + return parts[: len(prefix)] == prefix + + +def _has_usefixture(item: pytest.Item, fixture_name: str) -> bool: + """Returns whether a collected item already requests one fixture by name.""" + return any(fixture_name in marker.args for marker in item.iter_markers(name="usefixtures")) + + +def pytest_collection_modifyitems( + config: pytest.Config, + items: list[pytest.Item], +) -> None: + """Applies suite markers from the tests/suites directory layout.""" + root_path = Path(str(config.rootpath)).resolve() + for item in items: + relative_path = item.path.resolve().relative_to(root_path) + if _matches_suite_prefix(relative_path, _ARCHITECTURE_SUITE_PREFIX): + if "integration" not in item.keywords: + item.add_marker(pytest.mark.integration) + if "topology_contract" not in item.keywords: + item.add_marker(pytest.mark.topology_contract) + if not _has_usefixture(item, _RESET_AMBIENT_SETTINGS_FIXTURE): + item.add_marker(pytest.mark.usefixtures(_RESET_AMBIENT_SETTINGS_FIXTURE)) + continue + if _matches_suite_prefix(relative_path, _INTEGRATION_SUITE_PREFIX): + if "integration" not in item.keywords: + item.add_marker(pytest.mark.integration) + if not _has_usefixture(item, _RESET_AMBIENT_SETTINGS_FIXTURE): + item.add_marker(pytest.mark.usefixtures(_RESET_AMBIENT_SETTINGS_FIXTURE)) + continue + if _matches_suite_prefix(relative_path, _SMOKE_SUITE_PREFIX): + if "smoke" not in item.keywords: + item.add_marker(pytest.mark.smoke) + if not _has_usefixture(item, _RESET_AMBIENT_SETTINGS_FIXTURE): + item.add_marker(pytest.mark.usefixtures(_RESET_AMBIENT_SETTINGS_FIXTURE)) + continue + if _matches_suite_prefix(relative_path, _UNIT_SUITE_PREFIX) and "unit" not in item.keywords: + item.add_marker(pytest.mark.unit) + @pytest.fixture(scope="session") def repo_root(pytestconfig: pytest.Config) -> Path: diff --git a/tests/test_api.py b/tests/suites/integration/api/test_api.py similarity index 100% rename from tests/test_api.py rename to tests/suites/integration/api/test_api.py diff --git a/tests/test_config_public_contract.py b/tests/suites/integration/api/test_config_public_contract.py similarity index 100% rename from tests/test_config_public_contract.py rename to tests/suites/integration/api/test_config_public_contract.py diff --git a/tests/test_ambient_settings_contract.py b/tests/suites/integration/architecture/test_ambient_settings_contract.py similarity index 100% rename from tests/test_ambient_settings_contract.py rename to tests/suites/integration/architecture/test_ambient_settings_contract.py diff --git a/tests/test_api_import_boundary.py b/tests/suites/integration/architecture/test_api_import_boundary.py similarity index 100% rename from tests/test_api_import_boundary.py rename to tests/suites/integration/architecture/test_api_import_boundary.py diff --git a/tests/test_import_lint_policy.py b/tests/suites/integration/architecture/test_import_lint_policy.py similarity index 91% rename from tests/test_import_lint_policy.py rename to tests/suites/integration/architecture/test_import_lint_policy.py index 1522af42..f7af9b4c 100644 --- a/tests/test_import_lint_policy.py +++ b/tests/suites/integration/architecture/test_import_lint_policy.py @@ -46,7 +46,7 @@ def test_import_lint_policy_limits_tid251_exceptions_to_boundary_files(repo_root "ser/_internal/cli/data.py", "ser/_internal/cli/diagnostics.py", "ser/_internal/cli/runtime.py", - "tests/test_api.py", + "tests/suites/integration/api/test_api.py", } for file_path, ignored_rules in per_file_ignores.items(): if "TID251" in ignored_rules: @@ -60,5 +60,5 @@ def test_import_lint_lane_runs_boundary_contract_tests(repo_root: Path) -> None: script = (repo_root / "scripts" / "run_import_lint.sh").read_text(encoding="utf-8") assert "ruff check --select TID251" in script - assert "tests/test_api_import_boundary.py" in script - assert "tests/test_import_lint_policy.py" in script + assert "tests/suites/integration/architecture/test_api_import_boundary.py" in script + assert "tests/suites/integration/architecture/test_import_lint_policy.py" in script diff --git a/tests/test_pipeline_contracts.py b/tests/suites/integration/architecture/test_pipeline_contracts.py similarity index 100% rename from tests/test_pipeline_contracts.py rename to tests/suites/integration/architecture/test_pipeline_contracts.py diff --git a/tests/test_transcription_compatibility_ownership.py b/tests/suites/integration/architecture/test_transcription_compatibility_ownership.py similarity index 100% rename from tests/test_transcription_compatibility_ownership.py rename to tests/suites/integration/architecture/test_transcription_compatibility_ownership.py diff --git a/tests/test_cli.py b/tests/suites/integration/cli/test_cli.py similarity index 100% rename from tests/test_cli.py rename to tests/suites/integration/cli/test_cli.py diff --git a/tests/test_data_cli.py b/tests/suites/integration/cli/test_data_cli.py similarity index 100% rename from tests/test_data_cli.py rename to tests/suites/integration/cli/test_data_cli.py diff --git a/tests/test_diagnostics_command.py b/tests/suites/integration/cli/test_diagnostics_command.py similarity index 100% rename from tests/test_diagnostics_command.py rename to tests/suites/integration/cli/test_diagnostics_command.py diff --git a/tests/test_data_application.py b/tests/suites/integration/data/test_data_application.py similarity index 100% rename from tests/test_data_application.py rename to tests/suites/integration/data/test_data_application.py diff --git a/tests/test_dataset_prepare.py b/tests/suites/integration/data/test_dataset_prepare.py similarity index 100% rename from tests/test_dataset_prepare.py rename to tests/suites/integration/data/test_dataset_prepare.py diff --git a/tests/test_diagnostics_service.py b/tests/suites/integration/diagnostics/test_diagnostics_service.py similarity index 100% rename from tests/test_diagnostics_service.py rename to tests/suites/integration/diagnostics/test_diagnostics_service.py diff --git a/tests/test_emotion_model_contracts.py b/tests/suites/integration/models/test_emotion_model_contracts.py similarity index 100% rename from tests/test_emotion_model_contracts.py rename to tests/suites/integration/models/test_emotion_model_contracts.py diff --git a/tests/test_training_preparation_and_execution.py b/tests/suites/integration/models/test_training_preparation_and_execution.py similarity index 100% rename from tests/test_training_preparation_and_execution.py rename to tests/suites/integration/models/test_training_preparation_and_execution.py diff --git a/tests/test_accurate_research_inference.py b/tests/suites/integration/runtime/test_accurate_research_inference.py similarity index 100% rename from tests/test_accurate_research_inference.py rename to tests/suites/integration/runtime/test_accurate_research_inference.py diff --git a/tests/test_profile_quality_gate.py b/tests/suites/integration/runtime/test_profile_quality_gate.py similarity index 100% rename from tests/test_profile_quality_gate.py rename to tests/suites/integration/runtime/test_profile_quality_gate.py diff --git a/tests/test_archive_extraction.py b/tests/suites/unit/data/test_archive_extraction.py similarity index 100% rename from tests/test_archive_extraction.py rename to tests/suites/unit/data/test_archive_extraction.py diff --git a/tests/test_data_loader.py b/tests/suites/unit/data/test_data_loader.py similarity index 100% rename from tests/test_data_loader.py rename to tests/suites/unit/data/test_data_loader.py diff --git a/tests/test_dataset_adapters_biic_podcast.py b/tests/suites/unit/data/test_dataset_adapters_biic_podcast.py similarity index 100% rename from tests/test_dataset_adapters_biic_podcast.py rename to tests/suites/unit/data/test_dataset_adapters_biic_podcast.py diff --git a/tests/test_dataset_adapters_crema_d.py b/tests/suites/unit/data/test_dataset_adapters_crema_d.py similarity index 100% rename from tests/test_dataset_adapters_crema_d.py rename to tests/suites/unit/data/test_dataset_adapters_crema_d.py diff --git a/tests/test_dataset_adapters_msp_podcast.py b/tests/suites/unit/data/test_dataset_adapters_msp_podcast.py similarity index 100% rename from tests/test_dataset_adapters_msp_podcast.py rename to tests/suites/unit/data/test_dataset_adapters_msp_podcast.py diff --git a/tests/test_dataset_adapters_public_csv_datasets.py b/tests/suites/unit/data/test_dataset_adapters_public_csv_datasets.py similarity index 100% rename from tests/test_dataset_adapters_public_csv_datasets.py rename to tests/suites/unit/data/test_dataset_adapters_public_csv_datasets.py diff --git a/tests/test_dataset_adapters_ravdess.py b/tests/suites/unit/data/test_dataset_adapters_ravdess.py similarity index 100% rename from tests/test_dataset_adapters_ravdess.py rename to tests/suites/unit/data/test_dataset_adapters_ravdess.py diff --git a/tests/test_dataset_catalog_public_datasets.py b/tests/suites/unit/data/test_dataset_catalog_public_datasets.py similarity index 100% rename from tests/test_dataset_catalog_public_datasets.py rename to tests/suites/unit/data/test_dataset_catalog_public_datasets.py diff --git a/tests/test_dataset_consents.py b/tests/suites/unit/data/test_dataset_consents.py similarity index 100% rename from tests/test_dataset_consents.py rename to tests/suites/unit/data/test_dataset_consents.py diff --git a/tests/test_dataset_controls.py b/tests/suites/unit/data/test_dataset_controls.py similarity index 100% rename from tests/test_dataset_controls.py rename to tests/suites/unit/data/test_dataset_controls.py diff --git a/tests/test_dataset_registry.py b/tests/suites/unit/data/test_dataset_registry.py similarity index 100% rename from tests/test_dataset_registry.py rename to tests/suites/unit/data/test_dataset_registry.py diff --git a/tests/test_dataset_strategies.py b/tests/suites/unit/data/test_dataset_strategies.py similarity index 100% rename from tests/test_dataset_strategies.py rename to tests/suites/unit/data/test_dataset_strategies.py diff --git a/tests/test_embedding_cache.py b/tests/suites/unit/data/test_embedding_cache.py similarity index 100% rename from tests/test_embedding_cache.py rename to tests/suites/unit/data/test_embedding_cache.py diff --git a/tests/test_jl_corpus_downloads.py b/tests/suites/unit/data/test_jl_corpus_downloads.py similarity index 100% rename from tests/test_jl_corpus_downloads.py rename to tests/suites/unit/data/test_jl_corpus_downloads.py diff --git a/tests/test_manifest_jsonl.py b/tests/suites/unit/data/test_manifest_jsonl.py similarity index 100% rename from tests/test_manifest_jsonl.py rename to tests/suites/unit/data/test_manifest_jsonl.py diff --git a/tests/test_mendeley_dataset_preparation.py b/tests/suites/unit/data/test_mendeley_dataset_preparation.py similarity index 100% rename from tests/test_mendeley_dataset_preparation.py rename to tests/suites/unit/data/test_mendeley_dataset_preparation.py diff --git a/tests/test_mendeley_downloads.py b/tests/suites/unit/data/test_mendeley_downloads.py similarity index 100% rename from tests/test_mendeley_downloads.py rename to tests/suites/unit/data/test_mendeley_downloads.py diff --git a/tests/test_msp_podcast_mirror.py b/tests/suites/unit/data/test_msp_podcast_mirror.py similarity index 100% rename from tests/test_msp_podcast_mirror.py rename to tests/suites/unit/data/test_msp_podcast_mirror.py diff --git a/tests/test_openslr_dataset_preparation.py b/tests/suites/unit/data/test_openslr_dataset_preparation.py similarity index 100% rename from tests/test_openslr_dataset_preparation.py rename to tests/suites/unit/data/test_openslr_dataset_preparation.py diff --git a/tests/test_openslr_downloads.py b/tests/suites/unit/data/test_openslr_downloads.py similarity index 100% rename from tests/test_openslr_downloads.py rename to tests/suites/unit/data/test_openslr_downloads.py diff --git a/tests/test_provider_dataset_preparation.py b/tests/suites/unit/data/test_provider_dataset_preparation.py similarity index 100% rename from tests/test_provider_dataset_preparation.py rename to tests/suites/unit/data/test_provider_dataset_preparation.py diff --git a/tests/test_provider_downloads.py b/tests/suites/unit/data/test_provider_downloads.py similarity index 100% rename from tests/test_provider_downloads.py rename to tests/suites/unit/data/test_provider_downloads.py diff --git a/tests/test_public_dataset_downloads.py b/tests/suites/unit/data/test_public_dataset_downloads.py similarity index 100% rename from tests/test_public_dataset_downloads.py rename to tests/suites/unit/data/test_public_dataset_downloads.py diff --git a/tests/test_zenodo_downloads.py b/tests/suites/unit/data/test_zenodo_downloads.py similarity index 100% rename from tests/test_zenodo_downloads.py rename to tests/suites/unit/data/test_zenodo_downloads.py diff --git a/tests/test_transcription_default_benchmark.py b/tests/suites/unit/internal/transcription/test_transcription_default_benchmark.py similarity index 100% rename from tests/test_transcription_default_benchmark.py rename to tests/suites/unit/internal/transcription/test_transcription_default_benchmark.py diff --git a/tests/test_transcription_default_profiling.py b/tests/suites/unit/internal/transcription/test_transcription_default_profiling.py similarity index 100% rename from tests/test_transcription_default_profiling.py rename to tests/suites/unit/internal/transcription/test_transcription_default_profiling.py diff --git a/tests/test_transcription_default_recommendation.py b/tests/suites/unit/internal/transcription/test_transcription_default_recommendation.py similarity index 100% rename from tests/test_transcription_default_recommendation.py rename to tests/suites/unit/internal/transcription/test_transcription_default_recommendation.py diff --git a/tests/test_transcription_profile_candidates.py b/tests/suites/unit/internal/transcription/test_transcription_profile_candidates.py similarity index 100% rename from tests/test_transcription_profile_candidates.py rename to tests/suites/unit/internal/transcription/test_transcription_profile_candidates.py diff --git a/tests/test_transcription_profiling.py b/tests/suites/unit/internal/transcription/test_transcription_profiling.py similarity index 100% rename from tests/test_transcription_profiling.py rename to tests/suites/unit/internal/transcription/test_transcription_profiling.py diff --git a/tests/test_transcription_ravdess_references.py b/tests/suites/unit/internal/transcription/test_transcription_ravdess_references.py similarity index 100% rename from tests/test_transcription_ravdess_references.py rename to tests/suites/unit/internal/transcription/test_transcription_ravdess_references.py diff --git a/tests/test_transcription_runtime_calibration_workflow.py b/tests/suites/unit/internal/transcription/test_transcription_runtime_calibration_workflow.py similarity index 100% rename from tests/test_transcription_runtime_calibration_workflow.py rename to tests/suites/unit/internal/transcription/test_transcription_runtime_calibration_workflow.py diff --git a/tests/test_transcription_text_metrics.py b/tests/suites/unit/internal/transcription/test_transcription_text_metrics.py similarity index 100% rename from tests/test_transcription_text_metrics.py rename to tests/suites/unit/internal/transcription/test_transcription_text_metrics.py diff --git a/tests/test_accurate_feature_dataset.py b/tests/suites/unit/models/test_accurate_feature_dataset.py similarity index 100% rename from tests/test_accurate_feature_dataset.py rename to tests/suites/unit/models/test_accurate_feature_dataset.py diff --git a/tests/test_accurate_training_artifact.py b/tests/suites/unit/models/test_accurate_training_artifact.py similarity index 100% rename from tests/test_accurate_training_artifact.py rename to tests/suites/unit/models/test_accurate_training_artifact.py diff --git a/tests/test_accurate_training_preparation.py b/tests/suites/unit/models/test_accurate_training_preparation.py similarity index 100% rename from tests/test_accurate_training_preparation.py rename to tests/suites/unit/models/test_accurate_training_preparation.py diff --git a/tests/test_artifact_loading.py b/tests/suites/unit/models/test_artifact_loading.py similarity index 100% rename from tests/test_artifact_loading.py rename to tests/suites/unit/models/test_artifact_loading.py diff --git a/tests/test_artifact_persistence.py b/tests/suites/unit/models/test_artifact_persistence.py similarity index 100% rename from tests/test_artifact_persistence.py rename to tests/suites/unit/models/test_artifact_persistence.py diff --git a/tests/test_artifact_upgrade_path.py b/tests/suites/unit/models/test_artifact_upgrade_path.py similarity index 100% rename from tests/test_artifact_upgrade_path.py rename to tests/suites/unit/models/test_artifact_upgrade_path.py diff --git a/tests/test_dataset_training_consents.py b/tests/suites/unit/models/test_dataset_training_consents.py similarity index 100% rename from tests/test_dataset_training_consents.py rename to tests/suites/unit/models/test_dataset_training_consents.py diff --git a/tests/test_emotion_model.py b/tests/suites/unit/models/test_emotion_model.py similarity index 100% rename from tests/test_emotion_model.py rename to tests/suites/unit/models/test_emotion_model.py diff --git a/tests/test_medium_feature_dataset.py b/tests/suites/unit/models/test_medium_feature_dataset.py similarity index 100% rename from tests/test_medium_feature_dataset.py rename to tests/suites/unit/models/test_medium_feature_dataset.py diff --git a/tests/test_medium_noise_controls.py b/tests/suites/unit/models/test_medium_noise_controls.py similarity index 100% rename from tests/test_medium_noise_controls.py rename to tests/suites/unit/models/test_medium_noise_controls.py diff --git a/tests/test_medium_quality_report.py b/tests/suites/unit/models/test_medium_quality_report.py similarity index 100% rename from tests/test_medium_quality_report.py rename to tests/suites/unit/models/test_medium_quality_report.py diff --git a/tests/test_medium_training_noise_controls.py b/tests/suites/unit/models/test_medium_training_noise_controls.py similarity index 100% rename from tests/test_medium_training_noise_controls.py rename to tests/suites/unit/models/test_medium_training_noise_controls.py diff --git a/tests/test_medium_training_preparation.py b/tests/suites/unit/models/test_medium_training_preparation.py similarity index 100% rename from tests/test_medium_training_preparation.py rename to tests/suites/unit/models/test_medium_training_preparation.py diff --git a/tests/test_medium_training_windowing.py b/tests/suites/unit/models/test_medium_training_windowing.py similarity index 100% rename from tests/test_medium_training_windowing.py rename to tests/suites/unit/models/test_medium_training_windowing.py diff --git a/tests/test_provenance_metadata.py b/tests/suites/unit/models/test_provenance_metadata.py similarity index 100% rename from tests/test_provenance_metadata.py rename to tests/suites/unit/models/test_provenance_metadata.py diff --git a/tests/test_torch_head.py b/tests/suites/unit/models/test_torch_head.py similarity index 100% rename from tests/test_torch_head.py rename to tests/suites/unit/models/test_torch_head.py diff --git a/tests/test_training_reporting.py b/tests/suites/unit/models/test_training_reporting.py similarity index 100% rename from tests/test_training_reporting.py rename to tests/suites/unit/models/test_training_reporting.py diff --git a/tests/test_backend_contract.py b/tests/suites/unit/repr/test_backend_contract.py similarity index 100% rename from tests/test_backend_contract.py rename to tests/suites/unit/repr/test_backend_contract.py diff --git a/tests/test_emotion2vec_backend.py b/tests/suites/unit/repr/test_emotion2vec_backend.py similarity index 100% rename from tests/test_emotion2vec_backend.py rename to tests/suites/unit/repr/test_emotion2vec_backend.py diff --git a/tests/test_feature_extractor.py b/tests/suites/unit/repr/test_feature_extractor.py similarity index 100% rename from tests/test_feature_extractor.py rename to tests/suites/unit/repr/test_feature_extractor.py diff --git a/tests/test_feature_runtime_encoding.py b/tests/suites/unit/repr/test_feature_runtime_encoding.py similarity index 100% rename from tests/test_feature_runtime_encoding.py rename to tests/suites/unit/repr/test_feature_runtime_encoding.py diff --git a/tests/test_feature_runtime_policy.py b/tests/suites/unit/repr/test_feature_runtime_policy.py similarity index 100% rename from tests/test_feature_runtime_policy.py rename to tests/suites/unit/repr/test_feature_runtime_policy.py diff --git a/tests/test_handcrafted_backend.py b/tests/suites/unit/repr/test_handcrafted_backend.py similarity index 100% rename from tests/test_handcrafted_backend.py rename to tests/suites/unit/repr/test_handcrafted_backend.py diff --git a/tests/test_hf_whisper_backend.py b/tests/suites/unit/repr/test_hf_whisper_backend.py similarity index 100% rename from tests/test_hf_whisper_backend.py rename to tests/suites/unit/repr/test_hf_whisper_backend.py diff --git a/tests/test_hf_xlsr_backend.py b/tests/suites/unit/repr/test_hf_xlsr_backend.py similarity index 100% rename from tests/test_hf_xlsr_backend.py rename to tests/suites/unit/repr/test_hf_xlsr_backend.py diff --git a/tests/test_pooling.py b/tests/suites/unit/repr/test_pooling.py similarity index 100% rename from tests/test_pooling.py rename to tests/suites/unit/repr/test_pooling.py diff --git a/tests/test_accurate_model_contract.py b/tests/suites/unit/runtime/test_accurate_model_contract.py similarity index 100% rename from tests/test_accurate_model_contract.py rename to tests/suites/unit/runtime/test_accurate_model_contract.py diff --git a/tests/test_accurate_prediction.py b/tests/suites/unit/runtime/test_accurate_prediction.py similarity index 100% rename from tests/test_accurate_prediction.py rename to tests/suites/unit/runtime/test_accurate_prediction.py diff --git a/tests/test_dual_schema_compat.py b/tests/suites/unit/runtime/test_dual_schema_compat.py similarity index 100% rename from tests/test_dual_schema_compat.py rename to tests/suites/unit/runtime/test_dual_schema_compat.py diff --git a/tests/test_medium_prediction.py b/tests/suites/unit/runtime/test_medium_prediction.py similarity index 100% rename from tests/test_medium_prediction.py rename to tests/suites/unit/runtime/test_medium_prediction.py diff --git a/tests/test_medium_retry_policy.py b/tests/suites/unit/runtime/test_medium_retry_policy.py similarity index 100% rename from tests/test_medium_retry_policy.py rename to tests/suites/unit/runtime/test_medium_retry_policy.py diff --git a/tests/test_mps_oom.py b/tests/suites/unit/runtime/test_mps_oom.py similarity index 100% rename from tests/test_mps_oom.py rename to tests/suites/unit/runtime/test_mps_oom.py diff --git a/tests/test_postprocessing.py b/tests/suites/unit/runtime/test_postprocessing.py similarity index 100% rename from tests/test_postprocessing.py rename to tests/suites/unit/runtime/test_postprocessing.py diff --git a/tests/test_retry_primitives.py b/tests/suites/unit/runtime/test_retry_primitives.py similarity index 100% rename from tests/test_retry_primitives.py rename to tests/suites/unit/runtime/test_retry_primitives.py diff --git a/tests/test_schema_versioning.py b/tests/suites/unit/runtime/test_schema_versioning.py similarity index 100% rename from tests/test_schema_versioning.py rename to tests/suites/unit/runtime/test_schema_versioning.py diff --git a/tests/test_timestamp_semantics.py b/tests/suites/unit/runtime/test_timestamp_semantics.py similarity index 100% rename from tests/test_timestamp_semantics.py rename to tests/suites/unit/runtime/test_timestamp_semantics.py diff --git a/tests/test_eval_protocol.py b/tests/suites/unit/train/test_eval_protocol.py similarity index 100% rename from tests/test_eval_protocol.py rename to tests/suites/unit/train/test_eval_protocol.py diff --git a/tests/test_metrics.py b/tests/suites/unit/train/test_metrics.py similarity index 100% rename from tests/test_metrics.py rename to tests/suites/unit/train/test_metrics.py diff --git a/tests/test_stable_whisper_admission_runtime.py b/tests/suites/unit/transcription/test_stable_whisper_admission_runtime.py similarity index 100% rename from tests/test_stable_whisper_admission_runtime.py rename to tests/suites/unit/transcription/test_stable_whisper_admission_runtime.py diff --git a/tests/test_stable_whisper_mps_compat.py b/tests/suites/unit/transcription/test_stable_whisper_mps_compat.py similarity index 100% rename from tests/test_stable_whisper_mps_compat.py rename to tests/suites/unit/transcription/test_stable_whisper_mps_compat.py diff --git a/tests/test_stable_whisper_transcribe_admission.py b/tests/suites/unit/transcription/test_stable_whisper_transcribe_admission.py similarity index 100% rename from tests/test_stable_whisper_transcribe_admission.py rename to tests/suites/unit/transcription/test_stable_whisper_transcribe_admission.py diff --git a/tests/test_stable_whisper_transcribe_execution.py b/tests/suites/unit/transcription/test_stable_whisper_transcribe_execution.py similarity index 100% rename from tests/test_stable_whisper_transcribe_execution.py rename to tests/suites/unit/transcription/test_stable_whisper_transcribe_execution.py diff --git a/tests/test_stable_whisper_transcribe_kwargs.py b/tests/suites/unit/transcription/test_stable_whisper_transcribe_kwargs.py similarity index 100% rename from tests/test_stable_whisper_transcribe_kwargs.py rename to tests/suites/unit/transcription/test_stable_whisper_transcribe_kwargs.py diff --git a/tests/test_stable_whisper_transcribe_runtime.py b/tests/suites/unit/transcription/test_stable_whisper_transcribe_runtime.py similarity index 100% rename from tests/test_stable_whisper_transcribe_runtime.py rename to tests/suites/unit/transcription/test_stable_whisper_transcribe_runtime.py diff --git a/tests/test_transcription_admission_overrides.py b/tests/suites/unit/transcription/test_transcription_admission_overrides.py similarity index 100% rename from tests/test_transcription_admission_overrides.py rename to tests/suites/unit/transcription/test_transcription_admission_overrides.py diff --git a/tests/test_transcription_backends.py b/tests/suites/unit/transcription/test_transcription_backends.py similarity index 100% rename from tests/test_transcription_backends.py rename to tests/suites/unit/transcription/test_transcription_backends.py diff --git a/tests/test_transcription_factory.py b/tests/suites/unit/transcription/test_transcription_factory.py similarity index 100% rename from tests/test_transcription_factory.py rename to tests/suites/unit/transcription/test_transcription_factory.py diff --git a/tests/test_transcription_mps_admission.py b/tests/suites/unit/transcription/test_transcription_mps_admission.py similarity index 100% rename from tests/test_transcription_mps_admission.py rename to tests/suites/unit/transcription/test_transcription_mps_admission.py diff --git a/tests/test_transcription_runtime_failures.py b/tests/suites/unit/transcription/test_transcription_runtime_failures.py similarity index 100% rename from tests/test_transcription_runtime_failures.py rename to tests/suites/unit/transcription/test_transcription_runtime_failures.py diff --git a/tests/test_transcription_runtime_policy.py b/tests/suites/unit/transcription/test_transcription_runtime_policy.py similarity index 100% rename from tests/test_transcription_runtime_policy.py rename to tests/suites/unit/transcription/test_transcription_runtime_policy.py diff --git a/tests/test_audio_utils.py b/tests/suites/unit/utils/test_audio_utils.py similarity index 100% rename from tests/test_audio_utils.py rename to tests/suites/unit/utils/test_audio_utils.py diff --git a/tests/test_logger.py b/tests/suites/unit/utils/test_logger.py similarity index 100% rename from tests/test_logger.py rename to tests/suites/unit/utils/test_logger.py diff --git a/tests/test_segment_canonicalization.py b/tests/suites/unit/utils/test_segment_canonicalization.py similarity index 100% rename from tests/test_segment_canonicalization.py rename to tests/suites/unit/utils/test_segment_canonicalization.py diff --git a/tests/test_subtitles.py b/tests/suites/unit/utils/test_subtitles.py similarity index 100% rename from tests/test_subtitles.py rename to tests/suites/unit/utils/test_subtitles.py diff --git a/tests/test_timeline_utils.py b/tests/suites/unit/utils/test_timeline_utils.py similarity index 100% rename from tests/test_timeline_utils.py rename to tests/suites/unit/utils/test_timeline_utils.py diff --git a/tests/test_torch_inference.py b/tests/suites/unit/utils/test_torch_inference.py similarity index 100% rename from tests/test_torch_inference.py rename to tests/suites/unit/utils/test_torch_inference.py diff --git a/tests/test_transcription_compat.py b/tests/suites/unit/utils/test_transcription_compat.py similarity index 100% rename from tests/test_transcription_compat.py rename to tests/suites/unit/utils/test_transcription_compat.py