I am trying to test a statistics function, which counts what type of objects I have in my database. For this I would like to create at least one instance of each possible combination of model fields. Random test data requires a lot of test objects to make sure all possible combinations are met.
Here is a shortened example from one of my models:
class Member(models.Model)
is_active = models.BooleanField()
name = models.CharField()
balance = models.IntegerField()
division = models.ForeignKey(Division, on_delete=models.CASCADE)
Class Division(models.Model)
name = models.CharField()
This is how I'm doing it right now using django_dynamic_fixture:
from django.test import TestCase
from django_dynamic_fixture import G
from members.models import Member
class StatisticsTestCase(TestCase):
def setUp(self):
for is_active in [True, False]:
for balance in [-100, 0, 100]:
for division in Division.objects.all()
G(Member, is_active=is_active, balance=balance, division=division)
But this looks pretty bad and is hard to read. Is there a simpler way with better to read code to create all possible combinations of properties of an object?
I'm open to different test data generators as long as they work nicely with Python 3 and Django.
Sara's answer is a good step forward, but I am still not satisfied by the code readability, so I am answering my own question.
variants = {
'is_active': [True, False],
'balance': [-100, 0, 100],
'division': list(Division.objects.all())
}
names = sorted(variants)
products = [dict(zip(names, prod)) for prod in it.product(*(variants[name] for name in names))]
for combination in products:
G(Member, **combination)
Now anyone wanting to change this test can easily see which property is tested with which values. Thanks go to this q&a for the dict solution.