How To Use Django.test.TestCase for Unit Tests

by Owais Mushtaq

Test Case

If an application for which we are writing unit tests relies on database access for creating models or querying them then we should use test classes as subclasses of django.test.TestCase. The issue with using unittest.TestCase is that it avoids cost of running each test in a transaction, but if your tests interact with the database their behavior will vary based on the order that test runner executes them. This can lead to unit tests that pass when run in isolation but fail when run in a suite. In case of django.test.TestCase each TestCase is built in isolation with other TestCases and every time a new TestCase is built, database (test database) is flushed.

# Import libraries
from app.models import xxxx
from django.test import TestCase
class ClassNameTest(TestCase):
    #Unit test class definition
    @classmethod
        """With classmethods,
           the class of the object instance is implicitly passed as
           the first argument instead of self."""
    def setUpClass(self):
        """here we define all the prerequisites or set up data that
           are required for most of  test units"""
        code block goes here...

    def test_search_name_first(self):
        # test case
        code block goes here ...

        assertion methods ....

Test:

Default behavior of test utility is to find all the test cases that is/are subclasses of unittest.TestCase Class. Test case should always be pre-fixed with test and then unittest name or testcase name. TestCase automatically builds a test suite out of these test cases, and runs that suite. We can define test case as follows:

1. test_sumnumber(self):
     code goes here…
     assertion methods ...
2. testsumnumber(self):
     code goes here ...
     assertion methods ....

Note that we have defined each of the test cases above starting with word test so that unittest.TestCase will find the test case and build test suit for the particular test case. That is, if there is no test word before method, it will not be considered as a test case, rather a simple method.

Order of Execution: The django test cases are run in dictionary order. For example:

  1. test_zip_test_case(self)
  2. test_yen_test_case(self)
  3. test_app_test_case(self)

setUp:

We know that django.test.TestCase flushes the test database every time a new TestCase is to be executed. So there is a need for some technique that will initialize common data in database, which is required for most TestCases in the testsuite. SetUp utility helps us here. The behavior of setUp is to execute every time when a test case is to be built. SetUpClass above is a setUp utility and will be executed before every test case is executed. Let us take the above example, before test case test_app_test_case(self) will be executed setUpClass will  be executed and after test database is cleared for next test case, if we have  made some database transactions either in setUpClass or in test case method.

Implementation Example:

Let UserInstanceResource and UserListResource as our api’s to be implemented on Unit Test.

1="django.test" 2="import" 3="TestCase" 4="import" 5="unittest" 6="from" 7="cuser.api" 8="import" 9="UserListResource" 10="from" 11="cuser.api" 12="import" 13="UserInstanceResource" 14="class" 15="UserInstanceResourceTest(TestCase):" 16="@classmethod" 17="def" 18="setUpClass(self):" 19="'''prerequisite's" 20="to" 21="test" 22="user" 23="'''" email="owais@trialx.com" first_name="owais" last_name="mushtaq" password="test123" user_obj="UserInstanceResource()._get(id=1)" 24="def" 25="test_user_get(self):" 26="'''get" 27="the" 28="user" 29="with" 30="id" 31="'''" user="UserInstanceResource()._get(id=1)" 32="self.assertEqual(user.email,'owais@trialx.com')" 33="self.assertEqual(user.first_name,'owais')" 34="self.assertEqual(user.last_name,'mushtaq')" 35="def" 36="test_user_update(self):" 37="'''get" 38="the" 39="password" 40="for" 41="user" 42="updated" 43="'''" pre_pass="user_obj.password" 44="user=UserInstanceResource()._update(id=1,password='owais')" nw_pwd="user.password" 45="self.assertNotEqual(nw_pwd,pre_pass)" 46="self.assertEqual(user.email,'owais@trialx.com')" 47="self.assertEqual(user.first_name,'owais')" 48="self.assertEqual(user.last_name,'mushtaq')" language="[from"]

On running the above example in terminal we may come across following cases,

Case 1:

If all tests are working, the best case would be,

(env_project)owais@owais-Inspiron-3537:~/Desktop/workspace/test_proj$ python manage.py test user --settings= test_proj.test_settings</b><b>
</b><b>
</b><b>Creating test database for alias 'default'...</b><b>
</b><b>
</b><b>..</b><b>
</b><b>
</b><b>----------------------------------------------------------------------</b><b>
</b><b>
</b><b>Ran 2 tests in 0.003s
</b><b>OK Destroying test database for alias 'default'...

Case 2:

If there is any failure,

(env_project)owais@owais-Inspiron-3537:~/Desktop/workspace/test_proj$ python manage.py test user --settings= test_proj.test_settings</b><b>
</b><b>
</b><b>Creating test database for alias 'default'...</b><b>
</b><b>
</b><b>.F</b><b>
</b><b>
</b><b>======================================================================</b><b>
</b><b>
</b><b>FAIL: test_user_update (test_proj.test.UserInstanceResourceTest)</b><b>
</b><b>
</b><b>get the password for user updated</b><b>
</b><b>
</b><b>----------------------------------------------------------------------</b><b>
</b><b>
</b><b>Traceback (most recent call last):</b><b>
</b><b>
</b><b>  File "/home/owais/Desktop/workspace/test_proj/apps/cuser/test.py", line 35, in test_user_update</b><b>
</b><b>
</b><b>     self.assertNotEqual(nw_pwd,pre_pass)</b><b>
</b><b>
</b><b>AssertionError: u'test123' == 'test123'
</b><b>---------------------------------------------------------------------- Ran 2 tests in 0.004s
</b><strong><b>FAILED (failures=1) Destroying test database for alias 'default'...

In the above sections,  we have seen why TestCase is used, the main aim of using SetUp, @classmethod, and how to write and define a testcase. In the next blog we will take a look at using Autofixtures in Unit Tests.

Leave a Reply

Your email address will not be published. Required fields are marked *

Tools & Practices

Tools and Technologies we use at Applied

Contact us now

Popular Posts