nautobot.apps.testing
¶
Utilities for apps to implement test automation.
nautobot.apps.testing.APITestCase
¶
Bases: ModelTestCase
Base test case for API requests.
api_version: Specific API version to test. Leave unset to test the default behavior. Override with set_api_version()
assert_no_verboten_content(response)
¶
Check an API response for content that should not be exposed in the API.
If a specific API has a false failure here (maybe it has security-related strings as model flags or something?), its test case should overload self.VERBOTEN_STRINGS appropriately.
setUp()
¶
Create a token for API calls.
set_api_version(api_version)
¶
Set or unset a specific API version for requests in this test case.
nautobot.apps.testing.APITransactionTestCase
¶
Bases: APITransactionTestCase
, NautobotTestCaseMixin
setUp()
¶
Create a superuser and token for API calls.
nautobot.apps.testing.APIViewTestCases
¶
CreateObjectViewTestCase
¶
Bases: APITestCase
test_bulk_create_objects()
¶
POST a set of objects in a single request.
test_create_object()
¶
POST a single object with permission.
test_create_object_without_permission()
¶
POST a single object without permission.
test_recreate_object_csv()
¶
CSV export an object, delete it, and recreate it via CSV import.
DeleteObjectViewTestCase
¶
Bases: APITestCase
get_deletable_object()
¶
Get an instance that can be deleted.
For some models this may just be any random object, but when we have FKs with on_delete=models.PROTECT
(as is often the case) we need to find or create an instance that doesn't have such entanglements.
get_deletable_object_pks()
¶
Get a list of PKs corresponding to objects that can be safely bulk-deleted.
For some models this may just be any random objects, but when we have FKs with on_delete=models.PROTECT
(as is often the case) we need to find or create an instance that doesn't have such entanglements.
test_bulk_delete_objects()
¶
DELETE a set of objects in a single request.
test_delete_object()
¶
DELETE a single object identified by its primary key.
test_delete_object_without_permission()
¶
DELETE a single object without permission.
GetObjectViewTestCase
¶
Bases: APITestCase
test_get_object()
¶
GET a single object as an authenticated user with permission to view the object.
test_get_object_anonymous()
¶
GET a single object as an unauthenticated user.
test_get_object_without_permission()
¶
GET a single object as an authenticated user without the required permission.
test_options_object()
¶
Make an OPTIONS request for a single object.
ListObjectsViewTestCase
¶
Bases: APITestCase
get_depth_fields()
¶
Get a list of model fields that could be tested with the ?depth query parameter
test_list_objects()
¶
GET a list of objects as an authenticated user with permission to view the objects.
test_list_objects_anonymous()
¶
GET a list of objects as an unauthenticated user.
test_list_objects_csv()
¶
GET a list of objects in CSV format as an authenticated user with permission to view some objects.
test_list_objects_depth_0()
¶
GET a list of objects using the "?depth=0" parameter.
test_list_objects_depth_1()
¶
GET a list of objects using the "?depth=1" parameter.
test_list_objects_filtered()
¶
GET a list of objects filtered by ID.
test_list_objects_unknown_filter_no_strict_filtering()
¶
GET a list of objects with an unknown filter parameter and no strict filtering, expect it to be ignored.
test_list_objects_unknown_filter_strict_filtering()
¶
GET a list of objects with an unknown filter parameter and strict filtering, expect a 400 response.
test_list_objects_without_permission()
¶
GET a list of objects as an authenticated user without the required permission.
test_options_objects()
¶
Make an OPTIONS request for a list endpoint.
NotesURLViewTestCase
¶
TreeModelAPIViewTestCaseMixin
¶
Test ?depth=2
query parameter for TreeModel
test_list_objects_depth_2()
¶
GET a list of objects using the "?depth=2" parameter. TreeModel Only
UpdateObjectViewTestCase
¶
Bases: APITestCase
test_bulk_update_objects()
¶
PATCH a set of objects in a single request.
test_get_put_round_trip()
¶
GET and then PUT an object and verify that it's accepted and unchanged.
test_options_returns_expected_choices()
¶
Make an OPTIONS request for a list endpoint and validate choices match expected choices for serializer.
test_update_object()
¶
PATCH a single object identified by its ID.
test_update_object_without_permission()
¶
PATCH a single object without permission.
nautobot.apps.testing.FilterTestCases
¶
BaseFilterTestCase
¶
Bases: TestCase
Base class for testing of FilterSets.
get_filterset_test_values(field_name, queryset=None)
¶
Returns a list of distinct values from the requested queryset field to use in filterset tests.
Returns a list for use in testing multiple choice filters. The size of the returned list is random but will contain at minimum 2 unique values. The list of values will match at least 2 instances when passed to the queryset's filter(field_name__in=[]) method but will fail to match at least one instance.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
field_name |
str
|
The name of the field to retrieve test values from. |
required |
queryset |
QuerySet
|
The queryset to retrieve test values. Defaults to |
None
|
Returns:
Type | Description |
---|---|
list
|
A list of unique values derived from the queryset. |
Raises:
Type | Description |
---|---|
ValueError
|
Raised if unable to find a combination of 2 or more unique values to filter the queryset to a subset of the total instances. |
FilterTestCase
¶
Bases: BaseFilterTestCase
Add common tests for all FilterSets.
get_q_filter()
¶
Helper method to return q filter.
test_boolean_filters_generic()
¶
Test all RelatedMembershipBooleanFilter
filters found in self.filterset.get_filters()
except for the ones with custom filter logic defined in its method
attribute.
This test asserts that filter=True
matches self.queryset.filter(field__isnull=False)
and
that filter=False
matches self.queryset.filter(field__isnull=True)
.
test_filters_generic()
¶
Test all multiple choice filters declared in self.generic_filter_tests
.
This test uses get_filterset_test_values()
to retrieve a valid set of test data and asserts
that the filterset filter output matches the corresponding queryset filter.
The majority of Nautobot filters use conjoined=False, so the extra logic to support conjoined=True has not
been implemented here. TagFilter and similar "AND" filters are not supported.
Examples:
Multiple tests can be performed for the same filter by adding multiple entries in
generic_filter_tests
with explicit field names.
For example, to test a NaturalKeyOrPKMultipleChoiceFilter, use:
generic_filter_tests = (
["filter_name", "field_name__name"],
["filter_name", "field_name__id"],
)
If a field name is not declared, the filter name will be used for the field name:
generic_filter_tests = (
["devices"],
)
This expects a field named devices
on the model and a filter named devices
on the filterset.
test_id()
¶
Verify that the filterset supports filtering by id.
test_invalid_filter()
¶
Verify that the filterset reports as invalid when initialized with an unsupported filter parameter.
test_q_filter_exists()
¶
Test the q
filter exists on a filterset, does not validate the filter works as expected.
test_q_filter_valid()
¶
Test the q
filter based on attributes in filter_predicates
.
test_tags_filter()
¶
Test the tags
filter which should be present on all PrimaryModel filtersets.
NameOnlyFilterTestCase
¶
Bases: FilterTestCase
Add simple tests for filtering by name.
test_name()
¶
Verify that the filterset supports filtering by name.
NameSlugFilterTestCase
¶
Bases: NameOnlyFilterTestCase
Add simple tests for filtering by name and by slug.
test_slug()
¶
Verify that the filterset supports filtering by slug.
nautobot.apps.testing.FormTestCases
¶
BaseFormTestCase
¶
Bases: TestCase
Base class for generic form tests.
nautobot.apps.testing.ModelTestCase
¶
nautobot.apps.testing.ModelTestCases
¶
BaseModelTestCase
¶
Bases: NautobotTestCaseMixin
, TestCase
Base class for generic model tests.
nautobot.apps.testing.ModelViewTestCase
¶
Bases: ModelTestCase
Base TestCase for model views. Subclass to test individual views.
reverse_url_attribute = None
class-attribute
instance-attribute
¶
Name of instance field to pass as a kwarg when looking up URLs for creating/editing/deleting a model instance.
If unspecified, "pk" and "slug" will be tried, in that order.
nautobot.apps.testing.NautobotDataMigrationTest
¶
Bases: TestCase
populateDataBeforeMigration(installed_apps)
¶
Populate your Nautobot data before migrating from the first migration to the second
nautobot.apps.testing.NautobotTestCaseMixin
¶
Base class for all Nautobot-specific unit tests.
absolute_api_url(obj)
¶
Get the absolute API URL ("http://nautobot.example.com/api/...") for a given object.
add_permissions(*names)
¶
Assign a set of permissions to the test user. Accepts permission names in the form
assertHttpStatus(response, expected_status, msg=None)
¶
TestCase method. Provide more detail in the event of an unexpected HTTP response.
assertInstanceEqual(instance, data, exclude=None, api=False)
¶
Compare a model instance to a dictionary, checking that its attribute values match those specified in the dictionary.
:param instance: Python object instance :param data: Dictionary of test data used to define the instance :param exclude: List of fields to exclude from comparison (e.g. passwords, which get hashed) :param api: Set to True is the data is a JSON representation of the instance
assertQuerysetEqualAndNotEmpty(qs, values, *args, **kwargs)
¶
Wrapper for assertQuerysetEqual with additional logic to assert input queryset and values are not empty
create_tags(*names)
classmethod
¶
Create and return a Tag instance for each name given.
DEPRECATED: use TagFactory instead.
model_to_dict(instance, fields, api=False)
¶
Return a dictionary representation of an instance.
prepare_instance(instance)
¶
Test cases can override this method to perform any necessary manipulation of an instance prior to its evaluation against test data. For example, it can be used to decrypt a Secret's plaintext attribute.
setUpNautobot(client=True, populate_status=False)
¶
Setup shared testuser, statuses and client.
tearDown()
¶
Clear cache after each test case.
In theory this shouldn't be necessary as our cache should appropriately update and clear itself when
data changes occur, but in practice we've seen issues here. Best guess at present is that it's due to
TransactionTestCase
truncating the database, which presumably doesn't trigger the relevant Django signals
that would otherwise refresh the cache appropriately.
See also: https://code.djangoproject.com/ticket/11505
nautobot.apps.testing.NautobotTestClient
¶
Bases: APIClient
Base client class for Nautobot testing.
DO NOT USE THIS IN PRODUCTION NAUTOBOT CODE.
__init__(*args, **kwargs)
¶
Default the SERVER_NAME to "nautobot.example.com" rather than Django's default "testserver".
This matches the ALLOWED_HOSTS set in nautobot/core/tests/nautobot_config.py and helps to protect us against issues like https://github.com/nautobot/nautobot/issues/3065.
nautobot.apps.testing.OpenAPISchemaTestCases
¶
BaseSchemaTestCase
¶
Bases: TestCase
Base class for testing of the OpenAPI schema.
assert_component_mapped_by_object_type(schema, models)
¶
Test method to assert that this polymorphic component has the expected permitted types.
assert_not_nullable_property(component_schema, property_name)
¶
Test method to assert that the given component property is marked as non-nullable.
assert_not_read_only_property(component_schema, property_name)
¶
Test method to assert that the given component property is not marked as read-only.
assert_nullable_property(component_schema, property_name)
¶
Test method to assert that the given component property is marked as nullable.
assert_read_only_property(component_schema, property_name)
¶
Test method to assert that the given component property is marked as read-only.
get_component_schema(component_name, api_version=None)
¶
Helper method to pull a specific component schema from the larger OpenAPI schema already loaded.
get_property_ref_component_name(component_schema, property_name)
¶
Helper method to identify a component referenced by the given property of the current component.
get_schema_property(component_schema, property_name)
¶
Helper method to pull a specific property schema from a larger component schema already extracted.
validate_polymorphic_property(component_name, property_name, models=None, nullable=False, read_only=True, many=False)
¶
Bringing it all together.
This validates the schema to show that:
- The component exists and has such a property
- The property has the correct nullable
and readOnly
values
- The property has the correct multiplicity
- The property is a reference to another component
- The property's referenced component is polymorphic and has the expected set of model content-types.
Returns:
Type | Description |
---|---|
Tuple[ref_component_name, ref_component_schema]
|
The referenced component's name and schema. |
nautobot.apps.testing.SeleniumTestCase
¶
Bases: StaticLiveServerTestCase
, NautobotTestCaseMixin
Base test case for Splinter Selenium integration testing with custom helper methods.
This extends django.contrib.staticfiles.testing.StaticLiveServerTestCase
so there is no need to run collectstatic
prior to running tests.
nautobot.apps.testing.TestCase
¶
Bases: NautobotTestCaseMixin
, TestCase
Base class for all Nautobot-specific unit tests.
setUp()
¶
Initialize user and client.
nautobot.apps.testing.TransactionTestCase
¶
Bases: NautobotTestCaseMixin
, TransactionTestCase
Base test case class using the TransactionTestCase for unit testing
setUp()
¶
Provide a clean, post-migration state before each test case.
django.test.TransactionTestCase truncates the database after each test runs. We need at least the default statuses present in the database in order to run tests.
nautobot.apps.testing.ViewTestCases
¶
We keep any TestCases with test_* methods inside a class to prevent unittest from trying to run them.
BulkDeleteObjectsViewTestCase
¶
Bases: ModelViewTestCase
Delete multiple instances.
get_deletable_object_pks()
¶
Get a list of PKs corresponding to objects that can be safely bulk-deleted.
For some models this may just be any random objects, but when we have FKs with on_delete=models.PROTECT
(as is often the case) we need to find or create an instance that doesn't have such entanglements.
BulkEditObjectsViewTestCase
¶
Bases: ModelViewTestCase
Edit multiple instances.
:bulk_edit_data: A dictionary of data to be used when bulk editing a set of objects. This data should differ from that used for initial object creation within setUpTestData().
BulkImportObjectsViewTestCase
¶
Bases: ModelViewTestCase
Vestigial test case, to be removed in 3.0.
This is vestigial since the introduction of the ImportObjects system Job to handle bulk-import of all content-types via REST API serializers. The parsing of CSV data by the serializer is exercised by APIViewTestCases.CreateObjectViewTestCase.test_recreate_object_csv(), and the basic operation of the Job is exercised by nautobot.core.tests.test_jobs.
BulkRenameObjectsViewTestCase
¶
CreateMultipleObjectsViewTestCase
¶
Bases: ModelViewTestCase
Create multiple instances using a single form. Expects the creation of three new instances by default.
:bulk_create_count: The number of objects expected to be created (default: 3). :bulk_create_data: A dictionary of data to be used for bulk object creation.
CreateObjectViewTestCase
¶
Bases: ModelViewTestCase
Create a single new instance.
:form_data: Data to be used when creating a new object.
DeleteObjectViewTestCase
¶
Bases: ModelViewTestCase
Delete a single instance.
get_deletable_object()
¶
Get an instance that can be deleted.
For some models this may just be any random object, but when we have FKs with on_delete=models.PROTECT
(as is often the case) we need to find or create an instance that doesn't have such entanglements.
DeviceComponentTemplateViewTestCase
¶
Bases: EditObjectViewTestCase
, DeleteObjectViewTestCase
, CreateMultipleObjectsViewTestCase
, BulkEditObjectsViewTestCase
, BulkRenameObjectsViewTestCase
, BulkDeleteObjectsViewTestCase
TestCase suitable for testing device component template models (ConsolePortTemplates, InterfaceTemplates, etc.)
DeviceComponentViewTestCase
¶
Bases: GetObjectViewTestCase
, GetObjectChangelogViewTestCase
, GetObjectNotesViewTestCase
, EditObjectViewTestCase
, DeleteObjectViewTestCase
, ListObjectsViewTestCase
, CreateMultipleObjectsViewTestCase
, BulkEditObjectsViewTestCase
, BulkRenameObjectsViewTestCase
, BulkDeleteObjectsViewTestCase
TestCase suitable for testing device component models (ConsolePorts, Interfaces, etc.)
EditObjectViewTestCase
¶
Bases: ModelViewTestCase
Edit a single existing instance.
:form_data: Data to be used when updating the first existing object.
GetObjectChangelogViewTestCase
¶
GetObjectNotesViewTestCase
¶
GetObjectViewTestCase
¶
ListObjectsViewTestCase
¶
Bases: ModelViewTestCase
Retrieve multiple instances.
test_list_objects_unknown_filter_no_strict_filtering()
¶
Verify that without STRICT_FILTERING, an unknown filter is ignored.
test_list_objects_unknown_filter_strict_filtering()
¶
Verify that with STRICT_FILTERING, an unknown filter results in an error message and no matches.
test_list_view_app_banner()
¶
If example app is installed, check if the app banner is rendered correctly in ObjectListView.
OrganizationalObjectViewTestCase
¶
Bases: GetObjectViewTestCase
, GetObjectChangelogViewTestCase
, GetObjectNotesViewTestCase
, CreateObjectViewTestCase
, EditObjectViewTestCase
, DeleteObjectViewTestCase
, ListObjectsViewTestCase
, BulkDeleteObjectsViewTestCase
TestCase suitable for all organizational objects
PrimaryObjectViewTestCase
¶
Bases: GetObjectViewTestCase
, GetObjectChangelogViewTestCase
, GetObjectNotesViewTestCase
, CreateObjectViewTestCase
, EditObjectViewTestCase
, DeleteObjectViewTestCase
, ListObjectsViewTestCase
, BulkEditObjectsViewTestCase
, BulkDeleteObjectsViewTestCase
TestCase suitable for testing all standard View functions for primary objects
nautobot.apps.testing.create_job_result_and_run_job(module, name, source='local', *args, **kwargs)
¶
Test helper function to call get_job_class_and_model() then call run_job_for_testing().
nautobot.apps.testing.create_test_user(username='testuser', permissions=None)
¶
Create a User with the given permissions.
nautobot.apps.testing.disable_warnings(logger_name)
¶
Temporarily suppress expected warning messages to keep the test output clean.
nautobot.apps.testing.extract_form_failures(content)
¶
Given decoded HTML content from an HTTP response, return a list of form errors.
nautobot.apps.testing.extract_page_body(content)
¶
Given raw HTML content from an HTTP response, extract the main div only.
...
nautobot.apps.testing.generate_random_device_asset_tag_of_specified_size(size)
¶
For testing purposes only; it returns a random string of size 100 consisting of letters and numbers.
nautobot.apps.testing.get_deletable_objects(model, queryset)
¶
Returns a subset of objects in the given queryset that have no protected relationships that would prevent deletion.
nautobot.apps.testing.get_job_class_and_model(module, name, source='local')
¶
Test helper function to look up a job class and job model and ensure the latter is enabled.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
module |
str
|
Job module name |
required |
name |
str
|
Job class name |
required |
source |
str
|
Job grouping (default: "local") |
'local'
|
Returns:
Type | Description |
---|---|
JobClassInfo
|
Named 2-tuple of (job_class, job_model) |
nautobot.apps.testing.post_data(data)
¶
Take a dictionary of test data (suitable for comparison to an instance) and return a dict suitable for POSTing.
nautobot.apps.testing.run_job_for_testing(job, username='test-user', profile=False, **kwargs)
¶
Provide a common interface to run Nautobot jobs as part of unit tests.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
job |
Job
|
Job model instance (not Job class) to run |
required |
username |
str
|
Username of existing or to-be-created User account to own the JobResult. |
'test-user'
|
profile |
bool
|
Whether to profile the job execution. |
False
|
Other Parameters:
Name | Type | Description |
---|---|---|
**kwargs |
any
|
Input keyword arguments for Job run method. |
Returns:
Type | Description |
---|---|
JobResult
|
representing the executed job |