17 KiB
17 KiB
API Testing Guide - Tenhal Healthcare Platform
Setup for Testing
1. Install Required Packages
pip install requests pytest pytest-django
2. Start Development Server
python manage.py runserver
3. Create Test User (Django Shell)
python manage.py shell
from core.models import User, Tenant
# Create tenant
tenant = Tenant.objects.create(name="Test Clinic")
# Create test user
user = User.objects.create_user(
username='testuser',
email='test@example.com',
password='testpass123',
tenant=tenant,
role='DOCTOR'
)
Testing with Python Requests
Basic Setup
import requests
import json
BASE_URL = 'http://localhost:8000/api/v1'
# Login to get session
session = requests.Session()
login_response = session.post(
'http://localhost:8000/accounts/login/',
data={'username': 'testuser', 'password': 'testpass123'}
)
Test 1: List Patients
def test_list_patients():
response = session.get(f'{BASE_URL}/patients/')
assert response.status_code == 200
data = response.json()
print(f"Found {data['count']} patients")
return data
# Run test
patients = test_list_patients()
Test 2: Create Patient
def test_create_patient():
patient_data = {
'first_name_en': 'John',
'last_name_en': 'Doe',
'date_of_birth': '1990-01-01',
'gender': 'MALE',
'phone': '+966501234567',
'email': 'john.doe@example.com'
}
response = session.post(
f'{BASE_URL}/patients/',
json=patient_data
)
assert response.status_code == 201
patient = response.json()
print(f"Created patient: {patient['id']}")
return patient
# Run test
new_patient = test_create_patient()
Test 3: Get Patient Details
def test_get_patient(patient_id):
response = session.get(f'{BASE_URL}/patients/{patient_id}/')
assert response.status_code == 200
patient = response.json()
print(f"Patient: {patient['full_name']}")
return patient
# Run test
patient_details = test_get_patient(new_patient['id'])
Test 4: Search Patients
def test_search_patients(query):
response = session.get(
f'{BASE_URL}/patients/',
params={'search': query}
)
assert response.status_code == 200
data = response.json()
print(f"Found {data['count']} patients matching '{query}'")
return data
# Run test
search_results = test_search_patients('john')
Test 5: Book Appointment
def test_book_appointment(patient_id, clinic_id, provider_id):
appointment_data = {
'patient': patient_id,
'clinic': clinic_id,
'provider': provider_id,
'service_type': 'CONSULTATION',
'scheduled_date': '2025-10-15',
'scheduled_time': '10:00:00',
'duration': 30,
'notes': 'First visit'
}
response = session.post(
f'{BASE_URL}/appointments/',
json=appointment_data
)
assert response.status_code == 201
appointment = response.json()
print(f"Booked appointment: {appointment['appointment_number']}")
return appointment
# Run test (replace with actual IDs)
# appointment = test_book_appointment(patient_id, clinic_id, provider_id)
Test 6: Confirm Appointment
def test_confirm_appointment(appointment_id):
response = session.post(
f'{BASE_URL}/appointments/{appointment_id}/confirm/',
json={'method': 'SMS'}
)
assert response.status_code == 200
appointment = response.json()
print(f"Confirmed appointment: {appointment['status']}")
return appointment
# Run test
# confirmed = test_confirm_appointment(appointment['id'])
Test 7: Create Invoice
def test_create_invoice(patient_id, service_id):
invoice_data = {
'patient': patient_id,
'issue_date': '2025-10-13',
'due_date': '2025-10-20',
'subtotal': '500.00',
'tax': '75.00',
'discount': '0.00',
'line_items': [
{
'service': service_id,
'description': 'Medical Consultation',
'quantity': 1,
'unit_price': '500.00'
}
]
}
response = session.post(
f'{BASE_URL}/invoices/',
json=invoice_data
)
assert response.status_code == 201
invoice = response.json()
print(f"Created invoice: {invoice['invoice_number']}")
return invoice
# Run test
# invoice = test_create_invoice(patient_id, service_id)
Test 8: Record Payment
def test_record_payment(invoice_id):
payment_data = {
'invoice': invoice_id,
'payment_date': '2025-10-13',
'amount': '575.00',
'method': 'CARD',
'transaction_id': 'TXN123456',
'reference': 'Card ending 1234'
}
response = session.post(
f'{BASE_URL}/payments/',
json=payment_data
)
assert response.status_code == 201
payment = response.json()
print(f"Recorded payment: {payment['id']}")
return payment
# Run test
# payment = test_record_payment(invoice['id'])
Test 9: Create Referral
def test_create_referral(patient_id, from_clinic_id, to_clinic_id):
referral_data = {
'patient': patient_id,
'from_clinic': from_clinic_id,
'to_clinic': to_clinic_id,
'reason': 'Patient requires ABA assessment',
'clinical_summary': '3-year-old with speech delay',
'urgency': 'ROUTINE'
}
response = session.post(
f'{BASE_URL}/referrals/',
json=referral_data
)
assert response.status_code == 201
referral = response.json()
print(f"Created referral: {referral['id']}")
return referral
# Run test
# referral = test_create_referral(patient_id, from_clinic_id, to_clinic_id)
Test 10: Accept Referral
def test_accept_referral(referral_id):
response = session.post(
f'{BASE_URL}/referrals/{referral_id}/accept/',
json={'response_notes': 'Referral accepted. Will schedule assessment.'}
)
assert response.status_code == 200
referral = response.json()
print(f"Accepted referral: {referral['status']}")
return referral
# Run test
# accepted = test_accept_referral(referral['id'])
Testing with cURL
List Patients
curl -X GET http://localhost:8000/api/v1/patients/ \
-H "Cookie: sessionid=your-session-id"
Create Patient
curl -X POST http://localhost:8000/api/v1/patients/ \
-H "Content-Type: application/json" \
-H "Cookie: sessionid=your-session-id" \
-d '{
"first_name_en": "Jane",
"last_name_en": "Smith",
"date_of_birth": "1985-05-15",
"gender": "FEMALE",
"phone": "+966509876543"
}'
Book Appointment
curl -X POST http://localhost:8000/api/v1/appointments/ \
-H "Content-Type: application/json" \
-H "Cookie: sessionid=your-session-id" \
-d '{
"patient": "patient-uuid",
"clinic": "clinic-uuid",
"provider": "provider-uuid",
"scheduled_date": "2025-10-15",
"scheduled_time": "14:00:00",
"duration": 30
}'
Get Today's Appointments
curl -X GET http://localhost:8000/api/v1/appointments/today/ \
-H "Cookie: sessionid=your-session-id"
Get Appointment Statistics
curl -X GET http://localhost:8000/api/v1/appointments/statistics/ \
-H "Cookie: sessionid=your-session-id"
Complete Test Suite
import requests
import json
from datetime import date, timedelta
class TenhalAPITester:
def __init__(self, base_url='http://localhost:8000'):
self.base_url = base_url
self.api_url = f'{base_url}/api/v1'
self.session = requests.Session()
def login(self, username, password):
"""Login and establish session"""
response = self.session.post(
f'{self.base_url}/accounts/login/',
data={'username': username, 'password': password}
)
return response.status_code == 200
def test_patient_workflow(self):
"""Test complete patient workflow"""
print("\n=== Testing Patient Workflow ===")
# 1. Create patient
patient_data = {
'first_name_en': 'Test',
'last_name_en': 'Patient',
'date_of_birth': '2020-01-01',
'gender': 'MALE',
'phone': '+966501111111'
}
response = self.session.post(f'{self.api_url}/patients/', json=patient_data)
assert response.status_code == 201
patient = response.json()
print(f"✓ Created patient: {patient['mrn']}")
# 2. Get patient details
response = self.session.get(f"{self.api_url}/patients/{patient['id']}/")
assert response.status_code == 200
print(f"✓ Retrieved patient details")
# 3. Search for patient
response = self.session.get(f"{self.api_url}/patients/", params={'search': 'Test'})
assert response.status_code == 200
print(f"✓ Searched patients")
return patient
def test_appointment_workflow(self, patient_id, clinic_id, provider_id):
"""Test complete appointment workflow"""
print("\n=== Testing Appointment Workflow ===")
# 1. Book appointment
appointment_data = {
'patient': patient_id,
'clinic': clinic_id,
'provider': provider_id,
'scheduled_date': str(date.today() + timedelta(days=1)),
'scheduled_time': '10:00:00',
'duration': 30
}
response = self.session.post(f'{self.api_url}/appointments/', json=appointment_data)
assert response.status_code == 201
appointment = response.json()
print(f"✓ Booked appointment: {appointment['appointment_number']}")
# 2. Confirm appointment
response = self.session.post(
f"{self.api_url}/appointments/{appointment['id']}/confirm/",
json={'method': 'SMS'}
)
assert response.status_code == 200
print(f"✓ Confirmed appointment")
# 3. Mark arrived
response = self.session.post(f"{self.api_url}/appointments/{appointment['id']}/arrive/")
assert response.status_code == 200
print(f"✓ Marked patient arrived")
# 4. Start appointment
response = self.session.post(f"{self.api_url}/appointments/{appointment['id']}/start/")
assert response.status_code == 200
print(f"✓ Started appointment")
# 5. Complete appointment
response = self.session.post(f"{self.api_url}/appointments/{appointment['id']}/complete/")
assert response.status_code == 200
print(f"✓ Completed appointment")
return appointment
def test_finance_workflow(self, patient_id, service_id):
"""Test complete finance workflow"""
print("\n=== Testing Finance Workflow ===")
# 1. Create invoice
invoice_data = {
'patient': patient_id,
'issue_date': str(date.today()),
'due_date': str(date.today() + timedelta(days=7)),
'subtotal': '500.00',
'tax': '75.00',
'discount': '0.00',
'line_items': [{
'service': service_id,
'description': 'Test Service',
'quantity': 1,
'unit_price': '500.00'
}]
}
response = self.session.post(f'{self.api_url}/invoices/', json=invoice_data)
assert response.status_code == 201
invoice = response.json()
print(f"✓ Created invoice: {invoice['invoice_number']}")
# 2. Issue invoice
response = self.session.post(f"{self.api_url}/invoices/{invoice['id']}/issue/")
assert response.status_code == 200
print(f"✓ Issued invoice")
# 3. Record payment
payment_data = {
'invoice': invoice['id'],
'payment_date': str(date.today()),
'amount': '575.00',
'method': 'CASH'
}
response = self.session.post(f'{self.api_url}/payments/', json=payment_data)
assert response.status_code == 201
print(f"✓ Recorded payment")
# 4. Process payment
payment = response.json()
response = self.session.post(f"{self.api_url}/payments/{payment['id']}/process/")
assert response.status_code == 200
print(f"✓ Processed payment")
return invoice
def test_referral_workflow(self, patient_id, from_clinic_id, to_clinic_id):
"""Test complete referral workflow"""
print("\n=== Testing Referral Workflow ===")
# 1. Create referral
referral_data = {
'patient': patient_id,
'from_clinic': from_clinic_id,
'to_clinic': to_clinic_id,
'reason': 'Test referral',
'urgency': 'ROUTINE'
}
response = self.session.post(f'{self.api_url}/referrals/', json=referral_data)
assert response.status_code == 201
referral = response.json()
print(f"✓ Created referral")
# 2. Accept referral
response = self.session.post(
f"{self.api_url}/referrals/{referral['id']}/accept/",
json={'response_notes': 'Accepted'}
)
assert response.status_code == 200
print(f"✓ Accepted referral")
# 3. Complete referral
response = self.session.post(f"{self.api_url}/referrals/{referral['id']}/complete/")
assert response.status_code == 200
print(f"✓ Completed referral")
return referral
def run_all_tests(self, clinic_id, provider_id, service_id):
"""Run all test workflows"""
print("\n" + "="*50)
print("TENHAL API TEST SUITE")
print("="*50)
# Test patient workflow
patient = self.test_patient_workflow()
# Test appointment workflow
appointment = self.test_appointment_workflow(
patient['id'], clinic_id, provider_id
)
# Test finance workflow
invoice = self.test_finance_workflow(patient['id'], service_id)
# Test referral workflow (need two clinics)
# referral = self.test_referral_workflow(patient['id'], clinic_id, clinic_id)
print("\n" + "="*50)
print("ALL TESTS PASSED ✓")
print("="*50)
# Usage
if __name__ == '__main__':
tester = TenhalAPITester()
# Login
if tester.login('testuser', 'testpass123'):
print("✓ Logged in successfully")
# Run tests (replace with actual IDs)
# tester.run_all_tests(
# clinic_id='your-clinic-uuid',
# provider_id='your-provider-uuid',
# service_id='your-service-uuid'
# )
else:
print("✗ Login failed")
Performance Testing
import time
import statistics
def performance_test(session, endpoint, iterations=100):
"""Test API endpoint performance"""
times = []
for i in range(iterations):
start = time.time()
response = session.get(f'{BASE_URL}{endpoint}')
end = time.time()
times.append(end - start)
print(f"\nPerformance Test: {endpoint}")
print(f"Iterations: {iterations}")
print(f"Average: {statistics.mean(times):.3f}s")
print(f"Median: {statistics.median(times):.3f}s")
print(f"Min: {min(times):.3f}s")
print(f"Max: {max(times):.3f}s")
# Run performance tests
performance_test(session, '/patients/', iterations=50)
performance_test(session, '/appointments/', iterations=50)
Error Handling Tests
def test_error_handling():
"""Test API error responses"""
# Test 404
response = session.get(f'{BASE_URL}/patients/invalid-uuid/')
assert response.status_code == 404
print("✓ 404 error handled correctly")
# Test 400 (validation error)
response = session.post(f'{BASE_URL}/patients/', json={})
assert response.status_code == 400
print("✓ 400 validation error handled correctly")
# Test unauthorized
unauthorized_session = requests.Session()
response = unauthorized_session.get(f'{BASE_URL}/patients/')
assert response.status_code in [401, 403]
print("✓ Unauthorized access blocked")
test_error_handling()
Conclusion
This testing guide provides comprehensive examples for testing all major API endpoints. Adapt the test data (UUIDs, dates, etc.) to match your actual database records.
For automated testing in CI/CD, consider using pytest with pytest-django for integration tests.