Home > Mobile >  Django Unit Testing - How to test all instances in a model?
Django Unit Testing - How to test all instances in a model?

Time:10-19

I want to test all instances in a DB using Django.

I have a python script that populates the DB and I want to test every single instance if it pass the test.

I provide here a dummy tests.py:

from django.test import TestCase
from app_core.models import Item
# Item model fields are: pk, first, second

class PairTestCase(TestCase):
    def setUp(self):
        # This script populates the DB creating several Item instances
        from app_core.init import init_items

    def test_pair_elems_different(self):
        """First and second fields MUST be different inside the instance"""
        item = Item.objects.get(pk=1)
        self.assertNotEqual(item.first, item.second)

As you can see, I just tested a single instance. Let's suppose the DB contains 1000 Item instances, what is the best way to test them all?

The only solution that pops up in my mind is using a simple FOR loop inside test_pair_elems_different, iterating all object and comparing each instance.

Is this approach correct in the context of unit testing best practices/principles?

CodePudding user response:

I think you're looking at this the wrong way around.

You want to ensure first != second, right? Presumably you have a constraint on the model and it's this you're testing.

What you want is a test that tries to add a record where these 2 fields are equal, then test that this attempt raises the approriate constraint error.

I'm more of a pytest person myself, but I think the standard unittest framework uses assertRaises for this.

When you've validated that adding a record with equal values is not allowed, there is no need to go and test every instance.

CodePudding user response:

You could do something like this. Annotate a Column of if those two fields are equal and then filter by it.
This in fact would test every single item, but it wouldn't give you an error like Item <230> failed validation, but it'll give you a general Items Failed

from django.db.models import Q, F,  ExpressionWrapper, BooleanField

countOfEqual = Item.objects.annotate(
  equal=ExpressionWrapper(
    Q(first=F('second')),
    output_field=BooleanField()
)).filter(equal=True).count()

self.assertEqual(countOfEqual, 0, '{0} Items have matching first & second. This should be 0'.format(countOfEqual))

If you did want specific items that failed you could at least chop off the .count() and filter through the list- this would cut down on time as you're only looping through items you already know are bad

  • Related