3.8 KiB
3.8 KiB
applyTo, description
| applyTo | description |
|---|---|
| tests/** | Testing patterns and conventions for the NetBox LibreNMS plugin |
Testing Patterns
General Test Conventions
- Use plain pytest classes, not Django
TestCase. Avoidfrom django.test import TestCase. - Never use
@pytest.mark.django_dbfor unit tests—mock all database interactions withMagicMock. - Use inline imports inside test methods to avoid Django initialization at module load time.
- Mock NetBox models (Device, Job, User) with
MagicMock()instead of creating real instances. - Use
assert x == ysyntax, notself.assertEqual(x, y)(no TestCase inheritance). - See docs/development/testing.md for test file structure and running instructions.
Background Job Tests
- Instantiate
JobRunnersubclasses usingobject.__new__(JobClass)to bypass__init__, then setjob.job = MagicMock()andjob.logger = MagicMock(). Seecreate_mock_job_runner()helper intests/test_background_jobs.py. - Patch deferred/inline imports at their source module (e.g.,
netbox_librenms_plugin.import_utils.process_device_filters), not the consuming module. - Patch
cachewhere imported:netbox_librenms_plugin.views.imports.list.cache, notdjango.core.cache.cache. - Test view decision logic by setting
view._filter_form_data = {...}directly, not via HTTP requests. - Never use
RequestFactory—mock request objects directly or test method logic in isolation. - Cache key tests must patch
get_validated_device_cache_keyfromimport_utils.py; never hardcode key formats likejob_123_device_1.
Test File Naming
- Follow the
test_{module_name}.pyconvention for new test files. test_netbox_librenms_plugin.pyis an empty placeholder — do not add tests there.
Test Coverage by Module
librenms_api.py→test_librenms_api.py,test_librenms_api_helpers.pyimport_utils.py,import_validation_helpers.py,utils.py→test_import_utils.py,test_import_validation_helpers.py,test_utils.pyjobs.py,views/imports/list.py→test_background_jobs.py- Permission mixins, API permissions, constants →
test_permissions.py - VLAN API, mode detection, comparison, sync →
test_vlan_sync.py VlanAssignmentMixin, VLAN enrichment →test_interface_vlan_sync.py- Views (
views/sync/,views/object_sync/,views/imports/actions.py) — no dedicated test files yet. Test business logic via the utility modules they call, not via HTTP requests.
Permission Test Patterns
When testing permissions (see test_permissions.py for reference):
- Create a mock view instance with
object.__new__(ViewClass), setrequest = MagicMock()withrequest.user.has_perm.side_effect = lambda p: p in allowed_perms. - For
NetBoxObjectPermissionMixintests, setrequired_object_permissionson the instance before callingcheck_object_permissions(). - Test both the individual methods (
has_write_permission(),check_object_permissions()) and the combinedrequire_all_permissions()flow. - For JSON variants (
require_all_permissions_json), assertisinstance(response, JsonResponse)and checkresponse.status_code == 403.
Shared Fixtures (conftest.py)
Reuse fixtures from tests/conftest.py instead of creating ad-hoc mocks:
- Configuration:
mock_multi_server_config,mock_legacy_config - API client:
mock_librenms_api - NetBox objects:
mock_netbox_device,mock_netbox_vm,mock_netbox_site,mock_netbox_platform,mock_netbox_device_type,mock_netbox_device_role,mock_netbox_cluster,mock_netbox_rack - HTTP responses:
mock_response_factory,mock_success_response,mock_device_response,mock_error_response,mock_auth_error_response - Import workflow:
sample_librenms_device,sample_librenms_device_minimal,sample_validation_state,sample_validation_state_vm