Hi,
I'm starting using Hypothesis with Django and my first try is creating some tests for this Django model:
class Period(models.Model):
name = models.CharField(max_length=10, unique=True)
start_date = models.DateField(
validators=[
MinValueValidator(datetime.date(2025, 4, 1)),
MaxValueValidator(datetime.date(2055, 1, 1)),
]
)
end_date = models.DateField(
validators=[
MinValueValidator(datetime.date(2025, 12, 31)),
MaxValueValidator(datetime.date(2055, 12, 31)),
]
)
def __str__(self) -> str:
return self.name
def save(self, *args, **kwargs):
# Forces validation during saving. Note that validation
# will still not be called for 'update' and 'bulk_create'.
self.full_clean()
return super().save(*args, **kwargs)
#def other_methods(self):
# pass
class Meta:
constraints = [
models.UniqueConstraint(
fields=['start_date', 'end_date'], name='unique_start_end'
),
models.CheckConstraint(
condition=Q(date_debut__lt=F('end_date')),
name='start_lt_end',
),
]
First try:
from hypothesis import given
from hypothesis.extra.django import TestCase, from_model
from .models import Period
class PeriodModelTests(TestCase):
period_strategy = from_model(Period)
@given(period=period_strategy)
def test_str_method(self, period):
self.assertEqual(str(period), period.name)This gives me the
filter_too_much error. Is this normal?
I was thinking that the too much filtering was probably related to the two date fields, so, to circumvent the problem, I tried specifying the date fields like this:
import datetime
from hypothesis import strategies as st
class PeriodModelTests(TestCase):
period_strategy = from_model(
Period,
start_date=st.dates(
min_value=datetime.date(2025, 4, 1),
max_value=datetime.date(2055, 1, 1),
),
end_date=st.dates(
min_value=datetime.date(2025, 12, 31),
max_value=datetime.date(2055, 12, 31),
),
)
Now the test failed because when trying to save period instances to the DB the data did not validate (validation is called by full_clean() in the save() method) because, in the strategy, nothing enforce that start_date should be smaller then end_date.
I then tried enforcing this with @combine like this:
class PeriodeModelTests(TestCase):
@st.composite
def period_strategy(draw):
start_date = draw(
st.dates(
min_value=datetime.date(2025, 4, 1),
max_value=datetime.date(2055, 1, 1),
)
)
end_date = draw(
st.dates(
min_value=start_date + datetime.timedelta(days=1),
max_value=datetime.date(2055, 12, 31),
)
)
return from_model(Period, start_date=start_date, end_date=end_date)
@given(period=period_strategy())
def test_str_method(self, period):
self.assertEqual(str(period), period.name)This gives me the error:
AttributeError: 'LazyStrategy' object has no attribute 'name'From here I out of ideas. If someone can help me with this, it will be appreciated.
Also, during my different tests, when the system is creating entries in the DB (postgres) I'm receiving the
too_slow error. I added this setting to shutdown this healt check:
@settings(suppress_health_check=[HealthCheck.too_slow])Is this normal when creating entries in the DB?
Thanks!
Etienne