diff --git a/core/modules/aggregator/src/Tests/Views/AggregatorFeedViewsFieldAccessTest.php b/core/modules/aggregator/src/Tests/Views/AggregatorFeedViewsFieldAccessTest.php
new file mode 100644
index 0000000..4af9d4f
--- /dev/null
+++ b/core/modules/aggregator/src/Tests/Views/AggregatorFeedViewsFieldAccessTest.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\aggregator\Tests\Views\AggregatorFeedViewsFieldAccessTest.
+ */
+
+namespace Drupal\aggregator\Tests\Views;
+
+use Drupal\aggregator\Entity\Feed;
+use Drupal\views\Tests\Handler\FieldFieldAccessTestBase;
+
+/**
+ * Tests base field access in Views for the aggregator_feed entity.
+ *
+ * @group aggregator
+ */
+class AggregatorFeedViewsFieldAccessTest extends FieldFieldAccessTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['aggregator', 'entity_test', 'options'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
+
+    $this->installEntitySchema('aggregator_feed');
+  }
+
+  /**
+   * Check access for aggregator_feed fields.
+   */
+  public function testAggregatorFeedFields() {
+    $feed = Feed::create([
+      'title' => 'Drupal org',
+      'url' => 'https://www.drupal.org/rss.xml',
+      'link' => 'https://www.drupal.org/rss.xml',
+    ]);
+    $feed->save();
+
+    // $this->assertFieldAccess('aggregator_feed', 'title', $feed->label());
+    $this->assertFieldAccess('aggregator_feed', 'langcode', $feed->language()->getName());
+    $this->assertFieldAccess('aggregator_feed', 'url', $feed->getUrl());
+  }
+
+}
diff --git a/core/modules/aggregator/src/Tests/Views/AggregatorItemViewsFieldAccessTest.php b/core/modules/aggregator/src/Tests/Views/AggregatorItemViewsFieldAccessTest.php
new file mode 100644
index 0000000..fbd700d
--- /dev/null
+++ b/core/modules/aggregator/src/Tests/Views/AggregatorItemViewsFieldAccessTest.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\aggregator\Tests\Views\AggregatorItemViewsFieldAccessTest.
+ */
+
+namespace Drupal\aggregator\Tests\Views;
+
+use Drupal\aggregator\Entity\Feed;
+use Drupal\aggregator\Entity\Item;
+use Drupal\views\Tests\Handler\FieldFieldAccessTestBase;
+
+/**
+ * Tests base field access in Views for the aggregator_item entity.
+ *
+ * @group aggregator
+ */
+class AggregatorItemViewsFieldAccessTest extends FieldFieldAccessTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['aggregator', 'entity_test', 'options'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
+
+    $this->installEntitySchema('aggregator_feed');
+    $this->installEntitySchema('aggregator_item');
+  }
+
+  /**
+   * Check access for aggregator_item fields.
+   */
+  public function testAggregatorItemFields() {
+    $feed = Feed::create([
+      'title' => 'Drupal org',
+      'url' => 'https://www.drupal.org/rss.xml',
+    ]);
+    $feed->save();
+    $item = Item::create([
+      'title' => 'Test title',
+      'fid' => $feed->id(),
+      'description' => 'Test description',
+    ]);
+
+    $item->save();
+
+    // $this->assertFieldAccess('aggregator_item', 'title', $item->getTitle());
+    $this->assertFieldAccess('aggregator_item', 'langcode', $item->language()->getName());
+    // $this->assertFieldAccess('aggregator_item', 'description', $item->getDescription());
+  }
+
+}
diff --git a/core/modules/comment/src/Tests/Views/CommentViewsFieldAccessTest.php b/core/modules/comment/src/Tests/Views/CommentViewsFieldAccessTest.php
new file mode 100644
index 0000000..cdb2d22
--- /dev/null
+++ b/core/modules/comment/src/Tests/Views/CommentViewsFieldAccessTest.php
@@ -0,0 +1,73 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\comment\Tests\Views\CommentViewsFieldAccessTest.
+ */
+
+namespace Drupal\comment\Tests\Views;
+
+use Drupal\comment\Entity\Comment;
+use Drupal\user\Entity\User;
+use Drupal\views\Tests\Handler\FieldFieldAccessTestBase;
+
+/**
+ * Tests base field access in Views for the comment entity.
+ *
+ * @group comment
+ */
+class CommentViewsFieldAccessTest extends FieldFieldAccessTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['comment', 'entity_test'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
+
+    $this->installEntitySchema('comment');
+  }
+
+  /**
+   * Check access for comment fields.
+   */
+  public function testCommentFields() {
+    $user = User::create([
+      'name' => 'test user',
+    ]);
+    $user->save();
+
+    $comment = Comment::create([
+      'subject' => 'My comment title',
+      'uid' => $user->id(),
+      'entity_type' => 'entity_test',
+      'comment_type' => 'entity_test',
+    ]);
+    $comment->save();
+
+    $comment_anonymous = Comment::create([
+      'subject' => 'Anonymous comment title',
+      'uid' => 0,
+      'name' => 'anonymous',
+      'mail' => 'test@example.com',
+      'homepage' => 'https://example.com',
+      'entity_type' => 'entity_test',
+      'comment_type' => 'entity_test',
+    ]);
+    $comment_anonymous->save();
+
+    // $this->assertFieldAccess('comment', 'subject', 'My comment title');
+    // $this->assertFieldAccess('comment', 'subject', 'Anonymous comment title');
+    // $this->assertFieldAccess('comment', 'name', 'anonymous');
+    $this->assertFieldAccess('comment', 'mail', 'test@example.com');
+    $this->assertFieldAccess('comment', 'homepage', 'https://example.com');
+    // $this->assertFieldAccess('comment', 'uid', $comment->uid->target_id);
+    // $this->assertFieldAccess('comment', 'cid', $comment->id());
+    // $this->assertFieldAccess('comment', 'cid', $comment_anonymous->id());
+  }
+
+}
diff --git a/core/modules/file/src/Tests/Views/FileViewsFieldAccessTest.php b/core/modules/file/src/Tests/Views/FileViewsFieldAccessTest.php
new file mode 100644
index 0000000..cf7af16
--- /dev/null
+++ b/core/modules/file/src/Tests/Views/FileViewsFieldAccessTest.php
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\file\Tests\Views\FileViewsFieldAccessTest.
+ */
+
+namespace Drupal\file\Tests\Views;
+
+use Drupal\file\Entity\File;
+use Drupal\node\Entity\Node;
+use Drupal\node\Entity\NodeType;
+use Drupal\views\Tests\Handler\FieldFieldAccessTestBase;
+
+/**
+ * Tests base field access in Views for the file entity.
+ *
+ * @group File
+ */
+class FileViewsFieldAccessTest extends FieldFieldAccessTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['file', 'entity_test'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
+
+    $this->installEntitySchema('file');
+  }
+
+  /**
+   * Check access for file fields.
+   */
+  public function testFileFields() {
+    file_put_contents('public://test.txt', 'test');
+    $file = File::create([
+      'filename' => 'test.txt',
+      'uri' => 'public://test.txt',
+      'status' => TRUE,
+    ]);
+    $file->save();
+
+    // $this->assertFieldAccess('file', 'filename', $file->getFilename());
+    // $this->assertFieldAccess('file', 'fid', $file->id());
+    // $this->assertFieldAccess('file', 'uri', $file->getFileUri());
+    // $this->assertFieldAccess('file', 'filemime', $file->filemime->value);
+    // $this->assertFieldAccess('file', 'size', '4 Bytes');
+    // $this->assertFieldAccess('file', 'status', 'On');
+  }
+
+}
diff --git a/core/modules/node/src/Tests/Views/NodeViewsFieldAccessTest.php b/core/modules/node/src/Tests/Views/NodeViewsFieldAccessTest.php
new file mode 100644
index 0000000..41b4132
--- /dev/null
+++ b/core/modules/node/src/Tests/Views/NodeViewsFieldAccessTest.php
@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\node\Tests\Views\NodeViewsFieldAccessTest.
+ */
+
+namespace Drupal\node\Tests\Views;
+
+use Drupal\node\Entity\Node;
+use Drupal\node\Entity\NodeType;
+use Drupal\views\Tests\Handler\FieldFieldAccessTestBase;
+
+/**
+ * Tests base field access in Views for the node entity.
+ *
+ * @group Node
+ */
+class NodeViewsFieldAccessTest extends FieldFieldAccessTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node', 'entity_test'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
+
+    $this->installEntitySchema('node');
+  }
+
+  /**
+   * Check access for node fields.
+   */
+  public function testNodeFields() {
+    NodeType::create([
+      'type' => 'article',
+    ])->save();
+    $node = Node::create([
+      'type' => 'article',
+      'title' => 'Test title',
+      'status' => 1,
+      'promote' => 1,
+      'sticky' => 0,
+    ]);
+
+    $node->save();
+
+    $this->assertFieldAccess('node', 'title', 'Test title');
+    $this->assertFieldAccess('node', 'nid', $node->id());
+    $this->assertFieldAccess('node', 'vid', $node->id());
+    $this->assertFieldAccess('node', 'langcode', $node->language()->getName());
+    // @todo Don't we want to display Published / Unpublished by default?
+    $this->assertFieldAccess('node', 'status', 'On');
+    $this->assertFieldAccess('node', 'promote', 'On');
+    $this->assertFieldAccess('node', 'sticky', 'Off');
+
+    // @todo node_type is indeed not yet converted.
+    // $this->fieldAccess('node', 'type', $node->type->getEntity()->label());
+  }
+
+}
diff --git a/core/modules/node/tests/modules/node_access_test/node_access_test.module b/core/modules/node/tests/modules/node_access_test/node_access_test.module
index e8d1d36..3cd0b32 100644
--- a/core/modules/node/tests/modules/node_access_test/node_access_test.module
+++ b/core/modules/node/tests/modules/node_access_test/node_access_test.module
@@ -145,7 +145,8 @@ function node_access_test_add_field(NodeTypeInterface $type) {
  * Implements hook_node_access().
  */
 function node_access_test_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Session\AccountInterface $account, $langcode) {
-  $secret_catalan = \Drupal::state()->get('node_access_test_secret_catalan') ?: 0;
+  $secret_catalan = \Drupal::state()
+    ->get('node_access_test_secret_catalan') ?: 0;
   if ($secret_catalan && $langcode == 'ca') {
     // Make all Catalan content secret.
     return AccessResult::forbidden()->setCacheMaxAge(0);
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.module b/core/modules/system/tests/modules/entity_test/entity_test.module
index 1745294..a084b13 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.module
+++ b/core/modules/system/tests/modules/entity_test/entity_test.module
@@ -348,6 +348,17 @@ function entity_test_entity_field_access($operation, FieldDefinitionInterface $f
       }
     }
   }
+  if ($field = \Drupal::state()->get('views_field_access_test-field')) {
+    if ($field_definition->getName() === $field) {
+      $result = AccessResult::allowedIfHasPermission($account, 'view test entity field');
+      // For test purposes we want to actively deny access.
+      if ($result->isNeutral()) {
+        $result = AccessResult::forbidden();
+      }
+      return $result;
+    }
+  }
+
   // No opinion.
   return AccessResult::neutral();
 }
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.permissions.yml b/core/modules/system/tests/modules/entity_test/entity_test.permissions.yml
index e6b705e..ff9810b 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.permissions.yml
+++ b/core/modules/system/tests/modules/entity_test/entity_test.permissions.yml
@@ -5,3 +5,5 @@ view test entity:
   title: 'View test entities'
 view test entity translations:
   title: 'View translations of test entities'
+view test entity field:
+  title: 'View test entity field'
diff --git a/core/modules/user/src/Tests/Views/UserViewsFieldAccessTest.php b/core/modules/user/src/Tests/Views/UserViewsFieldAccessTest.php
new file mode 100644
index 0000000..925fdbc
--- /dev/null
+++ b/core/modules/user/src/Tests/Views/UserViewsFieldAccessTest.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\user\Tests\Views\userViewsFieldAccessTest.
+ */
+
+namespace Drupal\user\Tests\Views;
+
+use Drupal\user\Entity\user;
+use Drupal\views\Tests\Handler\FieldFieldAccessTestBase;
+
+/**
+ * Tests base field access in Views for the user entity.
+ *
+ * @group user
+ */
+class UserViewsFieldAccessTest extends FieldFieldAccessTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['user', 'entity_test'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
+
+    $this->installEntitySchema('user');
+  }
+
+  public function testUserFields() {
+    $user = User::create([
+      'name' => 'test user',
+      'mail' => 'druplicon@drop.org',
+      'status' => 1,
+    ]);
+
+    $user->save();
+
+    // $this->assertFieldAccess('user', 'name', 'test user');
+    // $this->assertFieldAccess('user', 'uid', $user->id());
+    $this->assertFieldAccess('user', 'langcode', $user->language()->getName());
+    $this->assertFieldAccess('user', 'status', 'On');
+
+    // Mail is not converted yet.
+    $this->assertFieldAccess('user', 'mail', 'druplicon@drop.org');
+  }
+
+}
diff --git a/core/modules/views/src/Tests/Handler/EntityTestViewsFieldAccessTest.php b/core/modules/views/src/Tests/Handler/EntityTestViewsFieldAccessTest.php
new file mode 100644
index 0000000..f72cbfd
--- /dev/null
+++ b/core/modules/views/src/Tests/Handler/EntityTestViewsFieldAccessTest.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Tests\Handler\EntityTestViewsFieldAccessTest.
+ */
+
+namespace Drupal\views\Tests\Handler;
+use Drupal\entity_test\Entity\EntityTest;
+
+/**
+ * Tests base field access in Views for the entity_test entity.
+ *
+ * @group entity_test
+ */
+class EntityTestViewsFieldAccessTest extends FieldFieldAccessTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['entity_test'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
+
+    $this->installEntitySchema('entity_test');
+  }
+
+  public function testEntityTestFields() {
+    $entity_test = EntityTest::create([
+      'name' => 'test entity name',
+    ]);
+    $entity_test->save();
+
+    $this->assertFieldAccess('entity_test', 'id', $entity_test->id());
+    $this->assertFieldAccess('entity_test', 'langcode', $entity_test->language()->getName());
+    $this->assertFieldAccess('entity_test', 'name', $entity_test->getName());
+  }
+
+}
diff --git a/core/modules/views/src/Tests/Handler/FieldFieldAccessTestBase.php b/core/modules/views/src/Tests/Handler/FieldFieldAccessTestBase.php
new file mode 100644
index 0000000..44ea708
--- /dev/null
+++ b/core/modules/views/src/Tests/Handler/FieldFieldAccessTestBase.php
@@ -0,0 +1,141 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Tests\Handler\FieldFieldAccessTest.
+ */
+
+namespace Drupal\views\Tests\Handler;
+
+use Drupal\user\Entity\Role;
+use Drupal\user\Entity\User;
+use Drupal\views\Entity\View;
+use Drupal\views\Tests\ViewUnitTestBase;
+use Drupal\views\Views;
+
+/**
+ * Provides a base class for base field access in views.
+ */
+abstract class FieldFieldAccessTestBase extends ViewUnitTestBase {
+
+  /**
+   * Stores an user entity with access to fields.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $userWithAccess;
+
+  /**
+   * Stores an user entity without access to fields.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $userWithoutAccess;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['user'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
+
+    $this->installEntitySchema('user');
+
+    $role_with_access = Role::create([
+      'id' => 'with_access',
+      'permissions' => ['view test entity field'],
+    ]);
+    $role_with_access->save();
+    $role_without_access = Role::create([
+      'id' => 'without_access',
+      'permissions' => [],
+    ]);
+    $role_without_access->save();
+
+    $this->userWithAccess = User::create([
+      'name' => $this->randomMachineName(),
+      'roles' => [$role_with_access->id()],
+    ]);
+    $this->userWithAccess->save();
+    $this->userWithoutAccess = User::create([
+      'name' => $this->randomMachineName(),
+      'roles' => [$role_without_access->id()],
+    ]);
+    $this->userWithoutAccess->save();
+  }
+
+  /**
+   * Checks views field access for a given entity type and field name.
+   *
+   * To use this method, set up an entity of type $entity_type_id, with field
+   * $field_name. Create an entity instance that contains content $field_content
+   * in that field.
+   *
+   * This method will check that a user with permission can see the content in a
+   * view, and a user without access permission on that field cannot.
+   *
+   * @param string $entity_type_id
+   *   The entity type ID.
+   * @param string $field_name
+   *   The field name.
+   * @param string $field_content
+   *   The expected field content.
+   */
+  protected function assertFieldAccess($entity_type_id, $field_name, $field_content) {
+    \Drupal::state()->set('views_field_access_test-field', $field_name);
+
+    $entity_type = \Drupal::entityManager()->getDefinition($entity_type_id);
+    $view_id = $this->randomMachineName();
+    $base_table = $entity_type->getDataTable() ?: $entity_type->getBaseTable();
+    $entity = View::create([
+      'id' => $view_id,
+      'base_table' => $base_table,
+      'display' => [
+        'default' => [
+          'display_plugin' => 'default',
+          'id' => 'default',
+          'display_options' => [
+            'fields' => [
+              $field_name => [
+                'table' => $base_table,
+                'field' => $field_name,
+                'id' => $field_name,
+                'plugin_id' => 'field',
+              ],
+            ],
+          ],
+        ],
+      ],
+    ]);
+    $entity->save();
+
+    /** @var \Drupal\Core\Session\AccountSwitcherInterface $account_switcher */
+    $account_switcher = \Drupal::service('account_switcher');
+
+    /** @var \Drupal\Core\Render\RendererInterface $renderer */
+    $renderer = \Drupal::service('renderer');
+
+    $account_switcher->switchTo($this->userWithAccess);
+    $executable = Views::getView($view_id);
+    $build = $executable->preview();
+    $this->setRawContent($renderer->render($build));
+
+    $this->assertText($field_content);
+    $this->assertTrue(isset($executable->field[$field_name]));
+
+    $account_switcher->switchTo($this->userWithoutAccess);
+    $executable = Views::getView($view_id);
+    $build = $executable->preview();
+    $this->setRawContent($renderer->render($build));
+
+    $this->assertNoText($field_content);
+    $this->assertFalse(isset($executable->field[$field_name]));
+
+    \Drupal::state()->delete('views_field_access_test-field');
+  }
+
+}
