diff --git a/core/modules/node/lib/Drupal/node/Tests/Views/AnalyzeNodeTest.php b/core/modules/node/lib/Drupal/node/Tests/Views/AnalyzeNodeTest.php
new file mode 100644
index 0000000..b5bb644
--- /dev/null
+++ b/core/modules/node/lib/Drupal/node/Tests/Views/AnalyzeNodeTest.php
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\node\Tests\Views\AnalyzeNodeTest.
+ */
+
+namespace Drupal\node\Tests\Views;
+
+/**
+ * Tests the node analyzer.
+ *
+ * @see node_views_analyze()
+ */
+class AnalyzeNodeTest extends NodeTestBase {
+
+  /**
+   * Views used by this test.
+   *
+   * @var array
+   */
+  public static $testViews = array('test_node_analyze');
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('views_ui');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Node: Analyzer',
+      'description' => 'Tests the node analyzer.',
+      'group' => 'Views module integration',
+    );
+  }
+
+  /**
+   * Tests the warnings given by node module in Views Analyze.
+   */
+  public function testNodeAnalyze() {
+    // Deny anonymous users the ability to access content, to cause analyzer warnings.
+    user_role_revoke_permissions(DRUPAL_ANONYMOUS_RID, array('access content'));
+
+    // Check the analyzer results for an incorrectly built view.
+    $this->drupalLogin($this->drupalCreateUser(array('administer views')));
+    $this->drupalGet('admin/structure/views/nojs/analyze/test_node_analyze/page_1');
+    $this->assertRaw(t('Some roles lack permission to access content, but display %display has no access control.', array('%display' => 'Master')));
+    $this->assertRaw(t('Display %display has no access control but does not contain a filter for published nodes.', array('%display' => 'Master')));
+    $this->assertRaw(t('Display %display has set node/%node as path. This will not produce what you want. If you want to have multiple versions of the node view, use panels.', array('%display' => 'Page')));
+
+    // Fix the errors and check the results again.
+    $view = views_get_view('test_node_analyze');
+    $view->initDisplay();
+    $view->displayHandlers->get('page_1')->setOption('path', 'test_node_analyze');
+    $view->displayHandlers->get('default')->setOption('access', array(
+      'type' => 'perm',
+      'options' => array(
+        'perm' => 'access content',
+      ),
+    ));
+    $view->addItem('default', 'filter', 'node', 'status', array('value' => TRUE));
+    $view->storage->save();
+    $this->drupalGet('admin/structure/views/nojs/analyze/test_node_analyze/page_1');
+    $this->assertText(t('View analysis can find nothing to report.'));
+  }
+
+}
diff --git a/core/modules/node/node.views.inc b/core/modules/node/node.views.inc
index 519fc21..6dfc56e 100644
--- a/core/modules/node/node.views.inc
+++ b/core/modules/node/node.views.inc
@@ -662,3 +662,44 @@ function node_views_plugins_row_alter(array &$plugins) {
   $plugins['entity:node']['class'] = 'Drupal\node\Plugin\views\row\NodeRow';
   $plugins['entity:node']['module'] = 'node';
 }
+
+/**
+ * Implements hook_views_analyze().
+ */
+function node_views_analyze(ViewExecutable $view) {
+  $ret = array();
+  // Check for something other than the default display:
+  if ($view->storage->get('base_table') == 'node') {
+    foreach ($view->displayHandlers as $id => $display) {
+      if (!$display->isDefaulted('access') || !$display->isDefaulted('filters')) {
+        // check for no access control
+        $access = $display->getOption('access');
+        if (empty($access['type']) || $access['type'] == 'none') {
+          $anonymous_role = entity_load('user_role', DRUPAL_ANONYMOUS_RID);
+          $anonymous_has_access = $anonymous_role && $anonymous_role->hasPermission('access content');
+          $authenticated_role = entity_load('user_role', DRUPAL_AUTHENTICATED_RID);
+          $authenticated_has_access = $authenticated_role && $authenticated_role->hasPermission('access content');
+          if (!$anonymous_has_access || !$authenticated_has_access) {
+            $ret[] = Analyzer::formatMessage(t('Some roles lack permission to access content, but display %display has no access control.', array('%display' => $display->display['display_title'])), 'warning');
+          }
+          $filters = $display->getOption('filters');
+          foreach ($filters as $filter) {
+            if ($filter['table'] == 'node' && ($filter['field'] == 'status' || $filter['field'] == 'status_extra')) {
+              continue 2;
+            }
+          }
+          $ret[] = Analyzer::formatMessage(t('Display %display has no access control but does not contain a filter for published nodes.', array('%display' => $display->display['display_title'])), 'warning');
+        }
+      }
+    }
+  }
+  foreach ($view->displayHandlers as $display) {
+    if ($display->getPluginId() == 'page') {
+      if ($display->getOption('path') == 'node/%') {
+        $ret[] = Analyzer::formatMessage(t('Display %display has set node/%node as path. This will not produce what you want. If you want to have multiple versions of the node view, use panels.', array('%display' => $display->display['display_title'])), 'warning');
+      }
+    }
+  }
+
+  return $ret;
+}
diff --git a/core/modules/node/node.views_execution.inc b/core/modules/node/node.views_execution.inc
index e43690b..b7f46b7 100644
--- a/core/modules/node/node.views_execution.inc
+++ b/core/modules/node/node.views_execution.inc
@@ -17,44 +17,3 @@ function node_views_query_substitutions(ViewExecutable $view) {
     '***BYPASS_NODE_ACCESS***' =>  intval(user_access('bypass node access')),
   );
 }
-
-/**
- * Implements hook_views_analyze().
- */
-function node_views_analyze(ViewExecutable $view) {
-  $ret = array();
-  // Check for something other than the default display:
-  if ($view->storage->get('base_table') == 'node') {
-    foreach ($view->displayHandlers as $id => $display) {
-      if (!$display->isDefaulted('access') || !$display->isDefaulted('filters')) {
-        // check for no access control
-        $access = $display->getOption('access');
-        if (empty($access['type']) || $access['type'] == 'none') {
-          $anonymous_role = entity_load('user_role', DRUPAL_ANONYMOUS_RID);
-          $anonymous_has_access = $anonymous_role && $anonymous_role->hasPermission('access content');
-          $authenticated_role = entity_load('user_role', DRUPAL_AUTHENTICATED_RID);
-          $authenticated_has_access = $authenticated_role && $authenticated_role->hasPermission('access content');
-          if (!$anonymous_has_access || !$authenticated_has_access) {
-            $ret[] = Analyzer::formatMessage(t('Some roles lack permission to access content, but display %display has no access control.', array('%display' => $display->display['display_title'])), 'warning');
-          }
-          $filters = $display->getOption('filters');
-          foreach ($filters as $filter) {
-            if ($filter['table'] == 'node' && ($filter['field'] == 'status' || $filter['field'] == 'status_extra')) {
-              continue 2;
-            }
-          }
-          $ret[] = Analyzer::formatMessage(t('Display %display has no access control but does not contain a filter for published nodes.', array('%display' => $display->display['display_title'])), 'warning');
-        }
-      }
-    }
-  }
-  foreach ($view->displayHandlers as $display) {
-    if ($display->getPluginId() == 'page') {
-      if ($display->getOption('path') == 'node/%') {
-        $ret[] = Analyzer::formatMessage(t('Display %display has set node/% as path. This will not produce what you want. If you want to have multiple versions of the node view, use panels.', array('%display' => $display->display['display_title'])), 'warning');
-      }
-    }
-  }
-
-  return $ret;
-}
diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_analyze.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_analyze.yml
new file mode 100644
index 0000000..afb502c
--- /dev/null
+++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_analyze.yml
@@ -0,0 +1,102 @@
+base_field: nid
+base_table: node
+core: 8.x
+description: ''
+status: '1'
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: '0'
+    display_options:
+      access:
+        type: none
+      cache:
+        type: none
+      query:
+        type: views_query
+      exposed_form:
+        type: basic
+      pager:
+        type: full
+      style:
+        type: default
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: '1'
+          row_class_special: '1'
+      row:
+        type: fields
+        options:
+          default_field_elements: '1'
+          inline: {  }
+          separator: ''
+          hide_empty: '0'
+      fields:
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: '0'
+          alter:
+            alter_text: '0'
+            text: ''
+            make_link: '0'
+            path: ''
+            absolute: '0'
+            external: '0'
+            replace_spaces: '0'
+            path_case: none
+            trim_whitespace: '0'
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: '0'
+            max_length: ''
+            word_boundary: '0'
+            ellipsis: '0'
+            more_link: '0'
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: '0'
+            trim: '0'
+            preserve_tags: ''
+            html: '0'
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: '0'
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: '1'
+          empty: ''
+          hide_empty: '0'
+          empty_zero: '0'
+          hide_alter_empty: '1'
+          link_to_node: '1'
+          plugin_id: node
+      filters: {  }
+      sorts: {  }
+  page_1:
+    display_plugin: page
+    id: page_1
+    display_title: Page
+    position: '1'
+    display_options:
+      path: node/%
+human_name: test_node_analyze
+module: views
+id: test_node_analyze
+tag: ''
+langcode: en
+label: ''
