Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Nose how to write this test?

I'm completely new to testing in Django. I have started by installing nose and selenium and now I want to test the following code (below) It sends an SMS message.

This is the actual code:

views.py

@login_required
def process_all(request):
    """
    I process the sending for a single or bulk message(s) to a group or single contact.
    :param request:
    """
    #If we had a POST then get the request post values.
    if request.method == 'POST':
        batches = Batch.objects.for_user_pending(request.user)
        for batch in batches:
            ProcessRequests.delay(batch)
            batch.complete_update()

    return HttpResponseRedirect('/reports/messages/')

So where do I start? This is what I have done so far...

1) created a folder called tests and added init.py.

2) created a new python file called test_views.py (I'm assuming that's correct).

Now, how do I go about writing this test?

Could someone show me with an example of how I write the test for the view above?

Thank you :)

like image 468
GrantU Avatar asked Jun 21 '13 10:06

GrantU


1 Answers

First of all, you don't need selenium for testing views. Selenium is a tool for high-level in-browser testing - it's good and useful when you are writing UI tests simulating a real user.

Nose is a tool that makes testing easier by providing features like automatic test discovery, supplies a number of helper functions etc. The best way to integrate nose with your django project is to use django_nose package. All you have to do is to:

  1. add django_nose to INSTALLED_APPS
  2. define TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'

Then, every time you run python manage.py test <project_name> nose will be used to run your tests.


So, speaking about testing this particular view, you should test:

  • login_required decorator work - in other words, unauthenticated user will be redirected to the login page
  • if request.method is not POST, no messages sent + redirect to /reports/messages
  • sending SMS messages when POST method is used + redirect to /reports/messages

Testing first two statements is pretty straight-forward, but in order to test the last statement you need to provide more details on what is Batch, ProcessRequests and how does it work. I mean, you probably don't want to send real SMS messages during testing - this is where mocking will help. Basically, you need to mock (replace with your own implementation on the fly) Batch, ProcessRequests objects. Here's an example of what you should have in test_views.py:

from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.test.client import Client
from django.test import TestCase


class ProcessAllTestCase(TestCase):
    def setUp(self):
        self.client = Client()
        self.user = User.objects.create_user('john', '[email protected]', 'johnpassword')

    def test_login_required(self):
        response = self.client.get(reverse('process_all'))
        self.assertRedirects(response, '/login')

    def test_get_method(self):
        self.client.login(username='john', password='johnpassword')
        response = self.client.get(reverse('process_all'))
        self.assertRedirects(response, '/reports/messages')

        # assert no messages were sent

    def test_post_method(self):
        self.client.login(username='john', password='johnpassword')

        # add pending messages, mock sms sending?

        response = self.client.post(reverse('process_all'))
        self.assertRedirects(response, '/reports/messages')

        # assert that sms messages were sent

Also see:

  • https://docs.djangoproject.com/en/dev/topics/testing/
  • Django Testing Guide
  • Getting Started with Python Mock

Hope that helps.

like image 87
alecxe Avatar answered Nov 15 '22 16:11

alecxe