9.2 KiB
Testing Patterns
Analysis Date: 2026-05-07
Test Framework
Runner:
- Django's built-in
TestCasefromdjango.test - NO pytest or pytest-django detected in
requirements.txt - Tests run via:
python manage.py test
Assertion Library:
- Django's
TestCasebuilt-in assertions (inherited fromunittest.TestCase) self.assertEqual(),self.assertTrue(),self.assertRaises(), etc.
Run Commands:
python manage.py test # Run all tests
python manage.py test app_name # Run tests for specific app
python manage.py test app_name.tests.TestClassName # Run specific test class
Coverage:
- No
.coveragercor coverage configuration found - No coverage requirement enforced
Test File Organization
Location:
- Each Django app has a
tests.pyfile in app root:{app_name}/tests.py - Pattern: co-located with models, serializers, views (one file per app)
Naming:
- Single file:
tests.py - Test classes inherit from
django.test.TestCase - Test methods prefixed with
test_:test_audio(),test_model_creation(),test_view_response()
File Structure:
app_name/
├── models.py
├── serializers.py
├── views.py
├── urls.py
└── tests.py # All tests for this app
Current Test Coverage Status
Honest Assessment: MINIMAL
Test files examined show very sparse coverage:
userapp/tests.py: 4 lines (empty TestCase class)aiapp/tests.py: 24 lines (only 1 actual test:test_audio())card/tests.py: 3 lines (empty)device_interaction/tests.py: 3 lines (empty)achievement_app/tests.py: 3 lines (empty)
Total active test methods: 1 (audio synthesis in aiapp/tests.py)
This represents critical test coverage gap — almost all API endpoints, models, and serializers are untested.
Test Structure
Suite Organization from aiapp/tests.py:
from django.test import TestCase
from django.urls import reverse
from .audio.AudioService import get_audio_service
class YourModelTest(TestCase):
def test_audio(self):
# Setup (minimal)
audio_ser = get_audio_service()
audio_ser.synthesize_speech('你好,你是谁啊')
# Commented-out template tests below (never implemented)
# def test_model_creation(self):
# def test_view_response(self):
Patterns:
setUp()method not used; tests don't create fixtures- No tearDown() cleanup observed
- No assertion calls in active test (test_audio just calls synthesize_speech without checking result)
Mocking
Framework: No mocking library detected (no unittest.mock, responses, pytest-mock in requirements.txt)
Current Practice:
- Tests that DO exist (test_audio) call real external services (AudioService.synthesize_speech)
- No mocking observed for:
- Aliyun API calls (SMS, OSS, NLS)
- Volcengine RTC token generation
- Tencent audio service
- Kimi AI API
- Redis cache operations
- Database operations (use real test DB)
Risk: Tests that call production services (Aliyun, Kimi, Volcengine) require:
- Valid credentials in .env
- Network access to external services
- Potential cost (SMS sends, API calls)
Database Testing
Test Database:
- Django uses a separate test database (by default: test_qy_lty or suffixed with
test_) - No custom settings for test DB observed
- No fixtures or data factories defined
Patterns:
- Models have no test data factories (no factory_boy or similar)
- No
setUp()creating test objects - Manual creation would be required:
Model.objects.create(...)
Fixtures and Test Data
Test Data:
- NO fixture files found (.json, .yaml, .fixture)
- NO factory definitions (factory_boy not in requirements)
- NO model-level test data builders
How to Add: If implementing tests, would need:
def setUp(self):
self.user = ParadiseUser.objects.create(
username='testuser',
email='test@example.com'
)
self.device = Device.objects.create(
device_type=...,
batch=...,
mac_address='AA:BB:CC:DD:EE:FF'
)
WebSocket Consumer Testing
Current State: NO WebSocket consumer tests
Channels provides channels.testing package for async testing, but:
- No
conftest.pyor pytest configuration - No async test runner configured
- Would require adding pytest + pytest-asyncio + pytest-django
If implementing WebSocket tests, would require:
from channels.testing import WebsocketCommunicator
from device_interaction.consumers import DeviceConsumer
async def test_device_consumer_connect():
communicator = WebsocketCommunicator(DeviceConsumer.as_asgi(), '/ws/device/')
connected, subprotocol = await communicator.connect()
assert connected
External Service Testing
Services integrated WITHOUT mocking in current codebase:
aiapp.audio.AudioService— calls real Aliyun/Tencent/Volcengine- Aliyun SMS (send_sms in userapp/utils.py)
- Aliyun OSS (file uploads)
- Kimi API (AI chat)
- Volcengine RTC token generation
- WeChat OAuth (django-allauth)
No test doubles, stubs, or mocks exist — tests would hit production services.
API Endpoint Testing
Current State: NO API tests
Endpoints that should be tested but are NOT:
- User authentication:
/api/user/register/,/api/user/mac-login/,/api/user/phone-login/ - AI chat:
/api/ai/chat/{bot_id}/,/api/ai/multi-chat/ - Device binding:
/api/device/bind/,/api/device/bind-status/ - Card operations:
/api/card/scan/,/api/card/use/,/api/card/batches/generate/ - Achievement tracking:
/api/achievement/user-achievements/ - WebSocket:
/ws/device/connection and message handling
If implementing, would use DRF test client:
from rest_framework.test import APIClient
class UserAuthTest(TestCase):
def setUp(self):
self.client = APIClient()
def test_mac_login(self):
response = self.client.post('/api/user/mac-login/', {
'mac_address': 'AA:BB:CC:DD:EE:FF'
})
self.assertEqual(response.status_code, 200)
self.assertIn('token', response.json()['data'])
Test Coverage Gaps
CRITICAL UNTESTED AREAS:
-
Authentication layer — RedisTokenAuthentication never tested
- Token generation in userapp/utils.py:generate_token()
- Token validation in userapp/authentication.py
- Device MAC login flow
- Phone verification login
-
Device control semantics — "last-bind-wins" ordering never verified
- UserDevice.Meta.ordering = ['-bound_at'] not tested
- Multiple users binding same device — control resolution untested
- Hardcoded test MAC (AA:BB:CC:DD:EE:FF) skip logic untested
-
WebSocket messaging — All consumer methods untested
- DeviceConsumer.connect() authentication
- Message routing in receive()
- Group messaging (device_{user_id})
- Disconnect and heartbeat (device:last_seen:{mac})
-
Serializer validation — No validation tests
- All custom validators in serializers.py files untested
- Foreign key constraints untested
- Unique field constraints untested
-
External service integration — No mocking
- Aliyun SMS send (send_sms)
- Aliyun OSS upload
- Kimi AI API calls
- Volcengine RTC token generation
- Tencent audio service
-
Async task processing — No tests
- Affinity rule evaluation (coming in P2)
- Device heartbeat refresh (5-min TTL)
- Daily affinity counter aggregation
-
Model business logic — No tests
- AffinityRule.get_solo() singleton pattern
- Device code generation (generate_device_code)
- User achievement unlock logic
- Card batch generation logic
Recommendations for Test Implementation
Phase 1 - Setup (High Priority):
- Add pytest + pytest-django + pytest-asyncio to requirements.txt
- Create conftest.py for shared fixtures
- Create factory definitions (factory_boy) for common models
- Mock external services (responses, unittest.mock)
Phase 2 - Unit Tests (High Priority):
- Test authentication (token generation, validation, expiry)
- Test device binding semantics (last-bind-wins)
- Test serializer validation
- Test model methods (AffinitySetting.get_solo, generate_device_code)
Phase 3 - Integration Tests (Medium Priority):
- Test full auth flows (MAC login, phone login, registration)
- Test API endpoints with mocked external services
- Test WebSocket consumer connection and messaging
- Test card batch generation workflow
Phase 4 - E2E Tests (Lower Priority):
- Test device binding → WebSocket connection → message exchange flow
- Test achievement unlock on user action flow
- Test affinity rule trigger and log creation
Minimum Coverage Target for Production:
- Authentication/authorization: 80%+
- Device control logic: 100% (critical for device binding semantics)
- Serializer validation: 70%+
- API endpoints: 60%+ (focus on public-facing, critical flows)
Testing analysis: 2026-05-07
Test Execution Example
Current working test (from aiapp/tests.py):
$ python manage.py test aiapp.tests.YourModelTest.test_audio
This test:
- Gets AudioService instance
- Calls synthesize_speech with Chinese text
- Returns (no assertions — test just checks for uncaught exceptions)
This represents the ONLY active test in the codebase and does not verify behavior, only that the call completes.