Search code examples
djangodjango-viewsdjango-testing

Django View Testing Returning 301 or not found


I'm trying to test the response code of a view, but I'm either getting a 301 or does not exist.

urls.py

...
url(r'^myview/(?P<view_id>.*)/$', view_myview.index, name='myview'),
...

Test code 1:

import unittest
from django.test import Client

class SimpleTest(unittest.TestCase):
    def setUp(self):
        self.client = Client()
    def test_details(self):
        response = self.client.get('/myview/123')
        self.assertEqual(response.status_code, 200)

The above code gives:

AssertionError: 301 != 200

Test code 2:

import unittest
from django.test import Client

class SimpleTest(unittest.TestCase):
    def setUp(self):
        self.client = Client()
    def test_details(self):
        response = self.client.get('/myview/123/')
        self.assertEqual(response.status_code, 200)

The above code gives:

Mymodel matching query does not exist.

All I want to do is simple testing of my views to ensure they aren't throwing an error code, but I can't seem to find the right way to do it and I've tried many, many suggestions from the internets. Is there a different way to pass in view_id? What if I also want to throw in some query parameters?

EDIT: Updating to show the workaround I've used to accomplish what I'm trying to do, as horrible as it may be. I found that using dumpdata and fixtures took FOREVER.

from django.test import TestCase
from django.test import Client
import os
from . import urls_to_test    # just a simple list of strings

class SimpleTest(TestCase):
    """ Simply test if views return status 200 """
    def setUp(self):
        self.client = Client()
        print('Dumping production database...')
        os.system("sudo mysqldump mydb > /tmp/mydb.sql")
        print('Loading production data into test database...')
        os.system("sudo mysql test_mydb < /tmp/mydb.sql")
        os.system("sudo rm -rf /tmp/mydb.sql")
    def test_details(self):
        for u in urls_to_test.test_urls:
            print('Testing {}'.format(u))
            response = self.client.get(u)
            self.assertEqual(response.status_code, 200)
        print('{} URLs tested!'.format(len(urls_to_test.test_urls)))

Solution

  • The first one doesn't work because Django is redirecting to the version with a final slash.

    The second one tells you exactly why it doesn't work: you haven't created an item with id 123 - or indeed any items at all - within the test.