Testing utils for Django-based projects
Project description
Django-testing-utils
Django-Testing-Utils is a package providing test helpers for django app testing.
Installation
pip install django-testing-utils
Usage
TestCase metaclass
Django 3.2 introduces setUpTestData attributes isolation, but django-testing-utils has slightly different way of resetting class attributes between tests. It collects all django model objects created in any TestCase class method and runs refresh_from_db() when necessary. It also clears fields_cache for such objects.
from django_testing_utils import mixins
from testproject.testapp import models
class SomeTestCase(mixins.BaseTestCase):
""" Some test case that uses django models."""
@classmethod
def setUpTestData(cls):
super().setUpTestData()
# In large code django docs recommend to create common objects in
# this method to speedup tests setup by reusing objects in db.
cls.project = models.Project.objects.create(name='project')
def test_something(self):
# in this test self.project instance is independent from other tests
...
Time mocking
There are multiple ways to freeze time in tests:
- ad-hoc mocking with
unittest.mock
- freezegun library
- any system approach that puts working with time in order
django-testing-utils provides a way to use last approach in test with some limitations:
- Project code must work with
django.utils.timezone
methods only - All tests should inherit
TimeMixin
from django-testing-utils
This leads to a systematic way of datetime and timezone usage in the project and it's tests.
from django.test import TestCase
from django_testing_utils.mixins import TimeMixin, second
class MyTimeTestCase(TimeMixin, TestCase):
@classmethod
def setUpTestData(cls):
# time is not mocked here yet
...
def setUp(self) -> None:
# not yet...
super().setUp()
# ... and here time has been frozen to `self.now`
def test_something(self):
# simulate time run
self.now += second
Helpers for django objects
There are some helper methods to work with django objects
update_object
- performs anUPDATE
on django model in a database. This does not affect field values for an object passed to this method.reload
- fetches a new model instance from a database via primary key.assert_object_fields
fetches an actual version from a database and compares all fields with values passed as named arguments
from django_testing_utils.mixins import BaseTestCase
from testapp import models
class MyTimeTestCase(BaseTestCase):
def test_something(self):
obj = models.Project.objects.create()
# change something in db
self.update_object(obj, name='new')
# fetch updated version
new = self.reload(obj)
# old object is untouched
self.assertNotEqual(new.name, obj.name)
# you could fetch and object and compare some fields in a single call
self.assert_object_fields(obj, name='new')
Decorators
-
override_defaults
- a test case/test method decorator to change default values that are stored inapp.defaults
module. The idea ofapp.defaults
is to reduce a number of rarely changed variables in django settings module by moving it to application-specific settings -
disable_patcher
- a context manager / decorator to temporarily disable someunittest.patch
instances defined in TestCase instance. This breaks open/close principle but allows postponing tests refactoring when some mocks are too generic.
from django.test import TestCase
from django.utils import timezone
from django_testing_utils.mixins import TimeMixin
from django_testing_utils.utils import override_defaults, disable_patchers
from testapp import defaults
import testapp
class MyTestCase(TimeMixin, TestCase):
@override_defaults(testapp.__name__, setting_1=42)
def test_setting_value(self):
self.assertEqual(defaults.setting_1, 42)
@disable_patchers('now_patcher')
def test_real_time(self):
# now patcher from TimeMixin is now disabled
with disable_patchers(self.timezone_datetime_patcher):
# timezone.datetime patcher is not also disabled
self.assertNotEqual(timezone.now(), timezone.now())
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file django-testing-utils-0.7.0.tar.gz
.
File metadata
- Download URL: django-testing-utils-0.7.0.tar.gz
- Upload date:
- Size: 9.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.0.0 CPython/3.12.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | c1eceeede958249bdc5a1fc264786fc59c6e026954dbafcb97bc9c514ee33f9b |
|
MD5 | b65c096822f1e25d3c584c11a995ae89 |
|
BLAKE2b-256 | bcb35af395b4dc45889c285693554b5f4ba50d4bd6c4e90d40d20466dd9f90a8 |
File details
Details for the file django_testing_utils-0.7.0-py3-none-any.whl
.
File metadata
- Download URL: django_testing_utils-0.7.0-py3-none-any.whl
- Upload date:
- Size: 8.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.0.0 CPython/3.12.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 70c67b82cdb35fd49ef3b0a63ad6c97f41516449933189e413ab88693841ae42 |
|
MD5 | 81d36976bbc507a935674791d6c477ab |
|
BLAKE2b-256 | f365d087afdf9a18a216e9f6a70f829bece704d89399b98ebbbea2a6adfe6d85 |