Source: credited to Toast Driven
Source: credited to Stack Overflow answer
Install coverage using pip.
pip install coverage
Collect modules for testing.
coverage run --source=app1,app2 --omit=*/migrations/* manage.py test
Run coverage report to plan modules for testing.
coverage report -m
Keep tests simple and well organized. Instead of using the test.py
module, create a directory and create a test for each module you'll be testing for. Example below...
app_name
tests
__init__.py
test_forms.py
test_models.py
test_views.py
Imports on the modules must include the app (example below)
from...
from .models import *
to...
from app.models import *
assertEqual(a, b) =
a == b
assertNotEqual(a, b) =
a != b
assertTrue(x) =
bool(x) is True
assertFalse(x) =
bool(x) is False
assertIs(a, b) =
a is b
assertIsNot(a, b) =
a is not b
assertIsNone(x) =
x is None
assertIsNotNone(x) =
x is not None
assertIn(a, b) =
a in b
assertNotIn(a, b) =
a not in b
assertIsInstance(a, b) =
isinstance(a, b)
assertNotIsInstance(a, b) =
not isinstance(a, b)
from django.test import TestCase, Client
from calib_inv.models import Gauge, History
from calib_inv.admin import HistoryAdmin
from calib_inv.views import *
import datetime
class GaugeTest(TestCase):
def setUp(self):
self.gauge = Gauge.objects.create(
serial_number = "123456",
manufacturer = "Test Co.",
description = "Test description text...",
location = "Test, Location",
frequency_of_use = "Infrequently",
calibration_method = "inhouse",
calibration_source = "ENGINEER",
calibration_interval = Gauge.two_years,
)
def test_new_save(self):
interval = self.gauge.calibration_interval
created = self.gauge.created_date.replace(microsecond=0)
last_mod = self.gauge.last_modified.replace(microsecond=0)
self.assertEqual(str(self.gauge.serial_number), "123456")
self.assertEqual(self.gauge.calibration_due_date,
self.gauge.last_calibration
+ datetime.timedelta(days=interval))
self.assertEqual(created, last_mod)
self.assertFalse(self.gauge.out_for_calibration)
self.assertFalse(self.gauge.archived)
def test_exist_save(self):
gauge = Gauge.objects.get(serial_number='123456')
gauge.save()
interval = gauge.calibration_interval
self.assertEqual(gauge.calibration_due_date,
gauge.last_calibration
+ datetime.timedelta(days=interval))
class PageViewsTest(TestCase):
def setUp(self):
self.client = Client()
self.client.force_login(User.objects.get_or_create(
username='testuser')[0])
def matchingAsserts(self, response, page_param):
self.assertEqual(response.status_code, 200)
self.assertIsNotNone(response.context['json_src'])
self.assertTemplateUsed(response, 'base.html')
self.assertTemplateUsed(response, 'lists.html')
self.assertTemplateUsed(response, 'js/gauge_records.html')
self.assertEqual(response.context['page_title'], page_param)
def test_index(self):
response = self.client.get('/calib_inv/')
page_arg = 'All Gauge Calibration Records'
self.matchingAsserts(response, page_arg)
def test_pastdue(self):
response = self.client.get('/calib_inv/past_due/')
page_arg = 'Past Due Gauge Calibration Records'
self.matchingAsserts(response, page_arg)
def test_post_edit_history(self):
post_resp = self.client.post(
'/calib_inv/123456/history/',
data={
'date': datetime.date.today(),
'results': 'tested good!',
'initials': 'JR',
}
)
self.assertRedirects(
post_resp,
'/calib_inv/123456/',
status_code=302,
target_status_code=200
)
def test_admin(self):
obj = History.objects.get(pk=1)
ha_fun = HistoryAdmin.gauge_sn(History, obj)
return_statement = obj.gauge.serial_number
self.assertEqual(ha_fun, return_statement)
Collect module tests to find coverage.
coverage run --source=app1,app2 --omit=*/migrations/* manage.py test
Run coverage report to see coverage.
coverage report -m
If you point the test client at a view that raises an exception, that exception will be visible in the test case. You can then use a standard try ... except block or assertRaises() to test for exceptions.
The only exceptions that are not visible to the test client are Http404, PermissionDenied, SystemExit, and SuspiciousOperation. Django catches these exceptions internally and converts them into the appropriate HTTP response codes. In these cases, you can check response.status_code in your test.