C4X
C4X

Reputation: 123

Should model fields be tested in Django?

class Author(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    date_of_birth = models.DateField(null=True, blank=True)
    date_of_death = models.DateField('Died', null=True, blank=True)

MDN says:

You don't need to explicitly test that first_name and last_name have been stored properly as CharField in the database because that is something defined by Django ... However you should check the text used for the labels (First name, Last name, Date of birth, Died), and the size of the field allocated for the text (100 chars), because these are part of your design and something that could be broken/changed in future.

If I wanted to follow that advice, I would not write a test that tests that the field only accepts 100 characters, since that would mean testing Django's behavior. Instead, I would write a test that tests that max_length indeed equals 100.
This test could look something like this:

def test_max_length(self):
    self.assertEqual(models.Author._meta.get_field('first_name').max_length, 100)

My feeling is that this test would basically be the same as testing that I wrote what I wrote. Of course, if a wrong max_length breaks some other piece of code, that should be tested, but it should be tested in that other piece of code. What are the best practices for testing Django model fields? Other than the quote from MDN I could only find very general statements along the lines of "Test as much as possible" or "If it can break, you should test it". Specifically, I would be interested in resources or opinions on the thin line between testing code/behavior and configuration. I would also appreciate input on the question whether the number of possible uses that a setting/parameter can have should influence the approach towards testing of that parameter. For example, one could argue that max_length has the sole purpose of defining the maximum length, so it's not going to be changed by accident by a developer following a different goal and inadvertently also changing max_length - you only change max_length if you want to change max_length.

Upvotes: -1

Views: 103

Answers (1)

Chukwujiobi Canon
Chukwujiobi Canon

Reputation: 4089

Write tests so that you will keep things under control. In a small project, this might seem implausible but when things get out of hand, it gets out of hand quickly. It will begin to make more sense then.

A program that is not tested rigorously is likely to be bug ridden. A program that doesn’t have tests is dead.

In a base where multiple developers contribute, that which you think is unnecessary will be indispensable. I’ll give a quick example:

In a model Author, the max_length of Author.first_name is set to 20 because of space constraints. A field that has this maximum value has already been entered into the database so we can’t go any lower because of this field.

def test_max_length(self):
    self.assertEqual(models.Author._meta.get_field('first_name').max_length, 20)

The simple test above will be useful in the following scenarios:

  • A different developer increases the max_length of Author.first_name to allow longer values but does not consider space constraints. The test will fail and if any messages were added, they will know why this requirement is so.
  • Another developer decreases the max_length of Author.first_name to save space but is not aware of the already existing value in the database. The test will also fail and if any messages were added, they will know why this requirement is so.

Ultimately, automated testing is what gives tranquility when there is chaos. [1]


[1] I exaggerated a little.

Upvotes: 0

Related Questions