turing-space / turing /tests /unit /test_config.py
papri-ka's picture
Deploy FastAPI ML service to Hugging Face Spaces
5fc6e5d
import importlib
from pathlib import Path
from unittest.mock import patch
import pytest
# Import the module to be tested
import turing.config as config
@pytest.mark.config
class TestConfig:
"""
Test suite for validating the project's configuration module (config.py).
These tests verify that paths are structured correctly, critical constants
are of the expected type and value, and module-level logic
(like calculations and .env loading) executes as intended.
"""
def test_proj_root_is_correctly_identified(self):
"""
Validates that PROJ_ROOT is a Path object and points to the
actual project root directory (which should contain 'pyproject.toml').
"""
assert isinstance(config.PROJ_ROOT, Path)
assert config.PROJ_ROOT.is_dir()
# A common "sanity check" is to look for a known file at the root
expected_file = config.PROJ_ROOT / "pyproject.toml"
assert expected_file.is_file(), (
f"PROJ_ROOT ({config.PROJ_ROOT}) does not seem to be the project root. "
f"Could not find {expected_file}"
)
def test_directory_paths_are_correctly_structured(self):
"""
Ensures all key directory variables are Path objects
and are correctly parented under PROJ_ROOT.
"""
# List of all directory variables defined in config.py
path_vars = [
config.DATA_DIR,
config.RAW_DATA_DIR,
config.INTERIM_DATA_DIR,
config.PROCESSED_DATA_DIR,
config.EXTERNAL_DATA_DIR,
config.MODELS_DIR,
config.REPORTS_DIR,
config.FIGURES_DIR,
]
for path_var in path_vars:
assert isinstance(path_var, Path)
# Check that PROJ_ROOT is an ancestor of this path
assert config.PROJ_ROOT in path_var.parents
# Spot-check a few for correct relative paths
assert config.DATA_DIR == config.PROJ_ROOT / "data"
assert config.RAW_DATA_DIR == config.PROJ_ROOT / "data" / "raw"
assert config.FIGURES_DIR == config.PROJ_ROOT / "reports" / "figures"
def test_dataset_constants_are_valid(self):
"""
Validates that critical dataset constants are non-empty and of
the correct type.
"""
assert isinstance(config.DATASET_HF_ID, str)
assert config.DATASET_HF_ID == "NLBSE/nlbse26-code-comment-classification"
assert isinstance(config.LANGS, list)
assert len(config.LANGS) == 3
assert "java" in config.LANGS
assert isinstance(config.INPUT_COLUMN, str) and config.INPUT_COLUMN
assert isinstance(config.LABEL_COLUMN, str) and config.LABEL_COLUMN
def test_labels_map_and_total_categories_are_correct(self):
"""
Validates the LABELS_MAP structure and ensures TOTAL_CATEGORIES
is correctly calculated from it.
"""
assert isinstance(config.LABELS_MAP, dict)
# Ensure all languages in LANGS are keys in LABELS_MAP
for lang in config.LANGS:
assert lang in config.LABELS_MAP
assert isinstance(config.LABELS_MAP[lang], list)
assert len(config.LABELS_MAP[lang]) > 0
# Validate the derived calculation
expected_total = (
len(config.LABELS_MAP["java"])
+ len(config.LABELS_MAP["python"])
+ len(config.LABELS_MAP["pharo"])
)
assert config.TOTAL_CATEGORIES == expected_total
assert config.TOTAL_CATEGORIES == 18 # 7 + 5 + 6
def test_numeric_parameters_are_positive(self):
"""
Ensures that numeric scoring and training parameters are positive
and of the correct type.
"""
numeric_params = {
"MAX_AVG_RUNTIME": config.MAX_AVG_RUNTIME,
"MAX_AVG_FLOPS": config.MAX_AVG_FLOPS,
"DEFAULT_BATCH_SIZE": config.DEFAULT_BATCH_SIZE,
"DEFAULT_NUM_ITERATIONS": config.DEFAULT_NUM_ITERATIONS,
}
for name, value in numeric_params.items():
assert isinstance(value, (int, float)), f"{name} is not numeric"
assert value > 0, f"{name} must be positive"
@patch("dotenv.load_dotenv")
def test_load_dotenv_is_called_on_module_load(self, mock_load_dotenv):
"""
Tests that the load_dotenv() function is executed when the
config.py module is loaded.
This requires reloading the module, as it's likely already been
imported by pytest or conftest.
"""
# Arrange (Patch is active)
# Act
# Reload the config module to trigger its top-level statements
importlib.reload(config)
# Assert
# Check that the patched load_dotenv was called
mock_load_dotenv.assert_called_once()