dlynch90 commited on
Commit
7851a1c
·
verified ·
1 Parent(s): e07b1d4

Create tests/test_app.py

Browse files
Files changed (1) hide show
  1. tests/test_app.py +271 -0
tests/test_app.py ADDED
@@ -0,0 +1,271 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Test suite for AI Agency Pro application.
2
+
3
+ Following vendor-driven testing patterns with HuggingFace libraries.
4
+ Official documentation: https://huggingface.co/docs/huggingface_hub/guides/inference
5
+ """
6
+
7
+ import pytest
8
+ from unittest.mock import Mock, patch
9
+ import sys
10
+ import os
11
+
12
+ # Add parent directory to path for imports
13
+ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
14
+
15
+
16
+ class TestModelConfiguration:
17
+ """Test model configuration follows vendor best practices."""
18
+
19
+ def test_models_dict_exists(self):
20
+ """Verify MODELS dictionary is defined."""
21
+ from app import MODELS
22
+ assert isinstance(MODELS, dict)
23
+ assert len(MODELS) > 0
24
+
25
+ def test_models_use_official_ids(self):
26
+ """Verify all models use official HuggingFace model IDs."""
27
+ from app import MODELS
28
+
29
+ # Expected official model ID patterns
30
+ expected_patterns = [
31
+ "facebook/",
32
+ "deepset/",
33
+ "mistralai/",
34
+ "google/",
35
+ "openai/",
36
+ "microsoft/"
37
+ ]
38
+
39
+ for task, model_id in MODELS.items():
40
+ # Model ID should contain organization prefix
41
+ assert "/" in model_id, f"Model {model_id} should have org/name format"
42
+
43
+ def test_required_models_present(self):
44
+ """Verify required models are configured."""
45
+ from app import MODELS
46
+
47
+ required_tasks = ["summarization", "text-classification", "question-answering", "text-generation"]
48
+ for task in required_tasks:
49
+ assert task in MODELS, f"Missing required task: {task}"
50
+
51
+
52
+ class TestSummarization:
53
+ """Test summarization functionality."""
54
+
55
+ def test_summarize_text_function_exists(self):
56
+ """Verify summarize_text function is defined."""
57
+ from app import summarize_text
58
+ assert callable(summarize_text)
59
+
60
+ def test_summarize_text_signature(self):
61
+ """Verify function signature matches expected parameters."""
62
+ from app import summarize_text
63
+ import inspect
64
+
65
+ sig = inspect.signature(summarize_text)
66
+ params = list(sig.parameters.keys())
67
+
68
+ assert "text" in params
69
+ assert "max_length" in params or len(params) >= 1
70
+
71
+ def test_summarize_empty_text(self):
72
+ """Test error handling for empty input."""
73
+ from app import summarize_text
74
+
75
+ result = summarize_text("")
76
+ # Should return error message, not raise exception
77
+ assert isinstance(result, str)
78
+ assert "error" in result.lower() or len(result) == 0 or result != ""
79
+
80
+ def test_summarize_short_text(self):
81
+ """Test handling of very short text."""
82
+ from app import summarize_text
83
+
84
+ result = summarize_text("Hi")
85
+ assert isinstance(result, str)
86
+
87
+
88
+ class TestClassification:
89
+ """Test classification functionality."""
90
+
91
+ def test_classify_text_function_exists(self):
92
+ """Verify classify_text function is defined."""
93
+ from app import classify_text
94
+ assert callable(classify_text)
95
+
96
+ def test_classify_text_signature(self):
97
+ """Verify function signature."""
98
+ from app import classify_text
99
+ import inspect
100
+
101
+ sig = inspect.signature(classify_text)
102
+ params = list(sig.parameters.keys())
103
+
104
+ assert "text" in params
105
+ assert "labels" in params
106
+
107
+ def test_classify_empty_labels(self):
108
+ """Test error handling for empty labels."""
109
+ from app import classify_text
110
+
111
+ result = classify_text("Test text", "")
112
+ assert isinstance(result, (str, dict))
113
+
114
+
115
+ class TestQuestionAnswering:
116
+ """Test Q&A functionality."""
117
+
118
+ def test_answer_question_function_exists(self):
119
+ """Verify answer_question function is defined."""
120
+ from app import answer_question
121
+ assert callable(answer_question)
122
+
123
+ def test_answer_question_signature(self):
124
+ """Verify function signature."""
125
+ from app import answer_question
126
+ import inspect
127
+
128
+ sig = inspect.signature(answer_question)
129
+ params = list(sig.parameters.keys())
130
+
131
+ assert "question" in params
132
+ assert "context" in params
133
+
134
+ def test_answer_empty_context(self):
135
+ """Test error handling for empty context."""
136
+ from app import answer_question
137
+
138
+ result = answer_question("What?", "")
139
+ assert isinstance(result, str)
140
+
141
+
142
+ class TestChatAgent:
143
+ """Test chat agent functionality."""
144
+
145
+ def test_chat_function_exists(self):
146
+ """Verify chat function is defined."""
147
+ from app import chat
148
+ assert callable(chat)
149
+
150
+
151
+ class TestInferenceClient:
152
+ """Test InferenceClient usage patterns."""
153
+
154
+ def test_client_initialization(self):
155
+ """Verify client uses official HuggingFace pattern."""
156
+ from app import client
157
+ from huggingface_hub import InferenceClient
158
+
159
+ assert isinstance(client, InferenceClient)
160
+
161
+ def test_client_is_global(self):
162
+ """Verify client is initialized at module level (best practice)."""
163
+ import app
164
+
165
+ assert hasattr(app, "client")
166
+
167
+
168
+ class TestGradioInterface:
169
+ """Test Gradio interface configuration."""
170
+
171
+ def test_demo_exists(self):
172
+ """Verify Gradio demo is defined."""
173
+ from app import demo
174
+ import gradio as gr
175
+
176
+ assert isinstance(demo, gr.Blocks)
177
+
178
+
179
+ class TestErrorHandling:
180
+ """Test error handling patterns."""
181
+
182
+ def test_functions_dont_raise_on_error(self):
183
+ """Verify functions return errors instead of raising."""
184
+ from app import summarize_text, classify_text, answer_question
185
+
186
+ # These should not raise exceptions
187
+ try:
188
+ summarize_text(None) # Invalid input
189
+ except TypeError:
190
+ pass # Expected for None input
191
+ except Exception as e:
192
+ pytest.fail(f"Unexpected exception: {e}")
193
+
194
+ def test_logging_configured(self):
195
+ """Verify logging is configured."""
196
+ import logging
197
+ from app import logger
198
+
199
+ assert isinstance(logger, logging.Logger)
200
+
201
+
202
+ class TestVendorDrivenPatterns:
203
+ """Test adherence to vendor-driven development principles."""
204
+
205
+ def test_no_custom_http_requests(self):
206
+ """Verify no custom HTTP requests to inference API."""
207
+ import app
208
+ import inspect
209
+
210
+ source = inspect.getsource(app)
211
+
212
+ # Should not contain direct requests to inference API
213
+ assert "requests.post" not in source or "inference" not in source.lower()
214
+
215
+ def test_uses_spaces_gpu_decorator(self):
216
+ """Verify GPU functions use @spaces.GPU decorator."""
217
+ import app
218
+ import inspect
219
+
220
+ source = inspect.getsource(app)
221
+
222
+ # Should use spaces.GPU decorator
223
+ assert "@spaces.GPU" in source or "spaces.GPU" in source
224
+
225
+ def test_uses_gradio_blocks(self):
226
+ """Verify UI uses Gradio Blocks pattern."""
227
+ import app
228
+ import inspect
229
+
230
+ source = inspect.getsource(app)
231
+
232
+ # Should use gr.Blocks
233
+ assert "gr.Blocks" in source
234
+
235
+
236
+ # Integration tests (require API access)
237
+ class TestIntegration:
238
+ """Integration tests - require HuggingFace API access."""
239
+
240
+ @pytest.mark.integration
241
+ def test_summarization_api(self):
242
+ """Test actual API call for summarization."""
243
+ from app import summarize_text
244
+
245
+ text = """
246
+ Machine learning is a subset of artificial intelligence that enables
247
+ systems to learn and improve from experience without being explicitly
248
+ programmed. It focuses on developing algorithms that can access data
249
+ and use it to learn for themselves.
250
+ """
251
+
252
+ result = summarize_text(text)
253
+ assert isinstance(result, str)
254
+ assert len(result) > 0
255
+ assert len(result) < len(text) # Should be shorter
256
+
257
+ @pytest.mark.integration
258
+ def test_classification_api(self):
259
+ """Test actual API call for classification."""
260
+ from app import classify_text
261
+
262
+ text = "I love programming in Python!"
263
+ labels = "positive, negative, neutral"
264
+
265
+ result = classify_text(text, labels)
266
+ assert isinstance(result, dict)
267
+ assert len(result) > 0
268
+
269
+
270
+ if __name__ == "__main__":
271
+ pytest.main([__file__, "-v"])