Spaces:
Sleeping
Sleeping
| """Test suite for AI Agency Pro application. | |
| Following vendor-driven testing patterns with HuggingFace libraries. | |
| Official documentation: https://huggingface.co/docs/huggingface_hub/guides/inference | |
| """ | |
| import pytest | |
| from unittest.mock import Mock, patch | |
| import sys | |
| import os | |
| # Add parent directory to path for imports | |
| sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | |
| class TestModelConfiguration: | |
| """Test model configuration follows vendor best practices.""" | |
| def test_models_dict_exists(self): | |
| """Verify MODELS dictionary is defined.""" | |
| from app import MODELS | |
| assert isinstance(MODELS, dict) | |
| assert len(MODELS) > 0 | |
| def test_models_use_official_ids(self): | |
| """Verify all models use official HuggingFace model IDs.""" | |
| from app import MODELS | |
| # Expected official model ID patterns | |
| expected_patterns = [ | |
| "facebook/", | |
| "deepset/", | |
| "mistralai/", | |
| "google/", | |
| "openai/", | |
| "microsoft/" | |
| ] | |
| for task, model_id in MODELS.items(): | |
| # Model ID should contain organization prefix | |
| assert "/" in model_id, f"Model {model_id} should have org/name format" | |
| def test_required_models_present(self): | |
| """Verify required models are configured.""" | |
| from app import MODELS | |
| required_tasks = ["summarization", "text-classification", "question-answering", "text-generation"] | |
| for task in required_tasks: | |
| assert task in MODELS, f"Missing required task: {task}" | |
| class TestSummarization: | |
| """Test summarization functionality.""" | |
| def test_summarize_text_function_exists(self): | |
| """Verify summarize_text function is defined.""" | |
| from app import summarize_text | |
| assert callable(summarize_text) | |
| def test_summarize_text_signature(self): | |
| """Verify function signature matches expected parameters.""" | |
| from app import summarize_text | |
| import inspect | |
| sig = inspect.signature(summarize_text) | |
| params = list(sig.parameters.keys()) | |
| assert "text" in params | |
| assert "max_length" in params or len(params) >= 1 | |
| def test_summarize_empty_text(self): | |
| """Test error handling for empty input.""" | |
| from app import summarize_text | |
| result = summarize_text("") | |
| # Should return error message, not raise exception | |
| assert isinstance(result, str) | |
| assert "error" in result.lower() or len(result) == 0 or result != "" | |
| def test_summarize_short_text(self): | |
| """Test handling of very short text.""" | |
| from app import summarize_text | |
| result = summarize_text("Hi") | |
| assert isinstance(result, str) | |
| class TestClassification: | |
| """Test classification functionality.""" | |
| def test_classify_text_function_exists(self): | |
| """Verify classify_text function is defined.""" | |
| from app import classify_text | |
| assert callable(classify_text) | |
| def test_classify_text_signature(self): | |
| """Verify function signature.""" | |
| from app import classify_text | |
| import inspect | |
| sig = inspect.signature(classify_text) | |
| params = list(sig.parameters.keys()) | |
| assert "text" in params | |
| assert "labels" in params | |
| def test_classify_empty_labels(self): | |
| """Test error handling for empty labels.""" | |
| from app import classify_text | |
| result = classify_text("Test text", "") | |
| assert isinstance(result, (str, dict)) | |
| class TestQuestionAnswering: | |
| """Test Q&A functionality.""" | |
| def test_answer_question_function_exists(self): | |
| """Verify answer_question function is defined.""" | |
| from app import answer_question | |
| assert callable(answer_question) | |
| def test_answer_question_signature(self): | |
| """Verify function signature.""" | |
| from app import answer_question | |
| import inspect | |
| sig = inspect.signature(answer_question) | |
| params = list(sig.parameters.keys()) | |
| assert "question" in params | |
| assert "context" in params | |
| def test_answer_empty_context(self): | |
| """Test error handling for empty context.""" | |
| from app import answer_question | |
| result = answer_question("What?", "") | |
| assert isinstance(result, str) | |
| class TestChatAgent: | |
| """Test chat agent functionality.""" | |
| def test_chat_function_exists(self): | |
| """Verify chat function is defined.""" | |
| from app import chat | |
| assert callable(chat) | |
| class TestInferenceClient: | |
| """Test InferenceClient usage patterns.""" | |
| def test_client_initialization(self): | |
| """Verify client uses official HuggingFace pattern.""" | |
| from app import client | |
| from huggingface_hub import InferenceClient | |
| assert isinstance(client, InferenceClient) | |
| def test_client_is_global(self): | |
| """Verify client is initialized at module level (best practice).""" | |
| import app | |
| assert hasattr(app, "client") | |
| class TestGradioInterface: | |
| """Test Gradio interface configuration.""" | |
| def test_demo_exists(self): | |
| """Verify Gradio demo is defined.""" | |
| from app import demo | |
| import gradio as gr | |
| assert isinstance(demo, gr.Blocks) | |
| class TestErrorHandling: | |
| """Test error handling patterns.""" | |
| def test_functions_dont_raise_on_error(self): | |
| """Verify functions return errors instead of raising.""" | |
| from app import summarize_text, classify_text, answer_question | |
| # These should not raise exceptions | |
| try: | |
| summarize_text(None) # Invalid input | |
| except TypeError: | |
| pass # Expected for None input | |
| except Exception as e: | |
| pytest.fail(f"Unexpected exception: {e}") | |
| def test_logging_configured(self): | |
| """Verify logging is configured.""" | |
| import logging | |
| from app import logger | |
| assert isinstance(logger, logging.Logger) | |
| class TestVendorDrivenPatterns: | |
| """Test adherence to vendor-driven development principles.""" | |
| def test_no_custom_http_requests(self): | |
| """Verify no custom HTTP requests to inference API.""" | |
| import app | |
| import inspect | |
| source = inspect.getsource(app) | |
| # Should not contain direct requests to inference API | |
| assert "requests.post" not in source or "inference" not in source.lower() | |
| def test_uses_spaces_gpu_decorator(self): | |
| """Verify GPU functions use @spaces.GPU decorator.""" | |
| import app | |
| import inspect | |
| source = inspect.getsource(app) | |
| # Should use spaces.GPU decorator | |
| assert "@spaces.GPU" in source or "spaces.GPU" in source | |
| def test_uses_gradio_blocks(self): | |
| """Verify UI uses Gradio Blocks pattern.""" | |
| import app | |
| import inspect | |
| source = inspect.getsource(app) | |
| # Should use gr.Blocks | |
| assert "gr.Blocks" in source | |
| # Integration tests (require API access) | |
| class TestIntegration: | |
| """Integration tests - require HuggingFace API access.""" | |
| def test_summarization_api(self): | |
| """Test actual API call for summarization.""" | |
| from app import summarize_text | |
| text = """ | |
| Machine learning is a subset of artificial intelligence that enables | |
| systems to learn and improve from experience without being explicitly | |
| programmed. It focuses on developing algorithms that can access data | |
| and use it to learn for themselves. | |
| """ | |
| result = summarize_text(text) | |
| assert isinstance(result, str) | |
| assert len(result) > 0 | |
| assert len(result) < len(text) # Should be shorter | |
| def test_classification_api(self): | |
| """Test actual API call for classification.""" | |
| from app import classify_text | |
| text = "I love programming in Python!" | |
| labels = "positive, negative, neutral" | |
| result = classify_text(text, labels) | |
| assert isinstance(result, dict) | |
| assert len(result) > 0 | |
| if __name__ == "__main__": | |
| pytest.main([__file__, "-v"]) |