Files
netbox-librenms-plugin/.github/instructions/testing.instructions.md
Vlastislav Svatek 673e67106e
Some checks failed
ci / deploy (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
first commit
2026-06-05 10:39:05 +02:00

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. Avoid from django.test import TestCase.
  • Never use @pytest.mark.django_db for unit tests—mock all database interactions with MagicMock.
  • 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 == y syntax, not self.assertEqual(x, y) (no TestCase inheritance).
  • See docs/development/testing.md for test file structure and running instructions.

Background Job Tests

  • Instantiate JobRunner subclasses using object.__new__(JobClass) to bypass __init__, then set job.job = MagicMock() and job.logger = MagicMock(). See create_mock_job_runner() helper in tests/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 cache where imported: netbox_librenms_plugin.views.imports.list.cache, not django.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_key from import_utils.py; never hardcode key formats like job_123_device_1.

Test File Naming

  • Follow the test_{module_name}.py convention for new test files.
  • test_netbox_librenms_plugin.py is an empty placeholder — do not add tests there.

Test Coverage by Module

  • librenms_api.pytest_librenms_api.py, test_librenms_api_helpers.py
  • import_utils.py, import_validation_helpers.py, utils.pytest_import_utils.py, test_import_validation_helpers.py, test_utils.py
  • jobs.py, views/imports/list.pytest_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), set request = MagicMock() with request.user.has_perm.side_effect = lambda p: p in allowed_perms.
  • For NetBoxObjectPermissionMixin tests, set required_object_permissions on the instance before calling check_object_permissions().
  • Test both the individual methods (has_write_permission(), check_object_permissions()) and the combined require_all_permissions() flow.
  • For JSON variants (require_all_permissions_json), assert isinstance(response, JsonResponse) and check response.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