diff --git a/core/modules/system/src/Tests/Entity/EntityPropertiesVisibilityTest.php b/core/modules/system/src/Tests/Entity/EntityPropertiesVisibilityTest.php
new file mode 100644
index 0000000..d9319d9
--- /dev/null
+++ b/core/modules/system/src/Tests/Entity/EntityPropertiesVisibilityTest.php
@@ -0,0 +1,90 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Tests\Entity\EntityPropertiesVisibilityTest.
+ */
+
+namespace Drupal\system\Tests\Entity;
+
+use Drupal\simpletest\TestBase;
+
+// The variable Vocabulary::hierarchy has a default value of
+// TAXONOMY_HIERARCHY_DISABLED. The problem is that this constant is defined in
+// the file taxonomy.module.
+include(DRUPAL_ROOT . '/core/modules/taxonomy/taxonomy.module');
+
+/**
+ * Tests that all class variables of subclasses of ContentEntityBase and ConfigEntityBase are protected or are allowed to be public.
+ *
+ * @group Entity
+ */
+class EntityPropertiesVisibilityTest extends TestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() { }
+
+  // All variables that are allowed to be public. In an ideal situation this
+  // would be empty.
+  protected $allowedPublicVariables = [
+    ['class' => 'Drupal\node\Entity\Node', 'variable' => 'in_preview'],
+    ['class' => 'Drupal\Core\Field\FieldConfigBase', 'variable' => 'default_value'],
+    ['class' => 'Drupal\Core\Field\Entity\BaseFieldOverride', 'variable' => 'default_value'],
+    ['class' => 'Drupal\field\Entity\FieldConfig', 'variable' => 'default_value'],
+    ['class' => 'Drupal\config_test\Entity\ConfigTest', 'variable' => 'label'],
+    ['class' => 'Drupal\config_test\Entity\ConfigTest', 'variable' => 'weight'],
+    ['class' => 'Drupal\config_test\Entity\ConfigTest', 'variable' => 'style'],
+    ['class' => 'Drupal\config_test\Entity\ConfigQueryTest', 'variable' => 'number'],
+    ['class' => 'Drupal\config_test\Entity\ConfigQueryTest', 'variable' => 'array'],
+    ['class' => 'Drupal\config_test\Entity\ConfigQueryTest', 'variable' => 'label'],
+    ['class' => 'Drupal\config_test\Entity\ConfigQueryTest', 'variable' => 'weight'],
+    ['class' => 'Drupal\config_test\Entity\ConfigQueryTest', 'variable' => 'style'],
+  ];
+
+  /**
+   * Checks that all variables of subclasses of ContentEntityBase and ConfigEntityBase are protected or are allowed to be public.
+   */
+  public function testEntityVariablesPublic() {
+    $directories = [
+      DRUPAL_ROOT . '/core/lib/Drupal/Core',
+      DRUPAL_ROOT . '/core/modules',
+      DRUPAL_ROOT . '/modules',
+    ];
+
+    // Load all files in the "Entity" directories.
+    foreach ($directories as $directory) {
+      foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($directory, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST) as $file) {
+        if (($file->getExtension() == 'php') && preg_match('/\/Entity$/', $file->getPath())) {
+          require_once $file->getPathname();
+        }
+      }
+    }
+
+    // Get all public class variables.
+    $publicVariables = [];
+    foreach (get_declared_classes() as $class) {
+      if (is_subclass_of($class, 'Drupal\Core\Entity\ContentEntityBase') || is_subclass_of($class, 'Drupal\Core\Config\Entity\ConfigEntityBase')) {
+        $variables = get_class_vars($class);
+        if (($variables !== FALSE) && !empty($variables) && is_array($variables)) {
+          foreach(array_keys($variables) as $variable) {
+            $publicVariables[] = ['class' => $class, 'variable' => $variable];
+          }
+        }
+      }
+    }
+
+    // Test the public class variables to see if they are allowed to be public.
+    foreach($publicVariables as $publicVariable) {
+      $allowed = FALSE;
+      foreach($this->allowedPublicVariables as $allowedPublicVariable) {
+        if ($publicVariable == $allowedPublicVariable) {
+          $allowed = TRUE;
+        }
+      }
+      $this->assertTrue($allowed, 'The variable ' . $publicVariable['class'] . '::' . $publicVariable['variable'] . ' is allowed to be public.');
+    }
+  }
+
+}
