-
Notifications
You must be signed in to change notification settings - Fork 81
Best practices for back end testing
Django Views are really hard to unit test, because they rely on many variables. The Django guides recommend to test views by sending a request using the test client; it's a good approach but it's also slowing down tests.
Here's a slightly alternative approach, which is quicker.
- Test if the URL name space reverses to the correct URL.
- Test if the URL is linked to the correct View. Simply compare the class names of the expected view and the one that was actually resolved.
# test_urls.py
def test_password_reset(self):
# test if the URL name space reverses to the correct URL
actual = reverse('accounts:password_reset')
expected = '/account/password/reset/'
self.assertEqual(actual, expected)
# test if the URL is linked to the correct view
resolved = resolve('/account/password/reset/')
actual = resolved.func.__name__
expected = views.PasswordReset.__name__
self.assertEqual(actual, expected)
- Create a request using Django REST Frameworks APIRequestFactory
- Render the response using the View directly
- Run assertions against the response
def test_view(self)
# create the request
request = APIRequestFactory().post('/account/activate/', {
'uid': encode_uid(user.pk),
'token': token
})
# Render the response using the view
response = AccountVerify.as_view()(request).render()
# Assert the response
self.assertEqual(response.status_code, 200)
self.assertIn('some content', response.content.decode("utf-8"))
PR #514 changed the handling of files in tests: Files that were created during a test are always removed after the test. That way, we make sure that a file created in one test does not affect another test. For instance, there were cases where a test just passed because a file required for the test was still available from another test.
To make this possible, I created a pytest fixture that creates all necessary directories before a test and removes these directories after the test. (Here's how pytest fixtures work).
You should use the same fixture whenever you write a test that writes files to the file system.
from core.tests.util import make_dirs # noqa
@pytest.mark.usefixtures('make_dirs')
class ResourcesTest(UserTestCase):
def test_somthing(self):
# write a bunch of files
Import make_dirs
from core.tests.util
and apply the fixture to a test class, which uses the file system by using the decorator @pytest.mark.usefixtures('make_dirs')
. The fixture creates all directories required by FakeS3Storage
by default. If for some reason, you need to write to a different directory, you can either create it inside the test:
from buckets.utils import ensure_dirs
from core.tests.util import make_dirs # noqa
@pytest.mark.usefixtures('make_dirs')
class ResourcesTest(UserTestCase):
def test_somthing(self):
ensure_dirs('my/special_dir', 'another/special/dir')
Or you add the directory to the fixture itself if it is required in a significant number of different tests.
Some tests also write files to a temporary directory (temp
), e.g. when an image is uploaded the image is downloaded from S3 and the post-processed to create the thumbnail. In this case, you should also add a fixture that removes the temp
directory after the test:
from resources.tests.utils import clear_temp # noqa
@pytest.mark.usefixtures('clear_temp')
class ResourcesTest(UserTestCase):
def test_somthing(self):
pass
Visit our User Documentation to learn more about using the Cadasta Platform.
If you'd like to contribute to the Cadasta Platform, start with our Contributing Guidelines.
Cadasta Wiki Home | Developer Setup Guide
Cadasta.org | About Cadasta | YouTube | Twitter | Facebook
- Installing & Running
- Contributing
- Planning & Sprints
- Platform Development
- Testing
- Utilities
- Outreachy
- Platform Site Map
- User Flows and Wireframes
- Other
- Quick Start Guide
- Glossary
- Questionnaire Guide