test(semantic): add semantic similarity tests

This commit is contained in:
2026-02-03 17:31:07 +00:00
parent 8b3536873e
commit 571b770281
3 changed files with 315 additions and 0 deletions

View File

@@ -207,3 +207,77 @@ class TestLexicalValidator:
validator = lexical(min_jaccard=0.5, min_overlap=0.6)
assert isinstance(validator, LexicalValidator)
assert validator.name == "lexical"
# SemanticValidator tests - conditionally run if sentence-transformers is installed
class TestSemanticValidator:
"""Tests for SemanticValidator."""
@staticmethod
def _skip_if_no_transformers() -> None:
"""Skip test if sentence-transformers is not installed."""
pytest.importorskip("sentence_transformers")
def test_semantic_validator_passes_when_score_meets_threshold(self) -> None:
"""Test that validator passes when semantic similarity meets threshold."""
self._skip_if_no_transformers()
from veritext.validators.metric import SemanticValidator
validator = SemanticValidator(min_score=0.5)
context = ValidationContext(reference="the cat sat on the mat")
result = validator.check("the cat sat on the mat", context)
assert result.passed is True
assert result.name == "semantic"
assert result.actual >= 0.99 # Identical text
assert result.threshold == 0.5
def test_semantic_validator_fails_when_score_below_threshold(self) -> None:
"""Test that validator fails when semantic similarity is below threshold."""
self._skip_if_no_transformers()
from veritext.validators.metric import SemanticValidator
validator = SemanticValidator(min_score=0.99)
context = ValidationContext(reference="the cat sat on the mat")
result = validator.check(
"quantum physics describes particle behaviour", context
)
assert result.passed is False
assert result.name == "semantic"
assert result.actual < 0.99
assert "below minimum" in result.message
def test_semantic_validator_raises_on_missing_reference(self) -> None:
"""Test that validator raises when reference is missing."""
self._skip_if_no_transformers()
from veritext.validators.metric import SemanticValidator
validator = SemanticValidator(min_score=0.5)
context = ValidationContext()
with pytest.raises(ValidationError, match="requires reference text"):
validator.check("some text", context)
def test_semantic_validator_raises_on_invalid_min_score(self) -> None:
"""Test that invalid min_score raises error without loading model."""
# This test doesn't need sentence-transformers since validation happens first
with pytest.raises(InvalidThresholdError, match=r"between 0\.0 and 1\.0"):
from veritext.validators.metric import SemanticValidator
SemanticValidator(min_score=1.5)
with pytest.raises(InvalidThresholdError, match=r"between 0\.0 and 1\.0"):
from veritext.validators.metric import SemanticValidator
SemanticValidator(min_score=-0.1)
def test_semantic_factory_function(self) -> None:
"""Test the semantic() factory function."""
self._skip_if_no_transformers()
from veritext.validators import semantic
from veritext.validators.metric import SemanticValidator
validator = semantic(min_score=0.6)
assert isinstance(validator, SemanticValidator)
assert validator.name == "semantic"