diff --git a/django/contrib/gis/db/backends/base/operations.py b/django/contrib/gis/db/backends/base/operations.py
index 2956fa3c9a..84b1785a1c 100644
--- a/django/contrib/gis/db/backends/base/operations.py
+++ b/django/contrib/gis/db/backends/base/operations.py
@@ -12,6 +12,7 @@ class BaseSpatialOperations:
     # an attribute for the spatial database version tuple (if applicable)
     postgis = False
     spatialite = False
+    mariadb = False
     mysql = False
     oracle = False
     spatial_version = None
diff --git a/django/contrib/gis/db/backends/mysql/operations.py b/django/contrib/gis/db/backends/mysql/operations.py
index e5000e99fa..3ca609f6c4 100644
--- a/django/contrib/gis/db/backends/mysql/operations.py
+++ b/django/contrib/gis/db/backends/mysql/operations.py
@@ -12,13 +12,19 @@ from django.utils.functional import cached_property
 
 
 class MySQLOperations(BaseSpatialOperations, DatabaseOperations):
-
-    mysql = True
     name = 'mysql'
     geom_func_prefix = 'ST_'
 
     Adapter = WKTAdapter
 
+    @cached_property
+    def mariadb(self):
+        return self.connection.mysql_is_mariadb
+
+    @cached_property
+    def mysql(self):
+        return not self.connection.mysql_is_mariadb
+
     @cached_property
     def select(self):
         return self.geom_func_prefix + 'AsBinary(%s)'
diff --git a/tests/gis_tests/distapp/tests.py b/tests/gis_tests/distapp/tests.py
index 10a0f99efc..30f64e97cb 100644
--- a/tests/gis_tests/distapp/tests.py
+++ b/tests/gis_tests/distapp/tests.py
@@ -1,5 +1,3 @@
-import unittest
-
 from django.contrib.gis.db.models.functions import (
     Area, Distance, Length, Perimeter, Transform, Union,
 )
@@ -9,7 +7,7 @@ from django.db import NotSupportedError, connection
 from django.db.models import Exists, F, OuterRef, Q
 from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature
 
-from ..utils import FuncTestMixin, mysql, oracle, postgis, spatialite
+from ..utils import FuncTestMixin
 from .models import (
     AustraliaCity, CensusZipcode, Interstate, SouthTexasCity, SouthTexasCityFt,
     SouthTexasInterstate, SouthTexasZipcode,
@@ -79,9 +77,9 @@ class DistanceTest(TestCase):
         # Now performing the `dwithin` queries on a geodetic coordinate system.
         for dist in au_dists:
             with self.subTest(dist=dist):
-                type_error = isinstance(dist, D) and not oracle
+                type_error = isinstance(dist, D) and not connection.ops.oracle
                 if isinstance(dist, tuple):
-                    if oracle or spatialite:
+                    if connection.ops.oracle or connection.ops.spatialite:
                         # Result in meters
                         dist = dist[1]
                     else:
@@ -137,7 +135,7 @@ class DistanceTest(TestCase):
             'Melbourne', 'Mittagong', 'Shellharbour',
             'Sydney', 'Thirroul', 'Wollongong',
         ]
-        if spatialite:
+        if connection.ops.spatialite:
             # SpatiaLite is less accurate and returns 102.8km for Batemans Bay.
             expected_cities.pop(0)
         self.assertEqual(expected_cities, self.get_names(dist_qs))
@@ -216,8 +214,9 @@ class DistanceTest(TestCase):
             SouthTexasCity.objects.count(),
         )
 
-    @unittest.skipUnless(mysql, 'This is a MySQL-specific test')
     def test_mysql_geodetic_distance_error(self):
+        if not connection.ops.mysql:
+            self.skipTest('This is a MySQL-specific test.')
         msg = 'Only numeric values of degree units are allowed on geodetic distance queries.'
         with self.assertRaisesMessage(ValueError, msg):
             AustraliaCity.objects.filter(point__distance_lte=(Point(0, 0), D(m=100))).exists()
@@ -313,7 +312,7 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
         """
         lagrange = GEOSGeometry('POINT(805066.295722839 4231496.29461335)', 32140)
         houston = SouthTexasCity.objects.annotate(dist=Distance('point', lagrange)).order_by('id').first()
-        tol = 2 if oracle else 5
+        tol = 2 if connection.ops.oracle else 5
         self.assertAlmostEqual(
             houston.dist.m,
             147075.069813,
@@ -348,7 +347,7 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
 
         # Original query done on PostGIS, have to adjust AlmostEqual tolerance
         # for Oracle.
-        tol = 2 if oracle else 5
+        tol = 2 if connection.ops.oracle else 5
 
         # Ensuring expected distances are returned for each distance queryset.
         for qs in dist_qs:
@@ -376,12 +375,12 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
         for city, distance in zip(qs, distances):
             with self.subTest(city=city, distance=distance):
                 # Testing equivalence to within a meter (kilometer on SpatiaLite).
-                tol = -3 if spatialite else 0
+                tol = -3 if connection.ops.spatialite else 0
                 self.assertAlmostEqual(distance, city.distance.m, tol)
 
     @skipUnlessDBFeature("has_Distance_function", "supports_distance_geodetic")
     def test_distance_geodetic_spheroid(self):
-        tol = 2 if oracle else 4
+        tol = 2 if connection.ops.oracle else 4
 
         # Got the reference distances using the raw SQL statements:
         #  SELECT ST_distance_spheroid(point, ST_GeomFromText('POINT(151.231341 -33.952685)', 4326),
@@ -408,7 +407,7 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
         for i, c in enumerate(qs):
             with self.subTest(c=c):
                 self.assertAlmostEqual(spheroid_distances[i], c.distance.m, tol)
-        if postgis or spatialite:
+        if connection.ops.postgis or connection.ops.spatialite:
             # PostGIS uses sphere-only distances by default, testing these as well.
             qs = AustraliaCity.objects.exclude(id=hillsdale.id).annotate(
                 distance=Distance('point', hillsdale.point)
@@ -521,7 +520,7 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
 
         if connection.features.supports_length_geodetic:
             qs = Interstate.objects.annotate(length=Length('path'))
-            tol = 2 if oracle else 3
+            tol = 2 if connection.ops.oracle else 3
             self.assertAlmostEqual(len_m1, qs[0].length.m, tol)
             # TODO: test with spheroid argument (True and False)
         else:
@@ -547,7 +546,7 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
         # Reference query:
         # SELECT ST_Perimeter(distapp_southtexaszipcode.poly) FROM distapp_southtexaszipcode;
         perim_m = [18404.3550889361, 15627.2108551001, 20632.5588368978, 17094.5996143697]
-        tol = 2 if oracle else 7
+        tol = 2 if connection.ops.oracle else 7
         qs = SouthTexasZipcode.objects.annotate(perimeter=Perimeter('poly')).order_by('name')
         for i, z in enumerate(qs):
             self.assertAlmostEqual(perim_m[i], z.perimeter.m, tol)
diff --git a/tests/gis_tests/geoapp/test_expressions.py b/tests/gis_tests/geoapp/test_expressions.py
index 89e83a782f..6ca8615d87 100644
--- a/tests/gis_tests/geoapp/test_expressions.py
+++ b/tests/gis_tests/geoapp/test_expressions.py
@@ -1,12 +1,9 @@
-from unittest import skipUnless
-
 from django.contrib.gis.db.models import F, GeometryField, Value, functions
 from django.contrib.gis.geos import Point, Polygon
 from django.db import connection
 from django.db.models import Count, Min
 from django.test import TestCase, skipUnlessDBFeature
 
-from ..utils import postgis
 from .models import City, ManyPointModel, MultiFields
 
 
@@ -25,7 +22,7 @@ class GeoExpressionsTests(TestCase):
         self.assertTrue(point.equals_exact(p.transform(4326, clone=True), 10 ** -5))
         self.assertEqual(point.srid, 4326)
 
-    @skipUnless(postgis, 'Only postgis has geography fields.')
+    @skipUnlessDBFeature('supports_geography')
     def test_geography_value(self):
         p = Polygon(((1, 1), (1, 2), (2, 2), (2, 1), (1, 1)))
         area = City.objects.annotate(a=functions.Area(Value(p, GeometryField(srid=4326, geography=True)))).first().a
diff --git a/tests/gis_tests/geoapp/test_functions.py b/tests/gis_tests/geoapp/test_functions.py
index 1a1eea8f4d..9cf444935e 100644
--- a/tests/gis_tests/geoapp/test_functions.py
+++ b/tests/gis_tests/geoapp/test_functions.py
@@ -12,7 +12,7 @@ from django.db import NotSupportedError, connection
 from django.db.models import IntegerField, Sum, Value
 from django.test import TestCase, skipUnlessDBFeature
 
-from ..utils import FuncTestMixin, mariadb, mysql, oracle, postgis
+from ..utils import FuncTestMixin
 from .models import City, Country, CountryWebMercator, State, Track
 
 
@@ -87,7 +87,7 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
         # WHERE "geoapp_city"."name" = 'Chicago';
         # Finally, we set every available keyword.
         # MariaDB doesn't limit the number of decimals in bbox.
-        if mariadb:
+        if connection.ops.mariadb:
             chicago_json['bbox'] = [-87.650175, 41.850385, -87.650175, 41.850385]
         self.assertJSONEqual(
             City.objects.annotate(
@@ -105,7 +105,7 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
             qs.annotate(gml=functions.AsGML('name'))
         ptown = City.objects.annotate(gml=functions.AsGML('point', precision=9)).get(name='Pueblo')
 
-        if oracle:
+        if connection.ops.oracle:
             # No precision parameter for Oracle :-/
             gml_regex = re.compile(
                 r'^<gml:Point srsName="EPSG:4326" xmlns:gml="http://www.opengis.net/gml">'
@@ -167,7 +167,7 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
         wkt = City.objects.annotate(
             wkt=functions.AsWKT(Point(1, 2, srid=4326)),
         ).first().wkt
-        self.assertEqual(wkt, 'POINT (1.0 2.0)' if oracle else 'POINT(1 2)')
+        self.assertEqual(wkt, 'POINT (1.0 2.0)' if connection.ops.oracle else 'POINT(1 2)')
 
     @skipUnlessDBFeature("has_Azimuth_function")
     def test_azimuth(self):
@@ -184,11 +184,11 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
             # num_seg is the number of segments per quarter circle.
             return (4 * num_seg) + 1
 
-        expected_areas = (169, 136) if postgis else (171, 126)
+        expected_areas = (169, 136) if connection.ops.postgis else (171, 126)
         qs = Country.objects.annotate(circle=functions.BoundingCircle('mpoly')).order_by('name')
         self.assertAlmostEqual(qs[0].circle.area, expected_areas[0], 0)
         self.assertAlmostEqual(qs[1].circle.area, expected_areas[1], 0)
-        if postgis:
+        if connection.ops.postgis:
             # By default num_seg=48.
             self.assertEqual(qs[0].circle.num_points, circle_num_points(48))
             self.assertEqual(qs[1].circle.num_points, circle_num_points(48))
@@ -199,7 +199,7 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
                 qs = Country.objects.annotate(
                     circle=functions.BoundingCircle('mpoly', num_seg=num_seq),
                 ).order_by('name')
-                if postgis:
+                if connection.ops.postgis:
                     self.assertGreater(qs[0].circle.area, 168.4, 0)
                     self.assertLess(qs[0].circle.area, 169.5, 0)
                     self.assertAlmostEqual(qs[1].circle.area, 136, 0)
@@ -212,7 +212,7 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
     @skipUnlessDBFeature("has_Centroid_function")
     def test_centroid(self):
         qs = State.objects.exclude(poly__isnull=True).annotate(centroid=functions.Centroid('poly'))
-        tol = 1.8 if mysql else (0.1 if oracle else 0.00001)
+        tol = 1.8 if connection.ops.mysql else (0.1 if connection.ops.oracle else 0.00001)
         for state in qs:
             self.assertTrue(state.poly.centroid.equals_exact(state.centroid, tol))
 
@@ -224,7 +224,7 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
         geom = Point(5, 23, srid=4326)
         qs = Country.objects.annotate(diff=functions.Difference('mpoly', geom))
         # Oracle does something screwy with the Texas geometry.
-        if oracle:
+        if connection.ops.oracle:
             qs = qs.exclude(name='Texas')
 
         for c in qs:
@@ -236,7 +236,7 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
         geom = Point(556597.4, 2632018.6, srid=3857)  # Spherical Mercator
         qs = Country.objects.annotate(difference=functions.Difference('mpoly', geom))
         # Oracle does something screwy with the Texas geometry.
-        if oracle:
+        if connection.ops.oracle:
             qs = qs.exclude(name='Texas')
         for c in qs:
             self.assertTrue(c.mpoly.difference(geom).equals(c.difference))
@@ -396,9 +396,9 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
 
         qs = City.objects.filter(point__isnull=False).annotate(num_geom=functions.NumGeometries('point'))
         for city in qs:
-            # Oracle and PostGIS return 1 for the number of geometries on
-            # non-collections, whereas MySQL returns None.
-            if mysql:
+            # The results for the number of geometries on non-collections
+            # depends on the database.
+            if connection.ops.mysql or connection.ops.mariadb:
                 self.assertIsNone(city.num_geom)
             else:
                 self.assertEqual(1, city.num_geom)
@@ -519,7 +519,7 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
         geom = Point(5, 23, srid=4326)
         qs = Country.objects.annotate(sym_difference=functions.SymDifference('mpoly', geom))
         # Oracle does something screwy with the Texas geometry.
-        if oracle:
+        if connection.ops.oracle:
             qs = qs.exclude(name='Texas')
         for country in qs:
             self.assertTrue(country.mpoly.sym_difference(geom).equals(country.sym_difference))
@@ -562,7 +562,7 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
             intersection=functions.Intersection('mpoly', geom),
         )
 
-        if oracle:
+        if connection.ops.oracle:
             # Should be able to execute the queries; however, they won't be the same
             # as GEOS (because Oracle doesn't use GEOS internally like PostGIS or
             # SpatiaLite).
diff --git a/tests/gis_tests/geoapp/test_indexes.py b/tests/gis_tests/geoapp/test_indexes.py
index d4c7d13d6d..4aee5062d8 100644
--- a/tests/gis_tests/geoapp/test_indexes.py
+++ b/tests/gis_tests/geoapp/test_indexes.py
@@ -1,10 +1,7 @@
-from unittest import skipUnless
-
 from django.db import connection
 from django.db.models import Index
 from django.test import TransactionTestCase
 
-from ..utils import mysql, oracle, postgis
 from .models import City
 
 
@@ -22,17 +19,18 @@ class SchemaIndexesTests(TransactionTestCase):
             }
 
     def has_spatial_indexes(self, table):
-        if mysql:
+        if connection.ops.mysql:
             with connection.cursor() as cursor:
                 return connection.introspection.supports_spatial_index(cursor, table)
-        elif oracle:
+        elif connection.ops.oracle:
             # Spatial indexes in Meta.indexes are not supported by the Oracle
             # backend (see #31252).
             return False
         return True
 
-    @skipUnless(postgis, 'This is a PostGIS-specific test.')
     def test_using_sql(self):
+        if not connection.ops.postgis:
+            self.skipTest('This is a PostGIS-specific test.')
         index = Index(fields=['point'])
         editor = connection.schema_editor()
         self.assertIn(
diff --git a/tests/gis_tests/geoapp/tests.py b/tests/gis_tests/geoapp/tests.py
index 9ac6928772..3456aad54f 100644
--- a/tests/gis_tests/geoapp/tests.py
+++ b/tests/gis_tests/geoapp/tests.py
@@ -13,9 +13,7 @@ from django.db.models import F, OuterRef, Subquery
 from django.test import TestCase, skipUnlessDBFeature
 from django.test.utils import CaptureQueriesContext
 
-from ..utils import (
-    mariadb, mysql, oracle, postgis, skipUnlessGISLookup, spatialite,
-)
+from ..utils import skipUnlessGISLookup
 from .models import (
     City, Country, Feature, MinusOneSRID, MultiFields, NonConcreteModel,
     PennsylvaniaCity, State, Track,
@@ -109,7 +107,7 @@ class GeoModelTest(TestCase):
         # Constructing & querying with a point from a different SRID. Oracle
         # `SDO_OVERLAPBDYINTERSECT` operates differently from
         # `ST_Intersects`, so contains is used instead.
-        if oracle:
+        if connection.ops.oracle:
             tx = Country.objects.get(mpoly__contains=other_srid_pnt)
         else:
             tx = Country.objects.get(mpoly__intersects=other_srid_pnt)
@@ -299,7 +297,7 @@ class GeoLookupTest(TestCase):
         invalid_geom = fromstr('POLYGON((0 0, 0 1, 1 1, 1 0, 1 1, 1 0, 0 0))')
         State.objects.create(name='invalid', poly=invalid_geom)
         qs = State.objects.all()
-        if oracle or (mysql and connection.mysql_version < (8, 0, 0)):
+        if connection.ops.oracle or (connection.ops.mysql and connection.mysql_version < (8, 0, 0)):
             # Kansas has adjacent vertices with distance 6.99244813842e-12
             # which is smaller than the default Oracle tolerance.
             # It's invalid on MySQL < 8 also.
@@ -453,12 +451,11 @@ class GeoLookupTest(TestCase):
             with self.assertRaises(e):
                 qs.count()
 
-        # Relate works differently for the different backends.
-        if postgis or spatialite or mariadb:
-            contains_mask = 'T*T***FF*'
-            within_mask = 'T*F**F***'
-            intersects_mask = 'T********'
-        elif oracle:
+        contains_mask = 'T*T***FF*'
+        within_mask = 'T*F**F***'
+        intersects_mask = 'T********'
+        # Relate works differently on Oracle.
+        if connection.ops.oracle:
             contains_mask = 'contains'
             within_mask = 'inside'
             # TODO: This is not quite the same as the PostGIS mask above
@@ -477,7 +474,7 @@ class GeoLookupTest(TestCase):
         self.assertEqual('Lawrence', City.objects.get(point__relate=(ks.poly, within_mask)).name)
 
         # Testing intersection relation mask.
-        if not oracle:
+        if not connection.ops.oracle:
             if connection.features.supports_transform:
                 self.assertEqual(
                     Country.objects.get(mpoly__relate=(pnt1, intersects_mask)).name,
@@ -487,7 +484,7 @@ class GeoLookupTest(TestCase):
             self.assertEqual('Lawrence', City.objects.get(point__relate=(ks.poly, intersects_mask)).name)
 
         # With a complex geometry expression
-        mask = 'anyinteract' if oracle else within_mask
+        mask = 'anyinteract' if connection.ops.oracle else within_mask
         self.assertFalse(City.objects.exclude(point__relate=(functions.Union('point', 'point'), mask)))
 
     def test_gis_lookups_with_complex_expressions(self):
diff --git a/tests/gis_tests/geogapp/tests.py b/tests/gis_tests/geogapp/tests.py
index 0faf749e14..53852517e8 100644
--- a/tests/gis_tests/geogapp/tests.py
+++ b/tests/gis_tests/geogapp/tests.py
@@ -2,7 +2,6 @@
 Tests for geography support in PostGIS
 """
 import os
-from unittest import skipUnless
 
 from django.contrib.gis.db import models
 from django.contrib.gis.db.models.functions import Area, Distance
@@ -11,7 +10,7 @@ from django.db import NotSupportedError, connection
 from django.db.models.functions import Cast
 from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature
 
-from ..utils import FuncTestMixin, oracle, postgis, spatialite
+from ..utils import FuncTestMixin
 from .models import City, County, Zipcode
 
 
@@ -37,9 +36,10 @@ class GeographyTest(TestCase):
         for cities in [cities1, cities2]:
             self.assertEqual(['Dallas', 'Houston', 'Oklahoma City'], cities)
 
-    @skipUnless(postgis, "This is a PostGIS-specific test")
     def test04_invalid_operators_functions(self):
         "Ensuring exceptions are raised for operators & functions invalid on geography fields."
+        if not connection.ops.postgis:
+            self.skipTest('This is a PostGIS-specific test.')
         # Only a subset of the geometry functions & operator are available
         # to PostGIS geography types.  For more information, visit:
         # http://postgis.refractions.net/documentation/manual-1.5/ch08.html#PostGIS_GeographyFunctions
@@ -108,9 +108,9 @@ class GeographyFunctionTests(FuncTestMixin, TestCase):
         """
         Testing Distance() support on non-point geography fields.
         """
-        if oracle:
+        if connection.ops.oracle:
             ref_dists = [0, 4899.68, 8081.30, 9115.15]
-        elif spatialite:
+        elif connection.ops.spatialite:
             # SpatiaLite returns non-zero distance for polygons and points
             # covered by that polygon.
             ref_dists = [326.61, 4899.68, 8081.30, 9115.15]
@@ -124,13 +124,13 @@ class GeographyFunctionTests(FuncTestMixin, TestCase):
         for z, ref in zip(qs, ref_dists):
             self.assertAlmostEqual(z.distance.m, ref, 2)
 
-        if postgis:
+        if connection.ops.postgis:
             # PostGIS casts geography to geometry when distance2 is calculated.
             ref_dists = [0, 4899.68, 8081.30, 9115.15]
         for z, ref in zip(qs, ref_dists):
             self.assertAlmostEqual(z.distance2.m, ref, 2)
 
-        if not spatialite:
+        if not connection.ops.spatialite:
             # Distance function combined with a lookup.
             hzip = Zipcode.objects.get(code='77002')
             self.assertEqual(qs.get(distance__lte=0), hzip)
diff --git a/tests/gis_tests/gis_migrations/test_operations.py b/tests/gis_tests/gis_migrations/test_operations.py
index 020d10b865..eb8640191a 100644
--- a/tests/gis_tests/gis_migrations/test_operations.py
+++ b/tests/gis_tests/gis_migrations/test_operations.py
@@ -10,8 +10,6 @@ from django.test import (
     TransactionTestCase, skipIfDBFeature, skipUnlessDBFeature,
 )
 
-from ..utils import mysql, oracle
-
 try:
     GeometryColumns = connection.ops.geometry_columns()
     HAS_GEOMETRY_COLUMNS = True
@@ -30,7 +28,7 @@ class OperationTestCase(TransactionTestCase):
 
     @property
     def has_spatial_indexes(self):
-        if mysql:
+        if connection.ops.mysql:
             with connection.cursor() as cursor:
                 return connection.introspection.supports_spatial_index(cursor, 'gis_neighborhood')
         return True
@@ -120,7 +118,7 @@ class OperationTests(OperationTestCase):
     def test_geom_col_name(self):
         self.assertEqual(
             GeometryColumns.geom_col_name(),
-            'column_name' if oracle else 'f_geometry_column',
+            'column_name' if connection.ops.oracle else 'f_geometry_column',
         )
 
     @skipUnlessDBFeature('supports_raster')
diff --git a/tests/gis_tests/inspectapp/tests.py b/tests/gis_tests/inspectapp/tests.py
index 61e7d3543a..d4b9ccedc4 100644
--- a/tests/gis_tests/inspectapp/tests.py
+++ b/tests/gis_tests/inspectapp/tests.py
@@ -10,7 +10,6 @@ from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature
 from django.test.utils import modify_settings
 
 from ..test_data import TEST_DATA
-from ..utils import mariadb
 from .models import AllOGRFields
 
 
@@ -142,7 +141,7 @@ class OGRInspectTest(SimpleTestCase):
         else:
             self.assertIn('    f_decimal = models.DecimalField(max_digits=0, decimal_places=0)', model_def)
         self.assertIn('    f_int = models.IntegerField()', model_def)
-        if not mariadb:
+        if not connection.ops.mariadb:
             # Probably a bug between GDAL and MariaDB on time fields.
             self.assertIn('    f_datetime = models.DateTimeField()', model_def)
             self.assertIn('    f_time = models.TimeField()', model_def)
diff --git a/tests/gis_tests/test_spatialrefsys.py b/tests/gis_tests/test_spatialrefsys.py
index bd24aaed00..548be7f54c 100644
--- a/tests/gis_tests/test_spatialrefsys.py
+++ b/tests/gis_tests/test_spatialrefsys.py
@@ -4,8 +4,6 @@ from django.db import connection
 from django.test import TestCase, skipUnlessDBFeature
 from django.utils.functional import cached_property
 
-from .utils import oracle, postgis, spatialite
-
 test_srs = ({
     'srid': 4326,
     'auth_name': ('EPSG', True),
@@ -75,13 +73,15 @@ class SpatialRefSysTest(TestCase):
             #  also, Oracle Spatial seems to add extraneous info to fields, hence the
             #  the testing with the 'startswith' flag.
             auth_name, oracle_flag = sd['auth_name']
-            if postgis or (oracle and oracle_flag):
-                self.assertTrue(srs.auth_name.startswith(auth_name))
+            # Compare case-insensitively because srs.auth_name is lowercase
+            # ("epsg") on Spatialite.
+            if not connection.ops.oracle or oracle_flag:
+                self.assertIs(srs.auth_name.upper().startswith(auth_name), True)
 
             self.assertEqual(sd['auth_srid'], srs.auth_srid)
 
-            # No PROJ and different srtext on oracle backends :(
-            if postgis:
+            # No PROJ and different srtext on Oracle.
+            if not connection.ops.oracle:
                 self.assertTrue(srs.wkt.startswith(sd['srtext']))
                 self.assertRegex(srs.proj4text, sd['proj_re'])
 
@@ -94,14 +94,9 @@ class SpatialRefSysTest(TestCase):
             self.assertTrue(sr.spheroid.startswith(sd['spheroid']))
             self.assertEqual(sd['geographic'], sr.geographic)
             self.assertEqual(sd['projected'], sr.projected)
-
-            if not (spatialite and not sd['spatialite']):
-                # Can't get 'NAD83 / Texas South Central' from PROJ string
-                # on SpatiaLite
-                self.assertTrue(sr.name.startswith(sd['name']))
-
+            self.assertIs(sr.name.startswith(sd['name']), True)
             # Testing the SpatialReference object directly.
-            if postgis or spatialite:
+            if not connection.ops.oracle:
                 srs = sr.srs
                 self.assertRegex(srs.proj, sd['proj_re'])
                 self.assertTrue(srs.wkt.startswith(sd['srtext']))
diff --git a/tests/gis_tests/utils.py b/tests/gis_tests/utils.py
index d2089e87a3..35c7d366ee 100644
--- a/tests/gis_tests/utils.py
+++ b/tests/gis_tests/utils.py
@@ -24,16 +24,9 @@ def skipUnlessGISLookup(*gis_lookups):
     return decorator
 
 
-# Shortcut booleans to omit only portions of tests.
 _default_db = settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'].rsplit('.')[-1]
-oracle = _default_db == 'oracle'
-postgis = _default_db == 'postgis'
-mysql = _default_db == 'mysql'
-mariadb = mysql and connection.mysql_is_mariadb
-spatialite = _default_db == 'spatialite'
-
 # MySQL spatial indices can't handle NULL geometries.
-gisfield_may_be_null = not mysql
+gisfield_may_be_null = _default_db != 'mysql'
 
 
 class FuncTestMixin: