| """ |
| Integration tests for RAG Pipeline application. |
| Tests actual components without mocking for real confidence. |
| """ |
|
|
| import pytest |
| import asyncio |
| import time |
| from fastapi.testclient import TestClient |
| from app.main import app, rag_qa |
| from app.pipeline import RAGPipeline |
|
|
| |
| client = TestClient(app) |
|
|
|
|
| class TestRealIntegration: |
| """Integration tests using actual components""" |
| |
| def test_real_rag_pipeline_creation(self): |
| """Test creating real RAG pipeline with actual dataset""" |
| |
| pipeline = RAGPipeline.from_preset('developer-portfolio') |
| |
| |
| assert pipeline is not None |
| assert hasattr(pipeline, 'config') |
| assert hasattr(pipeline, 'documents') |
| assert len(pipeline.documents) > 0 |
| |
| |
| first_doc = pipeline.documents[0] |
| assert hasattr(first_doc, 'content') |
| assert hasattr(first_doc, 'meta') |
| assert 'question' in first_doc.meta |
| assert 'answer' in first_doc.meta |
| |
| def test_real_rag_question_answering(self): |
| """Test actual RAG question answering""" |
| pipeline = RAGPipeline.from_preset('developer-portfolio') |
| |
| |
| question = "What is your current role?" |
| result = pipeline.answer_question(question) |
| |
| |
| assert result is not None |
| assert len(result) > 100 |
| assert 'role' in result.lower() or 'tech lead' in result.lower() |
| |
| def test_rag_qa_function_with_real_pipeline(self): |
| """Test rag_qa function with actual loaded pipeline""" |
| |
| from app.main import pipelines |
| original_pipelines = pipelines.copy() |
| |
| try: |
| |
| test_pipeline = RAGPipeline.from_preset('developer-portfolio') |
| pipelines['developer-portfolio'] = test_pipeline |
| |
| |
| result = rag_qa("What is your experience?", "developer-portfolio") |
| |
| |
| assert result is not None |
| assert len(result) > 50 |
| assert "still loading" not in result.lower() |
| |
| finally: |
| |
| pipelines.clear() |
| pipelines.update(original_pipelines) |
| |
| def test_chat_endpoint_with_real_components(self): |
| """Test chat endpoint with actual OpenRouter client""" |
| |
| |
| request_data = { |
| "messages": [ |
| {"role": "user", "content": "Hello! Can you help me?"} |
| ] |
| } |
| |
| response = client.post("/chat", json=request_data) |
| |
| |
| assert response.status_code in [200, 500] |
| |
| if response.status_code == 200: |
| data = response.json() |
| assert "response" in data |
| assert "tool_calls" in data |
| |
| assert isinstance(data["tool_calls"], (type(None), list)) |
| |
| def test_dataset_loading_performance(self): |
| """Test that dataset loading completes in reasonable time""" |
| start_time = time.time() |
| |
| |
| pipeline = RAGPipeline.from_preset('developer-portfolio') |
| |
| load_time = time.time() - start_time |
| |
| |
| assert load_time < 30.0 |
| assert len(pipeline.documents) > 0 |
| |
| |
| assert hasattr(pipeline, 'document_store') |
| assert hasattr(pipeline, 'retriever') |
| |
| def test_pipeline_document_structure(self): |
| """Test that loaded documents have expected structure""" |
| pipeline = RAGPipeline.from_preset('developer-portfolio') |
| |
| |
| for doc in pipeline.documents[:5]: |
| assert hasattr(doc, 'content') |
| assert hasattr(doc, 'meta') |
| assert doc.content is not None |
| assert len(doc.content) > 0 |
| |
| |
| meta = doc.meta |
| assert isinstance(meta, dict) |
| |
| if 'question' in meta: |
| assert isinstance(meta['question'], str) |
| if 'answer' in meta: |
| assert isinstance(meta['answer'], str) |
| |
| def test_multiple_different_questions(self): |
| """Test pipeline with multiple different questions""" |
| pipeline = RAGPipeline.from_preset('developer-portfolio') |
| |
| questions = [ |
| "What is your current role?", |
| "What technologies do you use?", |
| "Tell me about your experience" |
| ] |
| |
| results = [] |
| for question in questions: |
| result = pipeline.answer_question(question) |
| results.append(result) |
| |
| |
| assert len(results) == len(questions) |
| |
| |
| for i in range(len(results)): |
| for j in range(i + 1, len(results)): |
| |
| similarity = len(set(results[i].split()) & set(results[j].split())) |
| assert similarity < len(results[i].split()) * 0.8 |
| |
| def test_error_handling_with_real_pipeline(self): |
| """Test error handling with real pipeline""" |
| pipeline = RAGPipeline.from_preset('developer-portfolio') |
| |
| |
| result = pipeline.answer_question("") |
| |
| |
| assert result is not None |
| assert len(result) > 0 |
| |
| def test_config_access(self): |
| """Test that pipeline configuration is accessible""" |
| pipeline = RAGPipeline.from_preset('developer-portfolio') |
| |
| |
| assert hasattr(pipeline, 'config') |
| config = pipeline.config |
| assert hasattr(config, 'name') |
| assert hasattr(config, 'content_field') |
| assert hasattr(config, 'prompt_template') |
| |
| |
| assert config.name == 'syntaxhacker/developer-portfolio-rag' |
| assert config.content_field == 'answer' |
| assert config.prompt_template is not None |
|
|
|
|
| class TestSystemIntegration: |
| """Test system-level integration""" |
| |
| def test_fastapi_app_startup(self): |
| """Test that FastAPI app starts correctly""" |
| |
| from app.main import app |
| |
| assert app is not None |
| assert hasattr(app, 'routes') |
| |
| |
| route_paths = [route.path for route in app.routes] |
| assert '/chat' in route_paths |
| assert '/answer' in route_paths |
| assert '/health' in route_paths |
| assert '/datasets' in route_paths |
| |
| def test_openrouter_client_configuration(self): |
| """Test OpenRouter client is properly configured""" |
| from app.main import openrouter_client, MODEL_NAME |
| |
| assert openrouter_client is not None |
| assert hasattr(openrouter_client, 'base_url') |
| assert hasattr(openrouter_client, 'api_key') |
| |
| |
| assert MODEL_NAME == "z-ai/glm-4.5-air:free" |
| assert str(openrouter_client.base_url) == "https://openrouter.ai/api/v1/" |
| |
| def test_tools_configuration_structure(self): |
| """Test that tools are properly configured for real use""" |
| from app.main import TOOLS |
| |
| assert isinstance(TOOLS, list) |
| assert len(TOOLS) > 0 |
| |
| |
| rag_tool = None |
| for tool in TOOLS: |
| if tool['function']['name'] == 'rag_qa': |
| rag_tool = tool |
| break |
| |
| assert rag_tool is not None |
| assert 'parameters' in rag_tool['function'] |
| assert 'properties' in rag_tool['function']['parameters'] |
| assert 'question' in rag_tool['function']['parameters']['properties'] |
|
|
|
|
| if __name__ == "__main__": |
| pytest.main([__file__, "-v", "-s"]) |