Correct problems with tests (#234)

This commit is contained in:
Jack Linke 2023-05-24 21:35:03 -04:00 committed by GitHub
parent b2d9de2997
commit 27eaaa57cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 115 additions and 87 deletions

View file

@ -4,14 +4,20 @@ Whats new in django-cachalot?
2.6.0
-----
- Dropped Django 2.2 and 4.0 support. Added Django 4.2 and Python 3.11 support. Added psycopg support (#229)
- Dropped Django 2.2 and 4.0 support
- Added Django 4.2 and Python 3.11 support
- Added psycopg support (#229)
- Updated tests to account for the `BEGIN` and `COMMIT` query changes in Django 4.2
- Standardized django version comparisons in tests
2.5.3
-----
- Verify get_meta isn't none before requesting db_table (#225 #226)
2.5.2
-----
- Added Django 4.1 support (#217)
2.5.1

View file

@ -58,7 +58,7 @@ class PostgresModel(Model):
null=True, blank=True)
hstore = HStoreField(null=True, blank=True)
if DJANGO_VERSION[0] < 4:
if DJANGO_VERSION < (4, 0):
from django.contrib.postgres.fields import JSONField
json = JSONField(null=True, blank=True)

View file

@ -1,6 +1,5 @@
from unittest import skipIf
from django import VERSION as DJANGO_VERSION
from django.conf import settings
from django.db import DEFAULT_DB_ALIAS, connections, transaction
from django.test import TransactionTestCase
@ -27,24 +26,6 @@ class MultiDatabaseTestCase(TransactionTestCase):
# will execute an extra SQL request below.
connection2.cursor()
def is_django_21_below_and_sqlite2(self):
"""
Note: See test_utils.py with this function name
Checks if Django 2.1 or below and SQLite2
"""
django_version = DJANGO_VERSION
if not self.is_sqlite2:
# Immediately know if SQLite
return False
if django_version[0] < 2:
# Takes Django 0 and 1 out of the picture
return True
else:
if django_version[0] == 2 and django_version[1] < 2:
# Takes Django 2.0-2.1 out
return True
return False
def test_read(self):
with self.assertNumQueries(1):
data1 = list(Test.objects.all())
@ -66,8 +47,7 @@ class MultiDatabaseTestCase(TransactionTestCase):
data1 = list(Test.objects.using(self.db_alias2))
self.assertListEqual(data1, [])
with self.assertNumQueries(2 if self.is_django_21_below_and_sqlite2() else 1,
using=self.db_alias2):
with self.assertNumQueries(1, using=self.db_alias2):
t3 = Test.objects.using(self.db_alias2).create(name='test3')
with self.assertNumQueries(1, using=self.db_alias2):
@ -82,8 +62,7 @@ class MultiDatabaseTestCase(TransactionTestCase):
data1 = list(Test.objects.all())
self.assertListEqual(data1, [self.t1, self.t2])
with self.assertNumQueries(2 if self.is_django_21_below_and_sqlite2() else 1,
using=self.db_alias2):
with self.assertNumQueries(1, using=self.db_alias2):
Test.objects.using(self.db_alias2).create(name='test3')
with self.assertNumQueries(0):

View file

@ -3,7 +3,7 @@ from unittest import skipIf
from uuid import UUID
from decimal import Decimal
from django import VERSION as django_version
from django import VERSION as DJANGO_VERSION
from django.conf import settings
from django.contrib.auth.models import Group, Permission, User
from django.contrib.contenttypes.models import ContentType
@ -353,7 +353,7 @@ class ReadTestCase(TestUtilsMixin, TransactionTestCase):
@all_final_sql_checks
def test_subquery(self):
additional_tables = []
if django_version[0] == 4 and django_version[1] < 1 and settings.CACHALOT_FINAL_SQL_CHECK:
if DJANGO_VERSION >= (4, 0) and DJANGO_VERSION < (4, 1) and settings.CACHALOT_FINAL_SQL_CHECK:
# with Django 4.0 comes some query optimalizations that do selects little differently.
additional_tables.append('django_content_type')
qs = Test.objects.filter(owner__in=User.objects.all())
@ -694,7 +694,7 @@ class ReadTestCase(TestUtilsMixin, TransactionTestCase):
self.assert_query_cached(qs)
with self.assertRaisesMessage(
AssertionError if django_version[0] < 4 else TypeError,
AssertionError if DJANGO_VERSION < (4, 0) else TypeError,
'Cannot combine queries on two different base models.'
):
Test.objects.all() | Permission.objects.all()
@ -739,7 +739,7 @@ class ReadTestCase(TestUtilsMixin, TransactionTestCase):
self.assert_query_cached(qs)
with self.assertRaisesMessage(
AssertionError if django_version[0] < 4 else TypeError,
AssertionError if DJANGO_VERSION < (4, 0) else TypeError,
'Cannot combine queries on two different base models.'):
Test.objects.all() & Permission.objects.all()
@ -816,21 +816,21 @@ class ReadTestCase(TestUtilsMixin, TransactionTestCase):
with self.assertRaises(TransactionManagementError):
list(Test.objects.select_for_update())
with self.assertNumQueries(1):
with self.assertNumQueries(3 if DJANGO_VERSION >= (4, 2) else 1):
with transaction.atomic():
data1 = list(Test.objects.select_for_update())
self.assertListEqual(data1, [self.t1, self.t2])
self.assertListEqual([t.name for t in data1],
['test1', 'test2'])
with self.assertNumQueries(1):
with self.assertNumQueries(3 if DJANGO_VERSION >= (4, 2) else 1):
with transaction.atomic():
data2 = list(Test.objects.select_for_update())
self.assertListEqual(data2, [self.t1, self.t2])
self.assertListEqual([t.name for t in data2],
['test1', 'test2'])
with self.assertNumQueries(2):
with self.assertNumQueries(4 if DJANGO_VERSION >= (4, 2) else 2):
with transaction.atomic():
data3 = list(Test.objects.select_for_update())
data4 = list(Test.objects.select_for_update())
@ -896,7 +896,9 @@ class ReadTestCase(TestUtilsMixin, TransactionTestCase):
self.assert_query_cached(qs, [self.t2, self.t1])
def test_table_inheritance(self):
with self.assertNumQueries(3 if self.is_sqlite else 2):
with self.assertNumQueries(
3 if self.is_sqlite else (4 if DJANGO_VERSION >= (4, 2) else 2)
):
t_child = TestChild.objects.create(name='test_child')
with self.assertNumQueries(1):
@ -911,15 +913,10 @@ class ReadTestCase(TestUtilsMixin, TransactionTestCase):
expected = (r'\d+ 0 0 SCAN cachalot_test\n'
r'\d+ 0 0 USE TEMP B-TREE FOR ORDER BY')
elif self.is_mysql:
if self.django_version < (3, 1):
expected = (
r'1 SIMPLE cachalot_test '
r'(?:None )?ALL None None None None 2 100\.0 Using filesort')
else:
expected = (
r'-> Sort row IDs: cachalot_test.`name` \(cost=[\d\.]+ rows=\d\)\n '
r'-> Table scan on cachalot_test \(cost=[\d\.]+ rows=\d\)\n'
)
expected = (
r'-> Sort row IDs: cachalot_test.`name` \(cost=[\d\.]+ rows=\d\)\n '
r'-> Table scan on cachalot_test \(cost=[\d\.]+ rows=\d\)\n'
)
else:
explain_kwargs.update(
analyze=True,
@ -935,9 +932,7 @@ class ReadTestCase(TestUtilsMixin, TransactionTestCase):
r'Planning Time: [\d\.]+ ms\n'
r'Execution Time: [\d\.]+ ms$') % (operation_detail,
operation_detail)
with self.assertNumQueries(
2 if self.is_mysql and django_version[0] < 3
else 1):
with self.assertNumQueries(1):
explanation1 = Test.objects.explain(**explain_kwargs)
self.assertRegex(explanation1, expected)
with self.assertNumQueries(0):

View file

@ -1,4 +1,3 @@
from django import VERSION as DJANGO_VERSION
from django.core.management.color import no_style
from django.db import connection, transaction
@ -11,7 +10,6 @@ class TestUtilsMixin:
self.is_sqlite = connection.vendor == 'sqlite'
self.is_mysql = connection.vendor == 'mysql'
self.is_postgresql = connection.vendor == 'postgresql'
self.django_version = DJANGO_VERSION
self.force_reopen_connection()
# TODO: Remove this workaround when this issue is fixed:
@ -19,8 +17,6 @@ class TestUtilsMixin:
def tearDown(self):
if connection.vendor == 'postgresql':
flush_args = [no_style(), (PostgresModel._meta.db_table,),]
if float(".".join(map(str, DJANGO_VERSION[:2]))) < 3.1:
flush_args.append(())
flush_sql_list = connection.ops.sql_flush(*flush_args)
with transaction.atomic():
for sql in flush_sql_list:

View file

@ -1,5 +1,6 @@
from threading import Thread
from django import VERSION as DJANGO_VERSION
from django.db import connection, transaction
from django.test import TransactionTestCase, skipUnlessDBFeature
@ -29,7 +30,7 @@ class ThreadSafetyTestCase(TestUtilsMixin, TransactionTestCase):
self.assertEqual(t2, t)
def test_concurrent_caching_during_atomic(self):
with self.assertNumQueries(1):
with self.assertNumQueries(3 if DJANGO_VERSION >= (4, 2) else 1):
with transaction.atomic():
t1 = TestThread().start_and_join()
t = Test.objects.create(name='test')
@ -45,7 +46,7 @@ class ThreadSafetyTestCase(TestUtilsMixin, TransactionTestCase):
def test_concurrent_caching_before_and_during_atomic_1(self):
t1 = TestThread().start_and_join()
with self.assertNumQueries(1):
with self.assertNumQueries(3 if DJANGO_VERSION >= (4, 2) else 1):
with transaction.atomic():
t2 = TestThread().start_and_join()
t = Test.objects.create(name='test')
@ -60,7 +61,7 @@ class ThreadSafetyTestCase(TestUtilsMixin, TransactionTestCase):
def test_concurrent_caching_before_and_during_atomic_2(self):
t1 = TestThread().start_and_join()
with self.assertNumQueries(1):
with self.assertNumQueries(3 if DJANGO_VERSION >= (4, 2) else 1):
with transaction.atomic():
t = Test.objects.create(name='test')
t2 = TestThread().start_and_join()
@ -73,7 +74,7 @@ class ThreadSafetyTestCase(TestUtilsMixin, TransactionTestCase):
self.assertEqual(data, t)
def test_concurrent_caching_during_and_after_atomic_1(self):
with self.assertNumQueries(1):
with self.assertNumQueries(3 if DJANGO_VERSION >= (4, 2) else 1):
with transaction.atomic():
t1 = TestThread().start_and_join()
t = Test.objects.create(name='test')
@ -88,7 +89,7 @@ class ThreadSafetyTestCase(TestUtilsMixin, TransactionTestCase):
self.assertEqual(data, t)
def test_concurrent_caching_during_and_after_atomic_2(self):
with self.assertNumQueries(1):
with self.assertNumQueries(3 if DJANGO_VERSION >= (4, 2) else 1):
with transaction.atomic():
t = Test.objects.create(name='test')
t1 = TestThread().start_and_join()
@ -103,7 +104,7 @@ class ThreadSafetyTestCase(TestUtilsMixin, TransactionTestCase):
self.assertEqual(data, t)
def test_concurrent_caching_during_and_after_atomic_3(self):
with self.assertNumQueries(1):
with self.assertNumQueries(3 if DJANGO_VERSION >= (4, 2) else 1):
with transaction.atomic():
t1 = TestThread().start_and_join()
t = Test.objects.create(name='test')

View file

@ -1,4 +1,6 @@
from cachalot.transaction import AtomicCache
from django import VERSION as DJANGO_VERSION
from django.contrib.auth.models import User
from django.core.cache import cache
from django.db import transaction, connection, IntegrityError
@ -10,7 +12,9 @@ from .test_utils import TestUtilsMixin
class AtomicTestCase(TestUtilsMixin, TransactionTestCase):
def test_successful_read_atomic(self):
with self.assertNumQueries(2 if self.is_sqlite else 1):
with self.assertNumQueries(
2 if self.is_sqlite else (3 if DJANGO_VERSION >= (4, 2) else 1)
):
with transaction.atomic():
data1 = list(Test.objects.all())
self.assertListEqual(data1, [])
@ -20,7 +24,9 @@ class AtomicTestCase(TestUtilsMixin, TransactionTestCase):
self.assertListEqual(data2, [])
def test_unsuccessful_read_atomic(self):
with self.assertNumQueries(2 if self.is_sqlite else 1):
with self.assertNumQueries(
2 if self.is_sqlite else (3 if DJANGO_VERSION >= (4, 2) else 1)
):
try:
with transaction.atomic():
data1 = list(Test.objects.all())
@ -38,21 +44,27 @@ class AtomicTestCase(TestUtilsMixin, TransactionTestCase):
data1 = list(Test.objects.all())
self.assertListEqual(data1, [])
with self.assertNumQueries(2 if self.is_sqlite else 1):
with self.assertNumQueries(
2 if self.is_sqlite else (3 if DJANGO_VERSION >= (4, 2) else 1)
):
with transaction.atomic():
t1 = Test.objects.create(name='test1')
with self.assertNumQueries(1):
data2 = list(Test.objects.all())
self.assertListEqual(data2, [t1])
with self.assertNumQueries(2 if self.is_sqlite else 1):
with self.assertNumQueries(
2 if self.is_sqlite else (3 if DJANGO_VERSION >= (4, 2) else 1)
):
with transaction.atomic():
t2 = Test.objects.create(name='test2')
with self.assertNumQueries(1):
data3 = list(Test.objects.all())
self.assertListEqual(data3, [t1, t2])
with self.assertNumQueries(4 if self.is_sqlite else 3):
with self.assertNumQueries(
4 if self.is_sqlite else (5 if DJANGO_VERSION >= (4, 2) else 3)
):
with transaction.atomic():
data4 = list(Test.objects.all())
t3 = Test.objects.create(name='test3')
@ -67,7 +79,9 @@ class AtomicTestCase(TestUtilsMixin, TransactionTestCase):
data1 = list(Test.objects.all())
self.assertListEqual(data1, [])
with self.assertNumQueries(2 if self.is_sqlite else 1):
with self.assertNumQueries(
2 if self.is_sqlite else (3 if DJANGO_VERSION >= (4, 2) else 1)
):
try:
with transaction.atomic():
Test.objects.create(name='test')
@ -82,7 +96,9 @@ class AtomicTestCase(TestUtilsMixin, TransactionTestCase):
Test.objects.get(name='test')
def test_cache_inside_atomic(self):
with self.assertNumQueries(2 if self.is_sqlite else 1):
with self.assertNumQueries(
2 if self.is_sqlite else (3 if DJANGO_VERSION >= (4, 2) else 1)
):
with transaction.atomic():
data1 = list(Test.objects.all())
data2 = list(Test.objects.all())
@ -90,7 +106,9 @@ class AtomicTestCase(TestUtilsMixin, TransactionTestCase):
self.assertListEqual(data2, [])
def test_invalidation_inside_atomic(self):
with self.assertNumQueries(4 if self.is_sqlite else 3):
with self.assertNumQueries(
4 if self.is_sqlite else (5 if DJANGO_VERSION >= (4, 2) else 3)
):
with transaction.atomic():
data1 = list(Test.objects.all())
t = Test.objects.create(name='test')
@ -99,7 +117,9 @@ class AtomicTestCase(TestUtilsMixin, TransactionTestCase):
self.assertListEqual(data2, [t])
def test_successful_nested_read_atomic(self):
with self.assertNumQueries(7 if self.is_sqlite else 6):
with self.assertNumQueries(
7 if self.is_sqlite else (8 if DJANGO_VERSION >= (4, 2) else 6)
):
with transaction.atomic():
list(Test.objects.all())
with transaction.atomic():
@ -114,7 +134,9 @@ class AtomicTestCase(TestUtilsMixin, TransactionTestCase):
list(User.objects.all())
def test_unsuccessful_nested_read_atomic(self):
with self.assertNumQueries(6 if self.is_sqlite else 5):
with self.assertNumQueries(
6 if self.is_sqlite else (7 if DJANGO_VERSION >= (4, 2) else 5)
):
with transaction.atomic():
try:
with transaction.atomic():
@ -127,7 +149,9 @@ class AtomicTestCase(TestUtilsMixin, TransactionTestCase):
list(Test.objects.all())
def test_successful_nested_write_atomic(self):
with self.assertNumQueries(13 if self.is_sqlite else 12):
with self.assertNumQueries(
13 if self.is_sqlite else (14 if DJANGO_VERSION >= (4, 2) else 12)
):
with transaction.atomic():
t1 = Test.objects.create(name='test1')
with transaction.atomic():
@ -144,7 +168,9 @@ class AtomicTestCase(TestUtilsMixin, TransactionTestCase):
self.assertListEqual(data3, [t1, t2, t3, t4])
def test_unsuccessful_nested_write_atomic(self):
with self.assertNumQueries(16 if self.is_sqlite else 15):
with self.assertNumQueries(
16 if self.is_sqlite else (17 if DJANGO_VERSION >= (4, 2) else 15)
):
with transaction.atomic():
t1 = Test.objects.create(name='test1')
try:

View file

@ -1,3 +1,5 @@
import sys
from unittest import skipIf, skipUnless
from django import VERSION as DJANGO_VERSION
@ -56,7 +58,9 @@ class WriteTestCase(TestUtilsMixin, TransactionTestCase):
data1 = list(Test.objects.all())
self.assertListEqual(data1, [])
with self.assertNumQueries(3 if self.is_sqlite else 2):
with self.assertNumQueries(
3 if self.is_sqlite else (4 if DJANGO_VERSION >= (4, 2) else 2)
):
t, created = Test.objects.get_or_create(name='test')
self.assertTrue(created)
@ -78,14 +82,18 @@ class WriteTestCase(TestUtilsMixin, TransactionTestCase):
with self.assertNumQueries(1):
self.assertListEqual(list(Test.objects.all()), [])
with self.assertNumQueries(5 if self.is_sqlite else 4):
with self.assertNumQueries(
5 if self.is_sqlite else (6 if DJANGO_VERSION >= (4, 2) else 4)
):
t, created = Test.objects.update_or_create(
name='test', defaults={'public': True})
self.assertTrue(created)
self.assertEqual(t.name, 'test')
self.assertEqual(t.public, True)
with self.assertNumQueries(3 if self.is_sqlite else 2):
with self.assertNumQueries(
3 if self.is_sqlite else (4 if DJANGO_VERSION >= (4, 2) else 2)
):
t, created = Test.objects.update_or_create(
name='test', defaults={'public': False})
self.assertFalse(created)
@ -94,7 +102,9 @@ class WriteTestCase(TestUtilsMixin, TransactionTestCase):
# The number of SQL queries doesnt decrease because update_or_create
# always calls an UPDATE, even when data wasnt changed.
with self.assertNumQueries(3 if self.is_sqlite else 2):
with self.assertNumQueries(
3 if self.is_sqlite else (4 if DJANGO_VERSION >= (4, 2) else 2)
):
t, created = Test.objects.update_or_create(
name='test', defaults={'public': False})
self.assertFalse(created)
@ -109,17 +119,21 @@ class WriteTestCase(TestUtilsMixin, TransactionTestCase):
data1 = list(Test.objects.all())
self.assertListEqual(data1, [])
with self.assertNumQueries(2 if self.is_sqlite else 1):
with self.assertNumQueries(
2 if self.is_sqlite else (3 if DJANGO_VERSION >= (4, 2) else 1)
):
unsaved_tests = [Test(name='test%02d' % i) for i in range(1, 11)]
Test.objects.bulk_create(unsaved_tests)
self.assertEqual(Test.objects.count(), 10)
with self.assertNumQueries(2 if self.is_sqlite else 1):
with self.assertNumQueries(
2 if self.is_sqlite else (3 if DJANGO_VERSION >= (4, 2) else 1)
):
unsaved_tests = [Test(name='test%02d' % i) for i in range(1, 11)]
Test.objects.bulk_create(unsaved_tests)
self.assertEqual(Test.objects.count(), 20)
with self.assertNumQueries(1):
with self.assertNumQueries(3 if DJANGO_VERSION >= (4, 2) else else 1):
data2 = list(Test.objects.all())
self.assertEqual(len(data2), 20)
self.assertListEqual([t.name for t in data2],
@ -160,12 +174,16 @@ class WriteTestCase(TestUtilsMixin, TransactionTestCase):
self.assertListEqual(data1, [t1.name, t2.name])
self.assertListEqual(data2, [t1.name])
with self.assertNumQueries(2 if self.is_sqlite else 1):
with self.assertNumQueries(
2 if self.is_sqlite else (3 if DJANGO_VERSION >= (4, 2) else 1)
):
Test.objects.bulk_create([Test(name='test%s' % i)
for i in range(2, 11)])
with self.assertNumQueries(1):
self.assertEqual(Test.objects.count(), 10)
with self.assertNumQueries(2 if self.is_sqlite else 1):
with self.assertNumQueries(
2 if self.is_sqlite else (3 if DJANGO_VERSION >= (4, 2) else 1)
):
Test.objects.all().delete()
with self.assertNumQueries(1):
self.assertEqual(Test.objects.count(), 0)
@ -360,7 +378,9 @@ class WriteTestCase(TestUtilsMixin, TransactionTestCase):
self.assertListEqual(data4, [user1, user2])
self.assertListEqual([u.n for u in data4], [1, 0])
with self.assertNumQueries(2 if self.is_sqlite else 1):
with self.assertNumQueries(
2 if self.is_sqlite else (3 if DJANGO_VERSION >= (4, 2) else 1)
):
Test.objects.bulk_create([
Test(name='test3', owner=user1),
Test(name='test4', owner=user2),
@ -588,7 +608,9 @@ class WriteTestCase(TestUtilsMixin, TransactionTestCase):
data2 = list(Test.objects.select_related('owner'))
self.assertListEqual(data2, [])
with self.assertNumQueries(2 if self.is_sqlite else 1):
with self.assertNumQueries(
2 if self.is_sqlite else (3 if DJANGO_VERSION >= (4, 2) else 1)
):
Test.objects.bulk_create([
Test(name='test1', owner=u1),
Test(name='test2', owner=u2),
@ -602,7 +624,9 @@ class WriteTestCase(TestUtilsMixin, TransactionTestCase):
self.assertEqual(data3[2].owner, u2)
self.assertEqual(data3[3].owner, u1)
with self.assertNumQueries(2 if self.is_sqlite else 1):
with self.assertNumQueries(
2 if self.is_sqlite else (3 if DJANGO_VERSION >= (4, 2) else 1)
):
Test.objects.filter(name__in=['test1', 'test2']).delete()
with self.assertNumQueries(1):
data4 = list(Test.objects.select_related('owner'))
@ -635,9 +659,9 @@ class WriteTestCase(TestUtilsMixin, TransactionTestCase):
self.assertListEqual(list(data3[0].owner.groups.all()), [])
with self.assertNumQueries(
8 if self.is_sqlite and DJANGO_VERSION[0] == 2 and DJANGO_VERSION[1] == 2
else 4 if self.is_postgresql and DJANGO_VERSION[0] > 2
else 4 if self.is_mysql and DJANGO_VERSION[0] > 2
8 if self.is_postgresql and DJANGO_VERSION >= (4, 2)
else 4 if self.is_postgresql and DJANGO_VERSION >= (3, 0)
else 4 if self.is_mysql and DJANGO_VERSION >= (3, 0)
else 6
):
group = Group.objects.create(name='test_group')
@ -694,7 +718,7 @@ class WriteTestCase(TestUtilsMixin, TransactionTestCase):
@skipUnlessDBFeature('has_select_for_update')
def test_invalidate_select_for_update(self):
with self.assertNumQueries(1):
with self.assertNumQueries(3 if DJANGO_VERSION >= (4, 2) else 1):
Test.objects.bulk_create([Test(name='test1'), Test(name='test2')])
with self.assertNumQueries(1):
@ -852,7 +876,9 @@ class WriteTestCase(TestUtilsMixin, TransactionTestCase):
with self.assertRaises(TestChild.DoesNotExist):
TestChild.objects.get()
with self.assertNumQueries(3 if self.is_sqlite else 2):
with self.assertNumQueries(
3 if self.is_sqlite else (4 if DJANGO_VERSION >= (4, 2) else 2)
):
t_child = TestChild.objects.create(name='test_child')
with self.assertNumQueries(1):

View file

@ -3,7 +3,7 @@ envlist =
py{37,38,39,310}-django3.2-{sqlite3,postgresql,mysql}-{redis,memcached,pylibmc,locmem,filebased},
py{38,39,310}-django4.1-{sqlite3,postgresql,mysql}-{redis,memcached,pylibmc,locmem,filebased},
py{38,39,310,311}-django4.2-{sqlite3,postgresql,mysql}-{redis,memcached,pylibmc,locmem,filebased},
py{38,39,310}-djangomain-{sqlite3,postgresql,mysql}-{redis,memcached,pylibmc,locmem,filebased},
py{38,39,310,311}-djangomain-{sqlite3,postgresql,mysql}-{redis,memcached,pylibmc,locmem,filebased},
[testenv]
passenv = *
@ -14,12 +14,11 @@ basepython =
py310: python3.10
py311: python3.11
deps =
django2.2: Django>=2.2,<2.3
django3.2: Django>=3.2,<4.0
django4.1: Django>=4.1,<4.2
django4.2: Django>=4.2,<4.3
djangomain: https://github.com/django/django/archive/main.tar.gz
psycopg2>=2.8,<2.9
psycopg2>=2.9.5,<3.0
psycopg
mysqlclient
django-redis