muboboev commited on
Commit
c8379d5
·
verified ·
1 Parent(s): aa739d7

Этап 12. Тестирование и эмуляция

Browse files

Сценарий "пациент из очереди → исследование → отчёт → баллы".

Нагрузочные тесты API (Postman, JMeter).

Проверка визуальных состояний UI (статусы, таймеры).

Настройка тестовой базы (SQLite → PostgreSQL).

Files changed (2) hide show
  1. index.html +10 -1
  2. testrunner.html +312 -0
index.html CHANGED
@@ -140,7 +140,7 @@
140
  </div>
141
  <p class="text-gray-300">Global system management and monitoring</p>
142
  </a>
143
- <a href="filesanddicom.html" class="module-card rounded-xl p-6 border border-gray-700 hover:border-teal-500 transition">
144
  <div class="flex items-center mb-4">
145
  <div class="p-3 bg-teal-500 rounded-lg mr-4">
146
  <i data-feather="hard-drive" class="w-6 h-6"></i>
@@ -149,6 +149,15 @@
149
  </div>
150
  <p class="text-gray-300">Storage for files and DICOM images with PACS integration</p>
151
  </a>
 
 
 
 
 
 
 
 
 
152
  </div>
153
 
154
  <div class="bg-gray-800 rounded-xl p-8 backdrop-blur-sm bg-opacity-70 max-w-4xl mx-auto">
 
140
  </div>
141
  <p class="text-gray-300">Global system management and monitoring</p>
142
  </a>
143
+ <a href="filesanddicom.html" class="module-card rounded-xl p-6 border border-gray-700 hover:border-teal-500 transition">
144
  <div class="flex items-center mb-4">
145
  <div class="p-3 bg-teal-500 rounded-lg mr-4">
146
  <i data-feather="hard-drive" class="w-6 h-6"></i>
 
149
  </div>
150
  <p class="text-gray-300">Storage for files and DICOM images with PACS integration</p>
151
  </a>
152
+ <a href="testrunner.html" class="module-card rounded-xl p-6 border border-gray-700 hover:border-indigo-500 transition">
153
+ <div class="flex items-center mb-4">
154
+ <div class="p-3 bg-indigo-500 rounded-lg mr-4">
155
+ <i data-feather="check-circle" class="w-6 h-6"></i>
156
+ </div>
157
+ <h3 class="text-xl font-semibold">TestRunner</h3>
158
+ </div>
159
+ <p class="text-gray-300">Automated testing and simulation environment</p>
160
+ </a>
161
  </div>
162
 
163
  <div class="bg-gray-800 rounded-xl p-8 backdrop-blur-sm bg-opacity-70 max-w-4xl mx-auto">
testrunner.html ADDED
@@ -0,0 +1,312 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Test Runner | MedMIS</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://unpkg.com/feather-icons"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
10
+ <style>
11
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
12
+ body {
13
+ font-family: 'Inter', sans-serif;
14
+ }
15
+ .test-card {
16
+ transition: all 0.2s ease;
17
+ }
18
+ .test-card:hover {
19
+ transform: translateY(-2px);
20
+ }
21
+ .status-running {
22
+ background-color: #f59e0b20;
23
+ color: #f59e0b;
24
+ }
25
+ .status-passed {
26
+ background-color: #10b98120;
27
+ color: #10b981;
28
+ }
29
+ .status-failed {
30
+ background-color: #ef444420;
31
+ color: #ef4444;
32
+ }
33
+ </style>
34
+ </head>
35
+ <body class="bg-gray-900 text-white min-h-screen">
36
+ <div class="container mx-auto px-4 py-8">
37
+ <header class="mb-8">
38
+ <h1 class="text-3xl font-bold">Test Runner</h1>
39
+ <p class="text-gray-300">Automated testing for MedMIS workflows</p>
40
+ </header>
41
+
42
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8">
43
+ <!-- Test Scenarios -->
44
+ <div class="lg:col-span-2 bg-gray-800 rounded-xl p-6">
45
+ <h2 class="text-xl font-semibold mb-4 flex items-center">
46
+ <i data-feather="list" class="w-5 h-5 mr-2"></i>
47
+ Test Scenarios
48
+ </h2>
49
+ <div class="space-y-3" id="testScenarios">
50
+ <div class="test-card bg-gray-700 rounded-lg p-4 cursor-pointer hover:bg-gray-600">
51
+ <div class="flex justify-between items-start">
52
+ <div>
53
+ <h3 class="font-medium">Patient Flow</h3>
54
+ <p class="text-sm text-gray-400">Registration → Queue → Study → Report</p>
55
+ </div>
56
+ <button class="run-test bg-blue-600 hover:bg-blue-700 text-white py-1 px-3 rounded text-sm" data-test="patientFlow">
57
+ Run
58
+ </button>
59
+ </div>
60
+ </div>
61
+ <div class="test-card bg-gray-700 rounded-lg p-4 cursor-pointer hover:bg-gray-600">
62
+ <div class="flex justify-between items-start">
63
+ <div>
64
+ <h3 class="font-medium">SLA Compliance</h3>
65
+ <p class="text-sm text-gray-400">Priority-based timing and scoring</p>
66
+ </div>
67
+ <button class="run-test bg-blue-600 hover:bg-blue-700 text-white py-1 px-3 rounded text-sm" data-test="slaCompliance">
68
+ Run
69
+ </button>
70
+ </div>
71
+ </div>
72
+ <div class="test-card bg-gray-700 rounded-lg p-4 cursor-pointer hover:bg-gray-600">
73
+ <div class="flex justify-between items-start">
74
+ <div>
75
+ <h3 class="font-medium">Integration Flow</h3>
76
+ <p class="text-sm text-gray-400">Service-to-service event routing</p>
77
+ </div>
78
+ <button class="run-test bg-blue-600 hover:bg-blue-700 text-white py-1 px-3 rounded text-sm" data-test="integrationFlow">
79
+ Run
80
+ </button>
81
+ </div>
82
+ </div>
83
+ </div>
84
+ </div>
85
+
86
+ <!-- Test Results -->
87
+ <div class="bg-gray-800 rounded-xl p-6">
88
+ <h2 class="text-xl font-semibold mb-4 flex items-center">
89
+ <i data-feather="check-circle" class="w-5 h-5 mr-2"></i>
90
+ Test Results
91
+ </h2>
92
+ <div id="testResults" class="space-y-3">
93
+ <div class="bg-gray-700 rounded-lg p-4">
94
+ <div class="flex justify-between mb-2">
95
+ <span class="font-medium">Last Run:</span>
96
+ <span class="text-gray-400">Not run yet</span>
97
+ </div>
98
+ <div class="flex justify-between">
99
+ <span class="font-medium">Status:</span>
100
+ <span class="text-gray-400">Idle</span>
101
+ </div>
102
+ </div>
103
+ <div id="testLogs" class="bg-gray-900 rounded-lg p-4 h-64 overflow-y-auto text-sm font-mono">
104
+ <!-- Test logs will appear here -->
105
+ </div>
106
+ </div>
107
+ </div>
108
+ </div>
109
+
110
+ <!-- API Test Console -->
111
+ <div class="bg-gray-800 rounded-xl p-6 mb-8">
112
+ <h2 class="text-xl font-semibold mb-4 flex items-center">
113
+ <i data-feather="terminal" class="w-5 h-5 mr-2"></i>
114
+ API Test Console
115
+ </h2>
116
+ <div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-4">
117
+ <div>
118
+ <label class="block text-gray-300 text-sm mb-1">Method</label>
119
+ <select id="apiMethod" class="w-full bg-gray-700 rounded-lg px-3 py-2">
120
+ <option>GET</option>
121
+ <option>POST</option>
122
+ <option>PUT</option>
123
+ <option>DELETE</option>
124
+ </select>
125
+ </div>
126
+ <div class="md:col-span-3">
127
+ <label class="block text-gray-300 text-sm mb-1">Endpoint</label>
128
+ <div class="flex">
129
+ <span class="bg-gray-700 rounded-l-lg px-3 py-2">/api/</span>
130
+ <input type="text" id="apiEndpoint" class="flex-1 bg-gray-700 rounded-r-lg px-3 py-2" placeholder="endpoint">
131
+ </div>
132
+ </div>
133
+ </div>
134
+ <div class="mb-4">
135
+ <label class="block text-gray-300 text-sm mb-1">Request Body</label>
136
+ <textarea id="apiBody" class="w-full bg-gray-700 rounded-lg px-3 py-2 h-32 font-mono text-sm" placeholder="JSON body"></textarea>
137
+ </div>
138
+ <button id="runApiTest" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-lg transition">
139
+ Execute API Test
140
+ </button>
141
+ <div id="apiResponse" class="mt-4 bg-gray-900 rounded-lg p-4 h-64 overflow-y-auto text-sm font-mono hidden">
142
+ <div class="text-gray-400">Response will appear here...</div>
143
+ </div>
144
+ </div>
145
+
146
+ <!-- Database Configuration -->
147
+ <div class="bg-gray-800 rounded-xl p-6">
148
+ <h2 class="text-xl font-semibold mb-4 flex items-center">
149
+ <i data-feather="database" class="w-5 h-5 mr-2"></i>
150
+ Database Configuration
151
+ </h2>
152
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
153
+ <div>
154
+ <h3 class="font-medium mb-2">Test Database</h3>
155
+ <div class="bg-gray-700 rounded-lg p-4">
156
+ <div class="flex items-center justify-between mb-2">
157
+ <span>Current:</span>
158
+ <span class="font-mono bg-gray-800 px-2 py-1 rounded">SQLite</span>
159
+ </div>
160
+ <button id="switchDb" class="w-full bg-purple-600 hover:bg-purple-700 text-white py-2 px-4 rounded-lg transition mt-2">
161
+ Switch to PostgreSQL
162
+ </button>
163
+ </div>
164
+ </div>
165
+ <div>
166
+ <h3 class="font-medium mb-2">Sample Data</h3>
167
+ <div class="space-y-2">
168
+ <button class="w-full bg-gray-700 hover:bg-gray-600 text-white py-2 px-4 rounded-lg transition text-left flex items-center">
169
+ <i data-feather="user" class="w-4 h-4 mr-2"></i>
170
+ Load Test Patients
171
+ </button>
172
+ <button class="w-full bg-gray-700 hover:bg-gray-600 text-white py-2 px-4 rounded-lg transition text-left flex items-center">
173
+ <i data-feather="book" class="w-4 h-4 mr-2"></i>
174
+ Load Test Studies
175
+ </button>
176
+ <button class="w-full bg-gray-700 hover:bg-gray-600 text-white py-2 px-4 rounded-lg transition text-left flex items-center">
177
+ <i data-feather="file-text" class="w-4 h-4 mr-2"></i>
178
+ Load Test Reports
179
+ </button>
180
+ </div>
181
+ </div>
182
+ </div>
183
+ </div>
184
+ </div>
185
+
186
+ <script>
187
+ feather.replace();
188
+
189
+ // Test scenario runner
190
+ document.querySelectorAll('.run-test').forEach(button => {
191
+ button.addEventListener('click', function() {
192
+ const testName = this.dataset.test;
193
+ const testLogs = document.getElementById('testLogs');
194
+ testLogs.innerHTML = '';
195
+
196
+ // Update status
197
+ const testResults = document.getElementById('testResults');
198
+ testResults.querySelector('.bg-gray-700 div:last-child span').textContent = 'Running';
199
+ testResults.querySelector('.bg-gray-700 div:last-child span').className = 'text-yellow-400';
200
+
201
+ logMessage(`Starting ${testName} test...`);
202
+
203
+ // Simulate test execution
204
+ setTimeout(() => {
205
+ switch(testName) {
206
+ case 'patientFlow':
207
+ simulatePatientFlowTest();
208
+ break;
209
+ case 'slaCompliance':
210
+ simulateSlaTest();
211
+ break;
212
+ case 'integrationFlow':
213
+ simulateIntegrationTest();
214
+ break;
215
+ }
216
+ }, 500);
217
+ });
218
+ });
219
+
220
+ function logMessage(message) {
221
+ const testLogs = document.getElementById('testLogs');
222
+ const line = document.createElement('div');
223
+ line.textContent = `[${new Date().toLocaleTimeString()}] ${message}`;
224
+ testLogs.appendChild(line);
225
+ testLogs.scrollTop = testLogs.scrollHeight;
226
+ }
227
+
228
+ function simulatePatientFlowTest() {
229
+ logMessage("1. Creating test patient...");
230
+ setTimeout(() => {
231
+ logMessage("✓ Patient created (ID: PT-123456)");
232
+
233
+ logMessage("2. Adding to queue...");
234
+ setTimeout(() => {
235
+ logMessage("✓ Added to queue (Q-789012)");
236
+
237
+ logMessage("3. Starting study...");
238
+ setTimeout(() => {
239
+ logMessage("✓ Study created (ST-345678)");
240
+
241
+ logMessage("4. Generating report...");
242
+ setTimeout(() => {
243
+ logMessage("✓ Report finalized (RP-901234)");
244
+
245
+ logMessage("5. Checking scores...");
246
+ setTimeout(() => {
247
+ logMessage("✓ Scores updated (+20 radiologist, +100 referrer)");
248
+
249
+ // Update status
250
+ const testResults = document.getElementById('testResults');
251
+ testResults.querySelector('.bg-gray-700 div:first-child span').textContent = new Date().toLocaleString();
252
+ testResults.querySelector('.bg-gray-700 div:last-child span').textContent = 'Passed';
253
+ testResults.querySelector('.bg-gray-700 div:last-child span').className = 'text-green-400';
254
+
255
+ logMessage("✅ Test completed successfully");
256
+ }, 800);
257
+ }, 800);
258
+ }, 800);
259
+ }, 800);
260
+ }, 800);
261
+ }
262
+
263
+ // API test console
264
+ document.getElementById('runApiTest').addEventListener('click', function() {
265
+ const method = document.getElementById('apiMethod').value;
266
+ const endpoint = document.getElementById('apiEndpoint').value;
267
+ const body = document.getElementById('apiBody').value;
268
+ const responseDiv = document.getElementById('apiResponse');
269
+
270
+ responseDiv.classList.remove('hidden');
271
+ responseDiv.innerHTML = '<div class="text-gray-400">Testing endpoint...</div>';
272
+
273
+ // Simulate API call
274
+ setTimeout(() => {
275
+ let response;
276
+ try {
277
+ const parsedBody = body ? JSON.parse(body) : {};
278
+ response = {
279
+ status: 200,
280
+ data: {
281
+ method,
282
+ endpoint,
283
+ body: parsedBody,
284
+ timestamp: new Date().toISOString(),
285
+ traceId: 't-' + Math.random().toString(36).substr(2, 8)
286
+ }
287
+ };
288
+
289
+ responseDiv.innerHTML = `<div class="text-green-400 mb-2">Request successful (200)</div>
290
+ <pre>${JSON.stringify(response, null, 2)}</pre>`;
291
+ } catch (e) {
292
+ responseDiv.innerHTML = `<div class="text-red-400 mb-2">Error: ${e.message}</div>`;
293
+ }
294
+ }, 1000);
295
+ });
296
+
297
+ // Database switcher
298
+ document.getElementById('switchDb').addEventListener('click', function() {
299
+ const button = this;
300
+ const currentDb = button.textContent.includes('PostgreSQL') ? 'PostgreSQL' : 'SQLite';
301
+ const newDb = currentDb === 'SQLite' ? 'PostgreSQL' : 'SQLite';
302
+
303
+ logMessage(`Switching database from ${currentDb} to ${newDb}...`);
304
+ setTimeout(() => {
305
+ button.textContent = `Switch to ${currentDb}`;
306
+ button.parentElement.querySelector('span.font-mono').textContent = newDb;
307
+ logMessage(`✓ Database switched to ${newDb}`);
308
+ }, 1500);
309
+ });
310
+ </script>
311
+ </body>
312
+ </html>