diff --git a/django/db/backends/base/features.py b/django/db/backends/base/features.py
index c818fb10fe0..ef874d74dbb 100644
--- a/django/db/backends/base/features.py
+++ b/django/db/backends/base/features.py
@@ -374,6 +374,7 @@ class BaseDatabaseFeatures:
         "cs": None,  # Case-sensitive.
         "non_default": None,  # Non-default.
         "swedish_ci": None,  # Swedish case-insensitive.
+        "virtual": None,  # A collation that can be used for virtual columns.
     }
     # SQL template override for tests.aggregation.tests.NowUTC
     test_now_utc_template = None
diff --git a/django/db/backends/mysql/features.py b/django/db/backends/mysql/features.py
index 515f4f002c6..637bcbd17c2 100644
--- a/django/db/backends/mysql/features.py
+++ b/django/db/backends/mysql/features.py
@@ -86,6 +86,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
             "ci": f"{charset}_general_ci",
             "non_default": f"{charset}_esperanto_ci",
             "swedish_ci": f"{charset}_swedish_ci",
+            "virtual": f"{charset}_esperanto_ci",
         }
 
     test_now_utc_template = "UTC_TIMESTAMP(6)"
diff --git a/django/db/backends/oracle/features.py b/django/db/backends/oracle/features.py
index e04dde621db..dfec605c1b4 100644
--- a/django/db/backends/oracle/features.py
+++ b/django/db/backends/oracle/features.py
@@ -80,12 +80,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
     supports_comparing_boolean_expr = False
     supports_json_field_contains = False
     supports_collation_on_textfield = False
-    test_collations = {
-        "ci": "BINARY_CI",
-        "cs": "BINARY",
-        "non_default": "SWEDISH_CI",
-        "swedish_ci": "SWEDISH_CI",
-    }
     test_now_utc_template = "CURRENT_TIMESTAMP AT TIME ZONE 'UTC'"
 
     django_test_skips = {
@@ -148,6 +142,16 @@ class DatabaseFeatures(BaseDatabaseFeatures):
             "TimeField": "DateTimeField",
         }
 
+    @cached_property
+    def test_collations(self):
+        return {
+            "ci": "BINARY_CI",
+            "cs": "BINARY",
+            "non_default": "SWEDISH_CI",
+            "swedish_ci": "SWEDISH_CI",
+            "virtual": "SWEDISH_CI" if self.supports_collation_on_charfield else None,
+        }
+
     @cached_property
     def supports_collation_on_charfield(self):
         with self.connection.cursor() as cursor:
diff --git a/django/db/backends/postgresql/features.py b/django/db/backends/postgresql/features.py
index 7e6455ae27f..7bcc3564079 100644
--- a/django/db/backends/postgresql/features.py
+++ b/django/db/backends/postgresql/features.py
@@ -78,6 +78,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
         "deterministic": "C",
         "non_default": "sv-x-icu",
         "swedish_ci": "sv-x-icu",
+        "virtual": "sv-x-icu",
     }
     test_now_utc_template = "STATEMENT_TIMESTAMP() AT TIME ZONE 'UTC'"
     insert_test_table_with_defaults = "INSERT INTO {} DEFAULT VALUES"
diff --git a/django/db/backends/sqlite3/features.py b/django/db/backends/sqlite3/features.py
index 3d66466af50..713d8bd38ff 100644
--- a/django/db/backends/sqlite3/features.py
+++ b/django/db/backends/sqlite3/features.py
@@ -47,6 +47,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
         "ci": "nocase",
         "cs": "binary",
         "non_default": "nocase",
+        "virtual": "nocase",
     }
     django_test_expected_failures = {
         # The django_format_dtdelta() function doesn't properly handle mixed
diff --git a/tests/model_fields/models.py b/tests/model_fields/models.py
index b966da59e56..7804c198815 100644
--- a/tests/model_fields/models.py
+++ b/tests/model_fields/models.py
@@ -20,7 +20,7 @@ except ImportError:
 
 
 test_collation = SimpleLazyObject(
-    lambda: connection.features.test_collations.get("non_default")
+    lambda: connection.features.test_collations["virtual"]
 )
 
 
@@ -529,10 +529,7 @@ class GeneratedModelOutputField(models.Model):
     )
 
     class Meta:
-        required_db_features = {
-            "supports_stored_generated_columns",
-            "supports_collation_on_charfield",
-        }
+        required_db_features = {"supports_stored_generated_columns"}
 
 
 class GeneratedModelOutputFieldVirtual(models.Model):
@@ -544,10 +541,7 @@ class GeneratedModelOutputFieldVirtual(models.Model):
     )
 
     class Meta:
-        required_db_features = {
-            "supports_virtual_generated_columns",
-            "supports_collation_on_charfield",
-        }
+        required_db_features = {"supports_virtual_generated_columns"}
 
 
 class GeneratedModelNull(models.Model):
diff --git a/tests/model_fields/test_generatedfield.py b/tests/model_fields/test_generatedfield.py
index d965940465f..a37e3749813 100644
--- a/tests/model_fields/test_generatedfield.py
+++ b/tests/model_fields/test_generatedfield.py
@@ -165,12 +165,8 @@ class GeneratedFieldTestMixin:
         with self.assertNumQueries(0), self.assertRaises(does_not_exist):
             self.base_model.objects.get(field__gte=overflow_value)
 
-    @skipUnlessDBFeature("supports_collation_on_charfield")
     def test_output_field(self):
-        collation = connection.features.test_collations.get("non_default")
-        if not collation:
-            self.skipTest("Language collations are not supported.")
-
+        collation = connection.features.test_collations["virtual"]
         m = self.output_field_model.objects.create(name="NAME")
         field = m._meta.get_field("lower_name")
         db_parameters = field.db_parameters(connection)
@@ -181,7 +177,6 @@ class GeneratedFieldTestMixin:
             field._resolved_expression.output_field.db_type(connection),
         )
 
-    @skipUnlessDBFeature("supports_collation_on_charfield")
     def test_db_type_parameters(self):
         db_type_parameters = self.output_field_model._meta.get_field(
             "lower_name"