django-cachalot
django-cachalot copied to clipboard
Compatibility with freezegun
In our tests, we often use pytest + freezegun. Some time ago we started using cachalot and found out that our tests sometimes behave unstable.
For example, this simple test will fail if cachalot is connected:
@pytest.mark.freeze_time('2032-12-11')
def tests_broken():
created_entry = SomeModel.objects.create(data='OriginalData')
fetched_entry = SomeModel.objects.get(pk=created_entry.id)
fetched_entry.data = 'UpdatedData'
fetched_entry.save()
> assert SomeModel.objects.get(pk=created_entry.id).data == 'UpdatedData'
E AssertionError: assert 'OriginalData' == 'UpdatedData'
E - OriginalData
E + UpdatedData
This happens because with freezegun all dates are patched with static ones, and in this place the cachalot instead of making a new SELECT request takes the cache data, although the table was UPDATEd.
So we just turned off the cachalot in our tests.
I do not know if it is possible to fix it, but it would be great to write somewhere in the documentation that these libraries are not compatible. It can saves a lot of time to someone.
Hi ik I'm pretty late but better late than never. Cachalot works by setting cached values in a tuple: (time set, queryset value)
. By using freezegun, cachalot won't work properly as we need to use these set times to properly invalidate caches.
As to enabling or disabling cachalot during tests, it depends. I like keeping it on, so you must be aware that by putting it off your system is prone to any slight error that cachalot may make. I noticed in #181 that Django 3.1.10 included a new ORM attribute that broke Django 3.1 temporarily. It's fixed in v2.4.0.
So my recommendation:
Anytime you use freezegun, create a pytest fixture and mark any test that uses freezegun. Like @pytest.mark.freezegun
. Then, you should have an autouse=True
fixture of scope function to override the setting: CACHALOT_ENABLED=False
. That way, you can test all your queries properly while still being able to use freezegun. I hope this helped!