LLM-and-RAG-Application-GenAI / tests /test_search_engine.py
Redlion007's picture
Add src modules, tests, CI workflow, and Codecov config
ae2d710
Raw
History Blame Contribute Delete
2.95 kB
import numpy as np
import pytest
import src.search_engine as search_engine_module
from unittest.mock import MagicMock
from src.search_engine import HybridSearchEngine
SAMPLE_DOCS = [
{"content": "transformer models use attention mechanisms", "id": "1"},
{"content": "retrieval augmented generation improves accuracy", "id": "2"},
{"content": "bm25 is a sparse ranking algorithm for search", "id": "3"},
]
def make_mock_engine(docs=None):
if docs is None:
docs = SAMPLE_DOCS
mock_model = MagicMock()
mock_model.encode.side_effect = lambda texts, normalize_embeddings=False: (
np.random.rand(len(texts), 384)
if isinstance(texts, list)
else np.random.rand(1, 384)
)
mock_bm25 = MagicMock()
mock_bm25.get_scores.return_value = np.array([0.5, 0.8, 0.3])
return HybridSearchEngine(docs, model=mock_model, bm25=mock_bm25)
def test_search_returns_correct_number_of_results():
engine = make_mock_engine()
results = engine.search("transformer attention", top_k=2)
assert len(results) == 2
def test_search_results_have_rrf_score():
engine = make_mock_engine()
results = engine.search("bm25 ranking", top_k=3)
for r in results:
assert "rrf_score" in r
def test_search_top_k_one():
engine = make_mock_engine()
results = engine.search("any query", top_k=1)
assert len(results) == 1
def test_search_results_contain_content_and_id():
engine = make_mock_engine()
results = engine.search("retrieval generation")
for r in results:
assert "content" in r
assert "id" in r
def test_rrf_scores_are_positive():
engine = make_mock_engine()
results = engine.search("test query", top_k=3)
for r in results:
assert r["rrf_score"] > 0
def test_search_with_single_document():
docs = [{"content": "only one document here", "id": "solo"}]
engine = make_mock_engine(docs=docs)
engine.bm25.get_scores.return_value = np.array([1.0])
results = engine.search("document", top_k=1)
assert len(results) == 1
def test_init_with_real_model_classes():
"""Covers the else-branch of __init__ by patching module-level classes."""
docs = [{"content": "hello world", "id": "1"}]
mock_model = MagicMock()
mock_model.encode.return_value = np.random.rand(1, 384)
mock_bm25_instance = MagicMock()
mock_bm25_class = MagicMock(return_value=mock_bm25_instance)
original_st = search_engine_module._SentenceTransformer
original_bm25 = search_engine_module._BM25Okapi
search_engine_module._SentenceTransformer = MagicMock(return_value=mock_model)
search_engine_module._BM25Okapi = mock_bm25_class
try:
engine = HybridSearchEngine(docs)
assert engine.model is not None
assert engine.bm25 is not None
finally:
search_engine_module._SentenceTransformer = original_st
search_engine_module._BM25Okapi = original_bm25