Django 2.2 Test Driven Development
Tags: python, django, beginners
Published: 2019-05-07 23:20:35

95% into my first Django Website built by yours truly with the help of this <a href="https://www.amazon.com/gp/product/0994616864/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0994616864&linkCode=as2&tag=vagr888-20&linkId=fcc76125667c318f3ab0f253eb86ff5d">book</a> and something came into my mind. Testing.

I recently stumbled upon the words of <a href="https://jacobian.org/">Jacob Kaplan-Moss</a>, one of Django's original creators, "Code without tests is broken as designed." this hit me in a way that I know to my self that I suck at designing, which motivated me to learn how to test.
<h3>"Writing tests is important because it automates the process of confirming that the code works as expected." - <a href="https://djangoforbeginners.com/pages-app/">Django For Beginners</a></h3>
I tried two tests because obviously I had troubles with the first one and was getting an error:
<pre>AssertionError: 301 != 200</pre>
The first test I used was <a href="https://docs.djangoproject.com/en/2.2/topics/testing/tools/#django.test.SimpleTestCase">SimpleTestCase</a>. It is a subclass of <a href="https://docs.python.org/3/library/unittest.html#unittest.TestCase">unittest.TestCase</a> that adds some functionality
<pre>from django.test import SimpleTestCase

class PageTest(SimpleTestCase):

def test_portfolio_page_status_code(self):
    response = self.client.get("/portfolio")
    self.assertEquals(response.status_code, 200)

def test_blog_page_status_code(self):
    response = self.client.get("/blog")
    self.assertEqual(response.status_code, 200)

def test_home_page_status_code(self):
    response = self.client.get("")
    self.assertEquals(response.status_code, 200)

def test_quotes_page_status_code(self):
    response = self.client.get("/quotes/")
    self.assertEquals(response.status_code, 200)
</pre>
but the traceback was:
<pre>======================================================================
FAIL: test_blog_page_status_code (personal_portfolio.tests.PageTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/user/dir/personal_portfolio/tests.py", line 
11, in test_blog_page_status_code
self.assertEqual(response.status_code, 200)
AssertionError: 301 != 200

======================================================================
FAIL: test_portfolio_page_status_code 
(personal_portfolio.tests.PageTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/user/dir/personal_portfolio/tests.py", line 
7, in test_portfolio_page_status_code
self.assertEquals(response.status_code, 200)
AssertionError: 301 != 200
</pre>
I went to StackOverflow to ask for help and this is what I got:
<div class="votecell post-layout--left">
<div class="js-voting-container grid fd-column ai-stretch gs4 fc-black-200"><a href="https://stackoverflow.com/a/56030700/11292732">It is likely that your site does in fact return a <code>301</code> redirect code. This can happen for many reasons, but for example, if it requires authentication and redirects the some other page for that purpose. If so, one fix can be to add a test that logs in and then goes to that page. Without more information about how your site works (and the code) it's hard to determine the cause.</a></div>
</div>
<div></div>
<div></div>
I told myself, there must be another way to test my code. I tested my patience by reading through the article and stumbled upon <a href="https://docs.djangoproject.com/en/2.2/topics/testing/tools/#django.test.TransactionTestCase">TransactionTestCase</a> which inherits from <a href="https://docs.djangoproject.com/en/2.2/topics/testing/tools/#django.test.SimpleTestCase">SimpleTestCase</a> to add some database-specific features.


<div>
<pre>from django.test import TransactionTestCase

class Personal_PortfolioTests(TransactionTestCase):

        def test_home_page_status_code(self):
        response = self.client.get('/')
        self.assertEqual(response.status_code,200)

        def test_portfolio_page_status_code(self):
        response = self.client.get('/portfolio/')
        self.assertEqual(response.status_code,200)

        def test_quotes_page_status_code(self):
        response = self.client.get('/quotes/')
        self.assertEqual(response.status_code,200)

        def test_blog_page_status_code(self):
        response = self.client.get('/blog/')
        self.assertEqual(response.status_code,200)
</pre>
</div>
<h2></h2>
<h2>And viola!</h2>

<img class="alignnone size-full wp-image-247" src="https://highcenburgtech.files.wordpress.com/2019/05/test.png" alt="test" width="567" height="153" />

Django’s <a class="reference internal" title="django.test.TestCase" href="https://docs.djangoproject.com/en/2.2/topics/testing/tools/#django.test.TestCase"><code class="xref py py-class docutils literal notranslate"><span class="pre">TestCase</span></code></a> class is a more commonly used subclass of <code class="docutils literal notranslate"><span class="pre">TransactionTestCase</span></code> that makes use of database transaction facilities to speed up the process of resetting the database to a known state at the beginning of each test. A consequence of this, however, is that some database behaviors cannot be tested within a Django <code class="docutils literal notranslate"><span class="pre">TestCase</span></code> class. For instance, you cannot test that a block of code is executing within a transaction, as is required when using <a class="reference internal" title="django.db.models.query.QuerySet.select_for_update" href="https://docs.djangoproject.com/en/2.2/ref/models/querysets/#django.db.models.query.QuerySet.select_for_update"><code class="xref py py-meth docutils literal notranslate"><span class="pre">select_for_update()</span></code></a>. In those cases, you should use <code class="docutils literal notranslate"><span class="pre">TransactionTestCase</span></code>.


Read more here: https://docs.djangoproject.com/en/2.2/topics/testing/tools/#django.test.TransactionTestCase