HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythondjangoMinor

Test Driven Development with Django

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
djangowithdevelopmenttestdriven

Problem

I'm learning TDD with Django and currently I'm testing my CreateView class. I feel like I'm not using best practices but am not sure on how to improve my code.

test_reservation_create.py

```
from django.test import TestCase
from django.urls import reverse

from reservations.models import Reservation
from src.factories import UserFactory, GroupFactory, ProfileFactory, TagFactory

class TestCreateReservation(TestCase):

def setUp(self):
persona = UserFactory(groups=(GroupFactory.create(),))

ProfileFactory(user=persona, )
persona.profile.tags.add(TagFactory())

def test_create_view_denies_anonymous(self):
response = self.client.get(reverse('reservation-create'), follow=True)
self.assertRedirects(response, '/login?next=/r/create/')

def test_loads_template_for_user(self):
self.client.login(username='john', password='defaultpassword')
response = self.client.get(reverse('reservation-create'))
self.assertEquals(response.status_code, 200)

def test_create_blank_for_user(self):
self.client.login(username='john', password='defaultpassword')
data = {
'stops-TOTAL_FORMS': u'2',
'stops-INITIAL_FORMS': u'0',
'stops-MIN_NUM_FORMS': u'0',
'stops-MAX_NUM_FORMS': u'1000',
'stops-0-id': u'',
}
response = self.client.post(reverse('reservation-create'), data=data)
self.assertFormError(response,'form','passenger_name','This field is required.')
self.assertFormError(response,'form','passenger_lastname','This field is required.')
self.assertFormError(response,'form','service_date','This field is required.')
self.assertFormError(response,'form','author_alias','This field is required.')

def test_formset_validation(self):
self.client.login(username='john', password='defaultpassword')
data = {
'stops-TOTAL_FORMS': u'2',
'stops-INITIAL_FORMS':

Solution

The code has a lot of repetitive blocks, a test flow is mixed up with the data and the logic making it difficult to follow, the number of different assertions makes the tests bigger and more complicated.

I think you should have a much more readable code if you would switch to "data-driven tests" with "parameterized tests" (e.g. there is a built-in support in pytest) or take a look at the ddt package.

Also, instead of checking multiple model fields with multiple asserts, try dumping the model to, for example, a dictionary and compare it with a desired dictionary - basically this way you would check all the fields at once. Of course, in this case, in case of a failure, the output would be less clear, but if you have a good test runner like nose or pytest, this should not be a problem for the number of fields we are talking about.

Other notes:

  • the user credentials should probably be moved to a single place - to a config file for your tests. This way, if they change, we would need to change it in a single place instead of looking for them in multiple places in the code.



  • think about splitting your test case into multiple test cases - e.g. one for access control, the other for validation tests etc.

Context

StackExchange Code Review Q#154863, answer score: 4

Revisions (0)

No revisions yet.