diff --git a/core/modules/views/src/Tests/Handler/HandlerTestBase.php b/core/modules/views/src/Tests/Handler/HandlerTestBase.php
index 5345f47..c2afcbc 100644
--- a/core/modules/views/src/Tests/Handler/HandlerTestBase.php
+++ b/core/modules/views/src/Tests/Handler/HandlerTestBase.php
@@ -1,11 +1,13 @@
 <?php
 
 namespace Drupal\views\Tests\Handler;
+@trigger_error('\Drupal\views\Tests\Handler\HandlerTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\views\Functional\Handler\HandlerTestBase', E_USER_DEPRECATED);
 
 use Drupal\views\Tests\ViewTestBase;
 
 /**
- * @todo.
+ * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0.
+ *   Use \Drupal\Tests\views\Functional\Handler\HandlerTestBase.
  */
 abstract class HandlerTestBase extends ViewTestBase {
 
diff --git a/core/modules/views/src/Tests/Plugin/PluginTestBase.php b/core/modules/views/src/Tests/Plugin/PluginTestBase.php
index 3b03dcd..5322704 100644
--- a/core/modules/views/src/Tests/Plugin/PluginTestBase.php
+++ b/core/modules/views/src/Tests/Plugin/PluginTestBase.php
@@ -1,11 +1,13 @@
 <?php
 
 namespace Drupal\views\Tests\Plugin;
+@trigger_error('\Drupal\views\Tests\Plugin\PluginTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\views\Functional\Plugin\PluginTestBase', E_USER_DEPRECATED);
 
 use Drupal\views\Tests\ViewTestBase;
 
 /**
- * @todo.
+ * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0.
+ *   Use \Drupal\Tests\views\Functional\Plugin\PluginTestBase.
  */
 abstract class PluginTestBase extends ViewTestBase {
 
diff --git a/core/modules/views/src/Tests/ViewTestBase.php b/core/modules/views/src/Tests/ViewTestBase.php
index 720d528..121b21b 100644
--- a/core/modules/views/src/Tests/ViewTestBase.php
+++ b/core/modules/views/src/Tests/ViewTestBase.php
@@ -1,6 +1,7 @@
 <?php
 
 namespace Drupal\views\Tests;
+@trigger_error('\Drupal\views\Tests\ViewTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\views\Functional\ViewTestBase', E_USER_DEPRECATED);
 
 use Drupal\Core\Database\Query\SelectInterface;
 use Drupal\simpletest\WebTestBase;
@@ -13,6 +14,9 @@
  * When possible, ViewsKernelTestBase should be used instead. Both base classes
  * include the same methods.
  *
+ * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0.
+ *   Use \Drupal\Tests\views\Functional\ViewTestBase.
+ *
  * @see \Drupal\Tests\views\Kernel\ViewsKernelTestBase
  * @see \Drupal\simpletest\WebTestBase
  */
diff --git a/core/modules/views/src/Tests/Wizard/WizardTestBase.php b/core/modules/views/src/Tests/Wizard/WizardTestBase.php
index 835b9f4..f5f7cc0 100644
--- a/core/modules/views/src/Tests/Wizard/WizardTestBase.php
+++ b/core/modules/views/src/Tests/Wizard/WizardTestBase.php
@@ -1,11 +1,15 @@
 <?php
 
 namespace Drupal\views\Tests\Wizard;
+@trigger_error('\Drupal\views\Tests\Wizard\WizardTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\views\Functional\Wizard\WizardTestBase', E_USER_DEPRECATED);
 
 use Drupal\views\Tests\ViewTestBase;
 
 /**
  * Views UI wizard tests.
+ *
+ * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0.
+ *   Use \Drupal\Tests\views\Functional\Wizard\WizardTestBase.
  */
 abstract class WizardTestBase extends ViewTestBase {
 
diff --git a/core/modules/views/src/Tests/DefaultViewsTest.php b/core/modules/views/tests/src/Functional/DefaultViewsTest.php
similarity index 97%
rename from core/modules/views/src/Tests/DefaultViewsTest.php
rename to core/modules/views/tests/src/Functional/DefaultViewsTest.php
index 48e3cae..0e5c893 100644
--- a/core/modules/views/src/Tests/DefaultViewsTest.php
+++ b/core/modules/views/tests/src/Functional/DefaultViewsTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 use Drupal\comment\CommentInterface;
 use Drupal\comment\Tests\CommentTestTrait;
@@ -42,8 +42,8 @@ class DefaultViewsTest extends ViewTestBase {
     'glossary' => ['all'],
   ];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->drupalPlaceBlock('page_title_block');
 
diff --git a/core/modules/views/src/Tests/Entity/BaseFieldAccessTest.php b/core/modules/views/tests/src/Functional/Entity/BaseFieldAccessTest.php
similarity index 89%
rename from core/modules/views/src/Tests/Entity/BaseFieldAccessTest.php
rename to core/modules/views/tests/src/Functional/Entity/BaseFieldAccessTest.php
index 698a43e..19aa191 100644
--- a/core/modules/views/src/Tests/Entity/BaseFieldAccessTest.php
+++ b/core/modules/views/tests/src/Functional/Entity/BaseFieldAccessTest.php
@@ -1,9 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests\Entity;
+namespace Drupal\Tests\views\Functional\Entity;
 
 use Drupal\entity_test\Entity\EntityTest;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Tests\ViewTestData;
 
 /**
@@ -32,8 +32,8 @@ class BaseFieldAccessTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
     /** @var \Drupal\Core\Entity\EntityDefinitionUpdateManager $update_manager */
     $update_manager = $this->container->get('entity.definition_update_manager');
     \Drupal::entityManager()->clearCachedDefinitions();
diff --git a/core/modules/views/src/Tests/Entity/FieldEntityTest.php b/core/modules/views/tests/src/Functional/Entity/FieldEntityTest.php
similarity index 96%
rename from core/modules/views/src/Tests/Entity/FieldEntityTest.php
rename to core/modules/views/tests/src/Functional/Entity/FieldEntityTest.php
index 89f71ed..a46e54c 100644
--- a/core/modules/views/src/Tests/Entity/FieldEntityTest.php
+++ b/core/modules/views/tests/src/Functional/Entity/FieldEntityTest.php
@@ -1,11 +1,11 @@
 <?php
 
-namespace Drupal\views\Tests\Entity;
+namespace Drupal\Tests\views\Functional\Entity;
 
 use Drupal\comment\Tests\CommentTestTrait;
 use Drupal\node\Entity\Node;
 use Drupal\user\Entity\User;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Tests\ViewTestData;
 use Drupal\views\Views;
 use Drupal\comment\Entity\Comment;
diff --git a/core/modules/views/src/Tests/Entity/FieldEntityTranslationTest.php b/core/modules/views/tests/src/Functional/Entity/FieldEntityTranslationTest.php
similarity index 91%
rename from core/modules/views/src/Tests/Entity/FieldEntityTranslationTest.php
rename to core/modules/views/tests/src/Functional/Entity/FieldEntityTranslationTest.php
index bd4e2ed..2a227c5 100644
--- a/core/modules/views/src/Tests/Entity/FieldEntityTranslationTest.php
+++ b/core/modules/views/tests/src/Functional/Entity/FieldEntityTranslationTest.php
@@ -1,12 +1,12 @@
 <?php
 
-namespace Drupal\views\Tests\Entity;
+namespace Drupal\Tests\views\Functional\Entity;
 
 use Drupal\Core\Language\Language;
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\node\Entity\Node;
 use Drupal\node\Entity\NodeType;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Symfony\Component\CssSelector\CssSelectorConverter;
 
 /**
@@ -164,8 +164,8 @@ protected function assertRows($expected = []) {
     $rows = $this->cssSelect('div.views-row');
     foreach ($rows as $row) {
       $actual[] = [
-        'title' => (string) $row->xpath((new CssSelectorConverter())->toXPath('.views-field-title span.field-content a'))[0],
-        'sticky' => (string) $row->xpath((new CssSelectorConverter())->toXPath('.views-field-sticky span.field-content'))[0],
+        'title' => $row->find('xpath', (new CssSelectorConverter())->toXPath('.views-field-title span.field-content a'))->getText(),
+        'sticky' => $row->find('xpath', (new CssSelectorConverter())->toXPath('.views-field-sticky span.field-content'))->getText(),
       ];
     }
     $this->assertEqual($actual, $expected);
diff --git a/core/modules/views/src/Tests/Entity/FilterEntityBundleTest.php b/core/modules/views/tests/src/Functional/Entity/FilterEntityBundleTest.php
similarity index 95%
rename from core/modules/views/src/Tests/Entity/FilterEntityBundleTest.php
rename to core/modules/views/tests/src/Functional/Entity/FilterEntityBundleTest.php
index f099569..993293c 100644
--- a/core/modules/views/src/Tests/Entity/FilterEntityBundleTest.php
+++ b/core/modules/views/tests/src/Functional/Entity/FilterEntityBundleTest.php
@@ -1,9 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests\Entity;
+namespace Drupal\Tests\views\Functional\Entity;
 
 use Drupal\node\Entity\Node;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Tests\ViewTestData;
 use Drupal\views\Views;
 
@@ -42,7 +42,7 @@ class FilterEntityBundleTest extends ViewTestBase {
    */
   protected $entities = [];
 
-  protected function setUp() {
+  protected function setUp($import_test_views = TRUE) {
     parent::setUp(FALSE);
 
     $this->drupalCreateContentType(['type' => 'test_bundle']);
diff --git a/core/modules/views/src/Tests/Entity/ViewNonTranslatableEntityTest.php b/core/modules/views/tests/src/Functional/Entity/ViewNonTranslatableEntityTest.php
similarity index 87%
rename from core/modules/views/src/Tests/Entity/ViewNonTranslatableEntityTest.php
rename to core/modules/views/tests/src/Functional/Entity/ViewNonTranslatableEntityTest.php
index 82c6839..911cd61 100644
--- a/core/modules/views/src/Tests/Entity/ViewNonTranslatableEntityTest.php
+++ b/core/modules/views/tests/src/Functional/Entity/ViewNonTranslatableEntityTest.php
@@ -1,17 +1,17 @@
 <?php
 
-namespace Drupal\views\Tests\Entity;
+namespace Drupal\Tests\views\Functional\Entity;
 
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\language_test\Entity\NoLanguageEntityTest;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests the view creation of non-translatable entities.
  *
  * @group views
  */
-class ViewNonTranslatableEntityTest extends WebTestBase {
+class ViewNonTranslatableEntityTest extends BrowserTestBase {
 
   /**
    * Modules to enable.
diff --git a/core/modules/views/src/Tests/GlossaryTest.php b/core/modules/views/tests/src/Functional/GlossaryTest.php
similarity index 89%
rename from core/modules/views/src/Tests/GlossaryTest.php
rename to core/modules/views/tests/src/Functional/GlossaryTest.php
index b165768..d67f70d 100644
--- a/core/modules/views/src/Tests/GlossaryTest.php
+++ b/core/modules/views/tests/src/Functional/GlossaryTest.php
@@ -1,10 +1,11 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Url;
+use Drupal\views\Tests\AssertViewsCacheTagsTrait;
 use Drupal\views\Views;
 
 /**
@@ -97,8 +98,8 @@ public function testGlossaryView() {
         'user_list',
         'http_response',
         'rendered',
-        // FinishResponseSubscriber adds this cache tag to responses that have the
-        // 'user.permissions' cache context for anonymous users.
+        // FinishResponseSubscriber adds this cache tag to responses that have
+        // the 'user.permissions' cache context for anonymous users.
         'config:user.role.anonymous',
       ]
     );
@@ -113,8 +114,9 @@ public function testGlossaryView() {
       // to ensure that both of them are correct.
       $result = $this->xpath('//a[contains(@href, :href) and normalize-space(text())=:label]/..', [':href' => $href, ':label' => $label]);
       $this->assertTrue(count($result));
-      // The rendered output looks like "| (count)" so let's figure out the int.
-      $result_count = trim(str_replace(['|', '(', ')'], '', (string) $result[0]));
+      // The rendered output looks like "<a href=''>X</a> | (count)" so let's
+      // figure out the int.
+      $result_count = explode(' ', trim(str_replace(['|', '(', ')'], '', $result[0]->getText())))[1];
       $this->assertEqual($result_count, $count, 'The expected number got rendered.');
     }
   }
diff --git a/core/modules/views/src/Tests/Handler/AreaHTTPStatusCodeTest.php b/core/modules/views/tests/src/Functional/Handler/AreaHTTPStatusCodeTest.php
similarity index 95%
rename from core/modules/views/src/Tests/Handler/AreaHTTPStatusCodeTest.php
rename to core/modules/views/tests/src/Functional/Handler/AreaHTTPStatusCodeTest.php
index 2656adc..0e1cca9 100644
--- a/core/modules/views/src/Tests/Handler/AreaHTTPStatusCodeTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/AreaHTTPStatusCodeTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\views\Views;
 
diff --git a/core/modules/views/src/Tests/Handler/AreaTest.php b/core/modules/views/tests/src/Functional/Handler/AreaTest.php
similarity index 81%
rename from core/modules/views/src/Tests/Handler/AreaTest.php
rename to core/modules/views/tests/src/Functional/Handler/AreaTest.php
index ca9fc42..7e3e575 100644
--- a/core/modules/views/src/Tests/Handler/AreaTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/AreaTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\Component\Utility\Xss;
 use Drupal\views\Views;
@@ -28,8 +28,8 @@ class AreaTest extends HandlerTestBase {
    */
   public static $modules = ['node', 'views_ui'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
@@ -111,41 +111,6 @@ public function testRenderArea() {
   }
 
   /**
-   * Tests that the header and footer areas are not rendered if empty.
-   */
-  public function testRenderEmptyHeaderFooter() {
-    $view = Views::getView('test_example_area');
-    $view->initHandlers();
-
-    // Set example empty text.
-    $view->empty['test_example']->options['string'] = '<p>' . $this->randomMachineName() . '</p>';
-
-    $xpath = '//div[contains(@class, :class)]';
-
-    // Verify that the empty header and footer sections have not been rendered.
-    $output = $view->preview();
-    $html = $this->container->get('renderer')->renderRoot($output);
-    $this->setRawContent($html);
-    $this->assertEqual(0, count($this->xpath($xpath, [':class' => 'view-header'])));
-    $this->assertEqual(0, count($this->xpath($xpath, [':class' => 'view-footer'])));
-
-    // Set example header text.
-    $view->header['test_example']->options['string'] = '<p>' . $this->randomMachineName() . '</p>';
-    $view->header['test_example']->options['empty'] = TRUE;
-
-    // Set example footer text.
-    $view->footer['test_example']->options['string'] = '<p>' . $this->randomMachineName() . '</p>';
-    $view->footer['test_example']->options['empty'] = TRUE;
-
-    // Verify that the header and footer sections have been rendered.
-    $output = $view->preview();
-    $html = $this->container->get('renderer')->renderRoot($output);
-    $this->setRawContent($html);
-    $this->assertEqual(1, count($this->xpath($xpath, [':class' => 'view-header'])));
-    $this->assertEqual(1, count($this->xpath($xpath, [':class' => 'view-footer'])));
-  }
-
-  /**
    * Tests the access for an area.
    */
   public function testAreaAccess() {
diff --git a/core/modules/views/src/Tests/Handler/AreaTitleWebTest.php b/core/modules/views/tests/src/Functional/Handler/AreaTitleWebTest.php
similarity index 90%
rename from core/modules/views/src/Tests/Handler/AreaTitleWebTest.php
rename to core/modules/views/tests/src/Functional/Handler/AreaTitleWebTest.php
index afae1eb..db53771 100644
--- a/core/modules/views/src/Tests/Handler/AreaTitleWebTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/AreaTitleWebTest.php
@@ -1,9 +1,8 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\views\Entity\View;
-use Drupal\views\Tests\ViewTestBase;
 
 /**
  * Tests the title area handler with a web test.
@@ -11,7 +10,7 @@
  * @group views
  * @see \Drupal\views\Plugin\views\area\Title
  */
-class AreaTitleWebTest extends ViewTestBase {
+class AreaTitleWebTest extends HandlerTestBase {
 
   /**
    * Views used by this test.
@@ -23,8 +22,8 @@ class AreaTitleWebTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
diff --git a/core/modules/views/src/Tests/Handler/ArgumentStringTest.php b/core/modules/views/tests/src/Functional/Handler/ArgumentStringTest.php
similarity index 96%
rename from core/modules/views/src/Tests/Handler/ArgumentStringTest.php
rename to core/modules/views/tests/src/Functional/Handler/ArgumentStringTest.php
index 0682892..659e527 100644
--- a/core/modules/views/src/Tests/Handler/ArgumentStringTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/ArgumentStringTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\views\Views;
 
diff --git a/core/modules/views/src/Tests/Handler/FieldDropButtonTest.php b/core/modules/views/tests/src/Functional/Handler/FieldDropButtonTest.php
similarity index 89%
rename from core/modules/views/src/Tests/Handler/FieldDropButtonTest.php
rename to core/modules/views/tests/src/Functional/Handler/FieldDropButtonTest.php
index 9d5c67f..35f2a3e 100644
--- a/core/modules/views/src/Tests/Handler/FieldDropButtonTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/FieldDropButtonTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 /**
  * Tests the dropbutton field handler.
@@ -27,8 +27,8 @@ class FieldDropButtonTest extends HandlerTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $admin_user = $this->drupalCreateUser(['access content overview', 'administer nodes', 'bypass node access']);
     $this->drupalLogin($admin_user);
@@ -48,7 +48,7 @@ public function testDropbutton() {
     foreach ($nodes as $node) {
       $result = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[contains(@href, :path) and text()=:title]', [':path' => '/node/' . $node->id(), ':title' => $node->label()]);
       $this->assertEqual(count($result), 1, 'Just one node title link was found.');
-      $result = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[contains(@href, :path) and text()=:title]', [':path' => '/node/' . $node->id(), ':title' => t('Custom Text')]);
+      $result = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[contains(@href, :path) and text()=:title]', [':path' => '/node/' . $node->id(), ':title' => 'Custom Text']);
       $this->assertEqual(count($result), 1, 'Just one custom link was found.');
     }
 
diff --git a/core/modules/views/src/Tests/Handler/FieldEntityOperationsTest.php b/core/modules/views/tests/src/Functional/Handler/FieldEntityOperationsTest.php
similarity index 94%
rename from core/modules/views/src/Tests/Handler/FieldEntityOperationsTest.php
rename to core/modules/views/tests/src/Functional/Handler/FieldEntityOperationsTest.php
index 7efd1d7..a0b8827 100644
--- a/core/modules/views/src/Tests/Handler/FieldEntityOperationsTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/FieldEntityOperationsTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\Core\Url;
 use Drupal\language\Entity\ConfigurableLanguage;
@@ -27,8 +27,8 @@ class FieldEntityOperationsTest extends HandlerTestBase {
    */
   public static $modules = ['node', 'language', 'views_ui'];
 
-  public function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     // Create Article content type.
     $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
@@ -72,7 +72,7 @@ public function testEntityOperations() {
         $this->assertTrue(count($operations) > 0, 'There are operations.');
         foreach ($operations as $operation) {
           $expected_destination = Url::fromUri('internal:/test-entity-operations')->toString();
-          $result = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[@href=:path and text()=:title]', [':path' => $operation['url']->toString() . '?destination=' . $expected_destination, ':title' => $operation['title']]);
+          $result = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[@href=:path and text()=:title]', [':path' => $operation['url']->toString() . '?destination=' . $expected_destination, ':title' => (string) $operation['title']]);
           $this->assertEqual(count($result), 1, t('Found entity @operation link with destination parameter.', ['@operation' => $operation['title']]));
           // Entities which were created in Hungarian should link to the Hungarian
           // edit form, others to the English one (which has no path prefix here).
diff --git a/core/modules/views/src/Tests/Handler/FieldGroupRowsTest.php b/core/modules/views/tests/src/Functional/Handler/FieldGroupRowsTest.php
similarity index 95%
rename from core/modules/views/src/Tests/Handler/FieldGroupRowsTest.php
rename to core/modules/views/tests/src/Functional/Handler/FieldGroupRowsTest.php
index 2521e63..fb9e405 100644
--- a/core/modules/views/src/Tests/Handler/FieldGroupRowsTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/FieldGroupRowsTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\Core\Render\RenderContext;
@@ -38,8 +38,8 @@ class FieldGroupRowsTest extends HandlerTestBase {
    */
   private $fieldName = 'field_group_rows';
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     // Create content type with unlimited text field.
     $node_type = $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']);
diff --git a/core/modules/views/src/Tests/Handler/FieldGroupRowsWebTest.php b/core/modules/views/tests/src/Functional/Handler/FieldGroupRowsWebTest.php
similarity index 90%
rename from core/modules/views/src/Tests/Handler/FieldGroupRowsWebTest.php
rename to core/modules/views/tests/src/Functional/Handler/FieldGroupRowsWebTest.php
index 646cb12..08f701d 100644
--- a/core/modules/views/src/Tests/Handler/FieldGroupRowsWebTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/FieldGroupRowsWebTest.php
@@ -1,18 +1,17 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
-use Drupal\views\Tests\ViewTestBase;
 
 /**
  * Tests the "Display all values in the same row" setting.
  *
  * @group views
  */
-class FieldGroupRowsWebTest extends ViewTestBase {
+class FieldGroupRowsWebTest extends HandlerTestBase {
 
   /**
    * Views used by this test.
@@ -59,8 +58,8 @@ class FieldGroupRowsWebTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     // Create content type with unlimited text field.
     $this->nodeType = $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']);
@@ -98,7 +97,7 @@ public function testGroupRows() {
 
     $rendered_value = [];
     foreach ($result as $row) {
-      $rendered_value[] = (string) $row[0];
+      $rendered_value[] = $row->getText();
     }
     $this->assertEqual(['a, b, c'], $rendered_value);
   }
@@ -111,7 +110,7 @@ public function testUngroupedRows() {
     $result = $this->cssSelect('div.views-field-field-views-testing-group- div');
     $rendered_value = [];
     foreach ($result as $row) {
-      $rendered_value[] = (string) $row[0];
+      $rendered_value[] = $row->getText();
     }
     $this->assertEqual(['a', 'b', 'c'], $rendered_value);
   }
diff --git a/core/modules/views/src/Tests/Handler/FieldWebTest.php b/core/modules/views/tests/src/Functional/Handler/FieldWebTest.php
similarity index 99%
rename from core/modules/views/src/Tests/Handler/FieldWebTest.php
rename to core/modules/views/tests/src/Functional/Handler/FieldWebTest.php
index 31de7be..ceb73c4 100644
--- a/core/modules/views/src/Tests/Handler/FieldWebTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/FieldWebTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\Unicode;
@@ -41,8 +41,8 @@ class FieldWebTest extends HandlerTestBase {
     'views_test_data_name' => 'name',
   ];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
@@ -99,7 +99,7 @@ protected function clickSortLoadIdsFromOutput() {
     $fields = $this->xpath("//td[contains(@class, 'views-field-id')]");
     $ids = [];
     foreach ($fields as $field) {
-      $ids[] = (int) $field[0];
+      $ids[] = (int) $field->getText();
     }
     return $ids;
   }
diff --git a/core/modules/views/src/Tests/Handler/FilterDateTest.php b/core/modules/views/tests/src/Functional/Handler/FilterDateTest.php
similarity index 90%
rename from core/modules/views/src/Tests/Handler/FilterDateTest.php
rename to core/modules/views/tests/src/Functional/Handler/FilterDateTest.php
index f81e753..5ad85cc 100644
--- a/core/modules/views/src/Tests/Handler/FilterDateTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/FilterDateTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\config\Tests\SchemaCheckTestTrait;
 use Drupal\field\Entity\FieldConfig;
@@ -30,8 +30,8 @@ class FilterDateTest extends HandlerTestBase {
    */
   public static $modules = ['node', 'views_ui', 'datetime'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     // Add a date field so we can test datetime handling.
     NodeType::create([
@@ -213,7 +213,7 @@ protected function _testFilterDateUI() {
       $this->assertFieldByName($name, $value);
       if (strpos($name, '[value][type]')) {
         $radio = $this->cssSelect('input[name="' . $name . '"][checked="checked"][type="radio"]');
-        $this->assertEqual((string) $radio[0]['value'], $value);
+        $this->assertEqual($radio[0]->getAttribute('value'), $value);
       }
     }
 
@@ -221,22 +221,27 @@ protected function _testFilterDateUI() {
     $this->assertConfigSchemaByName('views.view.test_filter_date_between');
 
     // Test that the exposed filter works as expected.
-    $this->drupalGet('admin/structure/views/view/test_filter_date_between/edit');
-    $this->drupalPostForm(NULL, [], t('Update preview'));
+    $path = 'test_filter_date_between-path';
+    $this->drupalPostForm('admin/structure/views/view/test_filter_date_between/edit', [], 'Add Page');
+    $this->drupalPostForm('admin/structure/views/nojs/display/test_filter_date_between/page_1/path', ['path' => $path], 'Apply');
+    $this->drupalPostForm(NULL, [], t('Save'));
+
+    $this->drupalGet($path);
+    $this->drupalPostForm(NULL, [], t('Apply'));
     $results = $this->cssSelect('.view-content .field-content');
     $this->assertEqual(count($results), 4);
-    $this->drupalPostForm(NULL, ['created' => '1'], t('Update preview'));
+    $this->drupalPostForm(NULL, ['created' => '1'], t('Apply'));
     $results = $this->cssSelect('.view-content .field-content');
     $this->assertEqual(count($results), 1);
-    $this->assertEqual((string) $results[0], $this->nodes[3]->id());
-    $this->drupalPostForm(NULL, ['created' => '2'], t('Update preview'));
+    $this->assertEqual($results[0]->getText(), $this->nodes[3]->id());
+    $this->drupalPostForm(NULL, ['created' => '2'], t('Apply'));
     $results = $this->cssSelect('.view-content .field-content');
     $this->assertEqual(count($results), 1);
-    $this->assertEqual((string) $results[0], $this->nodes[3]->id());
-    $this->drupalPostForm(NULL, ['created' => '3'], t('Update preview'));
+    $this->assertEqual($results[0]->getText(), $this->nodes[3]->id());
+    $this->drupalPostForm(NULL, ['created' => '3'], t('Apply'));
     $results = $this->cssSelect('.view-content .field-content');
     $this->assertEqual(count($results), 1);
-    $this->assertEqual((string) $results[0], $this->nodes[1]->id());
+    $this->assertEqual($results[0]->getText(), $this->nodes[1]->id());
 
     // Change the filter to a single filter to test the schema when the operator
     // is not exposed.
@@ -250,15 +255,15 @@ protected function _testFilterDateUI() {
     $this->assertConfigSchemaByName('views.view.test_filter_date_between');
 
     // Test that the filter works as expected.
-    $this->drupalPostForm(NULL, [], t('Update preview'));
+    $this->drupalGet($path);
     $results = $this->cssSelect('.view-content .field-content');
     $this->assertEqual(count($results), 1);
-    $this->assertEqual((string) $results[0], $this->nodes[3]->id());
-    $this->drupalPostForm(NULL, ['created' => format_date(250000, 'custom', 'Y-m-d H:i:s')], t('Update preview'));
+    $this->assertEqual($results[0]->getText(), $this->nodes[3]->id());
+    $this->drupalPostForm(NULL, ['created' => format_date(250000, 'custom', 'Y-m-d H:i:s')], t('Apply'));
     $results = $this->cssSelect('.view-content .field-content');
     $this->assertEqual(count($results), 2);
-    $this->assertEqual((string) $results[0], $this->nodes[2]->id());
-    $this->assertEqual((string) $results[1], $this->nodes[3]->id());
+    $this->assertEqual($results[0]->getText(), $this->nodes[2]->id());
+    $this->assertEqual($results[1]->getText(), $this->nodes[3]->id());
   }
 
   /**
diff --git a/core/modules/views/src/Tests/Handler/HandlerAllTest.php b/core/modules/views/tests/src/Functional/Handler/HandlerAllTest.php
similarity index 98%
rename from core/modules/views/src/Tests/Handler/HandlerAllTest.php
rename to core/modules/views/tests/src/Functional/Handler/HandlerAllTest.php
index 5654376..77f5754 100644
--- a/core/modules/views/src/Tests/Handler/HandlerAllTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/HandlerAllTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\comment\Tests\CommentTestTrait;
 use Drupal\views\ViewExecutable;
diff --git a/core/modules/views/src/Tests/Handler/HandlerTest.php b/core/modules/views/tests/src/Functional/Handler/HandlerTest.php
similarity index 97%
rename from core/modules/views/src/Tests/Handler/HandlerTest.php
rename to core/modules/views/tests/src/Functional/Handler/HandlerTest.php
index e07beb3..eed5773 100644
--- a/core/modules/views/src/Tests/Handler/HandlerTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/HandlerTest.php
@@ -1,11 +1,10 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\comment\Tests\CommentTestTrait;
 use Drupal\views\Entity\View;
 use Drupal\views\ViewExecutable;
-use Drupal\views\Tests\ViewTestBase;
 use Drupal\views\Plugin\views\HandlerBase;
 use Drupal\views\Views;
 
@@ -14,7 +13,7 @@
  *
  * @group views
  */
-class HandlerTest extends ViewTestBase {
+class HandlerTest extends HandlerTestBase {
 
   use CommentTestTrait;
 
@@ -32,8 +31,8 @@ class HandlerTest extends ViewTestBase {
    */
   public static $modules = ['views_ui', 'comment', 'node'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
     $this->drupalCreateContentType(['type' => 'page']);
     $this->addDefaultCommentField('node', 'page');
     $this->enableViewsTestModule();
@@ -260,13 +259,13 @@ public function testRelationshipUI() {
     $this->assertFieldByName($relationship_name);
 
     // Check for available options.
-    $xpath = $this->constructFieldXpath('name', $relationship_name);
+    $xpath = $this->buildXPathQuery('//textarea[@name=:value]|//input[@name=:value]|//select[@name=:value]', [':value' => $relationship_name]);
     $fields = $this->xpath($xpath);
     $options = [];
     foreach ($fields as $field) {
-      $items = $this->getAllOptions($field);
+      $items = $field->findAll('css', 'option');
       foreach ($items as $item) {
-        $options[] = $item->attributes()->value;
+        $options[] = $item->getAttribute('value');
       }
     }
     $expected_options = ['none', 'nid'];
diff --git a/core/modules/views/tests/src/Functional/Handler/HandlerTestBase.php b/core/modules/views/tests/src/Functional/Handler/HandlerTestBase.php
new file mode 100644
index 0000000..e4a7736
--- /dev/null
+++ b/core/modules/views/tests/src/Functional/Handler/HandlerTestBase.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace Drupal\Tests\views\Functional\Handler;
+
+use Drupal\Tests\views\Functional\ViewTestBase;
+
+/**
+ * Views handler test base.
+ */
+abstract class HandlerTestBase extends ViewTestBase {
+
+}
diff --git a/core/modules/views/src/Tests/Plugin/AccessTest.php b/core/modules/views/tests/src/Functional/Plugin/AccessTest.php
similarity index 94%
rename from core/modules/views/src/Tests/Plugin/AccessTest.php
rename to core/modules/views/tests/src/Functional/Plugin/AccessTest.php
index 7a4eb1a..eca4862 100644
--- a/core/modules/views/src/Tests/Plugin/AccessTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/AccessTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\views\Tests\ViewTestData;
 use Drupal\views\Views;
@@ -42,8 +42,8 @@ class AccessTest extends PluginTestBase {
    */
   protected $normalUser;
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
 
diff --git a/core/modules/views/src/Tests/Plugin/ArgumentDefaultTest.php b/core/modules/views/tests/src/Functional/Plugin/ArgumentDefaultTest.php
similarity index 95%
rename from core/modules/views/src/Tests/Plugin/ArgumentDefaultTest.php
rename to core/modules/views/tests/src/Functional/Plugin/ArgumentDefaultTest.php
index a4e8217..5c7b3a3 100644
--- a/core/modules/views/src/Tests/Plugin/ArgumentDefaultTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/ArgumentDefaultTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\Core\Url;
 use Drupal\node\Entity\Node;
@@ -37,8 +37,8 @@ class ArgumentDefaultTest extends PluginTestBase {
    */
   public static $modules = ['node', 'views_ui', 'block'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
@@ -161,9 +161,9 @@ public function testArgumentDefaultNode() {
     $this->drupalPlaceBlock("views_block:test_argument_default_node-block_1", ['id' => $id]);
     $xpath = '//*[@id="block-' . $id . '"]';
     $this->drupalGet('node/' . $node1->id());
-    $this->assertTrue(strpos($this->xpath($xpath)[0]->asXml(), $node1->getTitle()));
+    $this->assertTrue(strpos($this->xpath($xpath)[0]->getText(), $node1->getTitle()));
     $this->drupalGet('node/' . $node2->id());
-    $this->assertTrue(strpos($this->xpath($xpath)[0]->asXml(), $node2->getTitle()));
+    $this->assertTrue(strpos($this->xpath($xpath)[0]->getText(), $node2->getTitle()));
   }
 
   /**
diff --git a/core/modules/views/src/Tests/Plugin/CacheTagTest.php b/core/modules/views/tests/src/Functional/Plugin/CacheTagTest.php
similarity index 98%
rename from core/modules/views/src/Tests/Plugin/CacheTagTest.php
rename to core/modules/views/tests/src/Functional/Plugin/CacheTagTest.php
index 72d94f3..044b8fd 100644
--- a/core/modules/views/src/Tests/Plugin/CacheTagTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/CacheTagTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\Core\Cache\Cache;
 use Drupal\views\ViewExecutable;
@@ -70,8 +70,8 @@ class CacheTagTest extends PluginTestBase {
    */
   protected $user;
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']);
     $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
diff --git a/core/modules/views/src/Tests/Plugin/CacheWebTest.php b/core/modules/views/tests/src/Functional/Plugin/CacheWebTest.php
similarity index 94%
rename from core/modules/views/src/Tests/Plugin/CacheWebTest.php
rename to core/modules/views/tests/src/Functional/Plugin/CacheWebTest.php
index 7786606..1549ca6 100644
--- a/core/modules/views/src/Tests/Plugin/CacheWebTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/CacheWebTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
@@ -33,8 +33,8 @@ class CacheWebTest extends PluginTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
diff --git a/core/modules/views/src/Tests/Plugin/ContextualFiltersBlockContextTest.php b/core/modules/views/tests/src/Functional/Plugin/ContextualFiltersBlockContextTest.php
similarity index 96%
rename from core/modules/views/src/Tests/Plugin/ContextualFiltersBlockContextTest.php
rename to core/modules/views/tests/src/Functional/Plugin/ContextualFiltersBlockContextTest.php
index 7fb7058..c4fbd34 100644
--- a/core/modules/views/src/Tests/Plugin/ContextualFiltersBlockContextTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/ContextualFiltersBlockContextTest.php
@@ -1,10 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\Core\Plugin\Context\ContextDefinitionInterface;
 use Drupal\views\Tests\ViewTestData;
-use Drupal\views\Tests\ViewTestBase;
 use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
 
 /**
@@ -12,7 +11,7 @@
  *
  * @group views
  */
-class ContextualFiltersBlockContextTest extends ViewTestBase {
+class ContextualFiltersBlockContextTest extends PluginTestBase {
 
   use AssertPageCacheContextsAndTagsTrait;
 
@@ -47,8 +46,8 @@ class ContextualFiltersBlockContextTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     ViewTestData::createTestViews(get_class($this), ['block_test_views']);
     $this->enableViewsTestModule();
diff --git a/core/modules/views/src/Tests/Plugin/DisabledDisplayTest.php b/core/modules/views/tests/src/Functional/Plugin/DisabledDisplayTest.php
similarity index 88%
rename from core/modules/views/src/Tests/Plugin/DisabledDisplayTest.php
rename to core/modules/views/tests/src/Functional/Plugin/DisabledDisplayTest.php
index cb43946..1a6612b 100644
--- a/core/modules/views/src/Tests/Plugin/DisabledDisplayTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/DisabledDisplayTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 /**
  * Tests the ability to disable and enable view displays.
@@ -24,8 +24,8 @@ class DisabledDisplayTest extends PluginTestBase {
    */
   public static $modules = ['block', 'node', 'views'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
 
@@ -56,7 +56,7 @@ public function testDisabledDisplays() {
     // Enabled page display should return content.
     $this->drupalGet('test-disabled-display');
     $result = $this->xpath('//h1[@class="page-title"]');
-    $this->assertEqual($result[0], 'test_disabled_display', 'The enabled page_1 display is accessible.');
+    $this->assertEqual($result[0]->getText(), 'test_disabled_display', 'The enabled page_1 display is accessible.');
 
     // Disabled page view should 404.
     $this->drupalGet('test-disabled-display-2');
@@ -75,7 +75,7 @@ public function testDisabledDisplays() {
     // Check that the originally disabled page_2 display is now enabled.
     $this->drupalGet('test-disabled-display-2');
     $result = $this->xpath('//h1[@class="page-title"]');
-    $this->assertEqual($result[0], 'test_disabled_display', 'The enabled page_2 display is accessible.');
+    $this->assertEqual($result[0]->getText(), 'test_disabled_display', 'The enabled page_2 display is accessible.');
 
     // Disable each disabled display and save the view.
     foreach ($display_ids as $display_id) {
diff --git a/core/modules/views/src/Tests/Plugin/DisplayAttachmentTest.php b/core/modules/views/tests/src/Functional/Plugin/DisplayAttachmentTest.php
similarity index 96%
rename from core/modules/views/src/Tests/Plugin/DisplayAttachmentTest.php
rename to core/modules/views/tests/src/Functional/Plugin/DisplayAttachmentTest.php
index 16c0680..a25cd39 100644
--- a/core/modules/views/src/Tests/Plugin/DisplayAttachmentTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/DisplayAttachmentTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\views\Views;
 
@@ -26,8 +26,8 @@ class DisplayAttachmentTest extends PluginTestBase {
    */
   public static $modules = ['node', 'views'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
 
diff --git a/core/modules/views/src/Tests/Plugin/DisplayEntityReferenceTest.php b/core/modules/views/tests/src/Functional/Plugin/DisplayEntityReferenceTest.php
similarity index 98%
rename from core/modules/views/src/Tests/Plugin/DisplayEntityReferenceTest.php
rename to core/modules/views/tests/src/Functional/Plugin/DisplayEntityReferenceTest.php
index ac7209c..2528192 100644
--- a/core/modules/views/src/Tests/Plugin/DisplayEntityReferenceTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/DisplayEntityReferenceTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\field\Entity\FieldConfig;
@@ -64,8 +64,8 @@ class DisplayEntityReferenceTest extends PluginTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->drupalLogin($this->drupalCreateUser(['administer views']));
 
diff --git a/core/modules/views/src/Tests/Plugin/DisplayPageWebTest.php b/core/modules/views/tests/src/Functional/Plugin/DisplayPageWebTest.php
similarity index 86%
rename from core/modules/views/src/Tests/Plugin/DisplayPageWebTest.php
rename to core/modules/views/tests/src/Functional/Plugin/DisplayPageWebTest.php
index b5c853f..101a584 100644
--- a/core/modules/views/src/Tests/Plugin/DisplayPageWebTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/DisplayPageWebTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
 use Drupal\views\Views;
@@ -31,8 +31,8 @@ class DisplayPageWebTest extends PluginTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
     $this->drupalPlaceBlock('local_tasks_block');
@@ -55,13 +55,13 @@ public function testArguments() {
     $this->assertCacheContexts(['languages:language_interface', 'route', 'theme', 'url']);
     $result = $this->xpath('//span[@class="field-content"]');
     $this->assertEqual(count($result), 1, 'Ensure that just the filtered entry was returned.');
-    $this->assertEqual((string) $result[0], 1, 'The passed ID was returned.');
+    $this->assertEqual($result[0]->getText(), 1, 'The passed ID was returned.');
 
     $this->drupalGet('test_route_with_suffix/1/suffix');
     $this->assertResponse(200);
     $result = $this->xpath('//span[@class="field-content"]');
     $this->assertEqual(count($result), 1, 'Ensure that just the filtered entry was returned.');
-    $this->assertEqual((string) $result[0], 1, 'The passed ID was returned.');
+    $this->assertEqual($result[0]->getText(), 1, 'The passed ID was returned.');
 
     $this->drupalGet('test_route_with_suffix_and_argument/1/suffix/2');
     $this->assertResponse(200);
@@ -72,13 +72,13 @@ public function testArguments() {
     $this->assertResponse(200);
     $result = $this->xpath('//span[@class="field-content"]');
     $this->assertEqual(count($result), 1, 'Ensure that just the filtered entry was returned.');
-    $this->assertEqual((string) $result[0], 1, 'The passed ID was returned.');
+    $this->assertEqual($result[0]->getText(), 1, 'The passed ID was returned.');
 
     $this->drupalGet('test_route_with_long_argument/1');
     $this->assertResponse(200);
     $result = $this->xpath('//span[@class="field-content"]');
     $this->assertEqual(count($result), 1, 'Ensure that just the filtered entry was returned.');
-    $this->assertEqual((string) $result[0], 1, 'The passed ID was returned.');
+    $this->assertEqual($result[0]->getText(), 1, 'The passed ID was returned.');
   }
 
   /**
@@ -88,11 +88,11 @@ public function testPageDisplayMenu() {
     // Check local tasks.
     $this->drupalGet('test_page_display_menu');
     $this->assertResponse(200);
-    $element = $this->xpath('//ul[contains(@class, :ul_class)]//a[contains(@class, :a_class)]', [
+    $element = $this->xpath('//ul[contains(@class, :ul_class)]//a[contains(@class, :a_class)]/child::text()', [
       ':ul_class' => 'tabs primary',
       ':a_class' => 'is-active',
     ]);
-    $this->assertEqual((string) $element[0], t('Test default tab'));
+    $this->assertEqual($element[0]->getText(), t('Test default tab'));
     $this->assertTitle(t('Test default page | Drupal'));
 
     $this->drupalGet('test_page_display_menu/default');
@@ -100,11 +100,11 @@ public function testPageDisplayMenu() {
 
     $this->drupalGet('test_page_display_menu/local');
     $this->assertResponse(200);
-    $element = $this->xpath('//ul[contains(@class, :ul_class)]//a[contains(@class, :a_class)]', [
+    $element = $this->xpath('//ul[contains(@class, :ul_class)]//a[contains(@class, :a_class)]/child::text()', [
       ':ul_class' => 'tabs primary',
       ':a_class' => 'is-active',
     ]);
-    $this->assertEqual((string) $element[0], t('Test local tab'));
+    $this->assertEqual($element[0]->getText(), t('Test local tab'));
     $this->assertTitle(t('Test local page | Drupal'));
 
     // Check an ordinary menu link.
@@ -114,7 +114,7 @@ public function testPageDisplayMenu() {
     $this->drupalGet('<front>');
 
     $menu_link = $this->cssSelect('nav.block-menu ul.menu a');
-    $this->assertEqual((string) $menu_link[0], 'Test menu link');
+    $this->assertEqual($menu_link[0]->getText(), 'Test menu link');
 
     // Update the menu link.
     $this->drupalPostForm("admin/structure/menu/link/views_view:views.test_page_display_menu.page_3/edit", [
@@ -123,7 +123,7 @@ public function testPageDisplayMenu() {
 
     $this->drupalGet('<front>');
     $menu_link = $this->cssSelect('nav.block-menu ul.menu a');
-    $this->assertEqual((string) $menu_link[0], 'New title');
+    $this->assertEqual($menu_link[0]->getText(), 'New title');
   }
 
   /**
diff --git a/core/modules/views/src/Tests/Plugin/DisplayTest.php b/core/modules/views/tests/src/Functional/Plugin/DisplayTest.php
similarity index 81%
rename from core/modules/views/src/Tests/Plugin/DisplayTest.php
rename to core/modules/views/tests/src/Functional/Plugin/DisplayTest.php
index 42a389c..927cdda 100644
--- a/core/modules/views/src/Tests/Plugin/DisplayTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/DisplayTest.php
@@ -1,9 +1,8 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\language\Entity\ConfigurableLanguage;
-use Drupal\views\Entity\View;
 use Drupal\views\Views;
 use Drupal\views_test_data\Plugin\views\display\DisplayTest as DisplayTestPlugin;
 
@@ -28,7 +27,7 @@ class DisplayTest extends PluginTestBase {
    */
   public static $modules = ['views_ui', 'node', 'block'];
 
-  protected function setUp() {
+  protected function setUp($import_test_views = TRUE) {
     parent::setUp();
 
     $this->enableViewsTestModule();
@@ -94,6 +93,7 @@ public function testDisplayPlugin() {
     // Check the test option.
     $this->assertIdentical($view->display_handler->getOption('test_option'), '');
 
+    $this->setExpectedException(\PHPUnit_Framework_Error::class);
     $output = $view->preview();
     $output = $renderer->renderRoot($output);
 
@@ -103,6 +103,7 @@ public function testDisplayPlugin() {
     $view->display_handler->overrideOption('test_option', 'Test option title');
     $view->save();
 
+    $this->setExpectedException(\PHPUnit_Framework_Error::class);
     $output = $view->preview();
     $output = $renderer->renderRoot($output);
 
@@ -161,76 +162,6 @@ public function testGetAttachedDisplays() {
   }
 
   /**
-   * Tests the readmore functionality.
-   */
-  public function testReadMore() {
-    /** @var \Drupal\Core\Render\RendererInterface $renderer */
-    $renderer = $this->container->get('renderer');
-
-    if (!isset($this->options['validate']['type'])) {
-      return;
-    }
-    $expected_more_text = 'custom more text';
-
-    $view = Views::getView('test_display_more');
-    $this->executeView($view);
-
-    $output = $view->preview();
-    $output = $renderer->renderRoot($output);
-
-    $this->setRawContent($output);
-    $result = $this->xpath('//a[@class=:class]', [':class' => 'more-link']);
-    $this->assertEqual($result[0]->attributes()->href, \Drupal::url('view.test_display_more.page_1'), 'The right more link is shown.');
-    $this->assertEqual(trim($result[0][0]), $expected_more_text, 'The right link text is shown.');
-
-    // Test the renderMoreLink method directly. This could be directly unit
-    // tested.
-    $more_link = $view->display_handler->renderMoreLink();
-    $more_link = $renderer->renderRoot($more_link);
-    $this->setRawContent($more_link);
-    $result = $this->xpath('//a[@class=:class]', [':class' => 'more-link']);
-    $this->assertEqual($result[0]->attributes()->href, \Drupal::url('view.test_display_more.page_1'), 'The right more link is shown.');
-    $this->assertEqual(trim($result[0][0]), $expected_more_text, 'The right link text is shown.');
-
-    // Test the useMoreText method directly. This could be directly unit
-    // tested.
-    $more_text = $view->display_handler->useMoreText();
-    $this->assertEqual($more_text, $expected_more_text, 'The right more text is chosen.');
-
-    $view = Views::getView('test_display_more');
-    $view->setDisplay();
-    $view->display_handler->setOption('use_more', 0);
-    $this->executeView($view);
-    $output = $view->preview();
-    $output = $renderer->renderRoot($output);
-    $this->setRawContent($output);
-    $result = $this->xpath('//a[@class=:class]', [':class' => 'more-link']);
-    $this->assertTrue(empty($result), 'The more link is not shown.');
-
-    $view = Views::getView('test_display_more');
-    $view->setDisplay();
-    $view->display_handler->setOption('use_more', 0);
-    $view->display_handler->setOption('use_more_always', 0);
-    $view->display_handler->setOption('pager', [
-      'type' => 'some',
-      'options' => [
-        'items_per_page' => 1,
-        'offset' => 0,
-      ],
-    ]);
-    $this->executeView($view);
-    $output = $view->preview();
-    $output = $renderer->renderRoot($output);
-    $this->setRawContent($output);
-    $result = $this->xpath('//a[@class=:class]', [':class' => 'more-link']);
-    $this->assertTrue(empty($result), 'The more link is not shown when view has more records.');
-
-    // Test the default value of use_more_always.
-    $view = View::create()->getExecutable();
-    $this->assertTrue($view->getDisplay()->getOption('use_more_always'), 'Always display the more link by default.');
-  }
-
-  /**
    * Tests the readmore validation.
    */
   public function testReadMoreNoDisplay() {
@@ -290,7 +221,8 @@ public function testInvalidDisplayPlugins() {
 
     $this->drupalGet('<front>');
     $this->assertResponse(200);
-    $this->assertBlockAppears($block);
+    $result = $this->xpath('//div[@id = :id]', [':id' => 'block-' . $block->id()]);
+    $this->assertEquals(1, count($result));
 
     // Change the block plugin ID to an invalid one.
     $config = $this->config('views.view.test_display_invalid');
@@ -302,7 +234,8 @@ public function testInvalidDisplayPlugins() {
     $this->drupalGet('<front>');
     $this->assertResponse(200);
     $this->assertText('The &quot;invalid&quot; plugin does not exist.');
-    $this->assertNoBlockAppears($block);
+    $result = $this->xpath('//div[@id = :id]', [':id' => 'block-' . $block->id()]);
+    $this->assertEquals(0, count($result));
   }
 
   /**
diff --git a/core/modules/views/src/Tests/Plugin/ExposedFormTest.php b/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php
similarity index 91%
rename from core/modules/views/src/Tests/Plugin/ExposedFormTest.php
rename to core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php
index cfb3c0a..d9fe5ce 100644
--- a/core/modules/views/src/Tests/Plugin/ExposedFormTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\Component\Utility\Html;
 use Drupal\entity_test\Entity\EntityTest;
@@ -15,7 +15,7 @@
  *
  * @group views
  */
-class ExposedFormTest extends ViewTestBase {
+class ExposedFormTest extends PluginTestBase {
 
   use AssertPageCacheContextsAndTagsTrait;
 
@@ -33,8 +33,8 @@ class ExposedFormTest extends ViewTestBase {
    */
   public static $modules = ['node', 'views_ui', 'block', 'entity_test'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
 
@@ -192,26 +192,6 @@ public function testResetButton() {
   }
 
   /**
-   * Tests the exposed form markup.
-   */
-  public function testExposedFormRender() {
-    $view = Views::getView('test_exposed_form_buttons');
-    $this->executeView($view);
-    $exposed_form = $view->display_handler->getPlugin('exposed_form');
-    $output = $exposed_form->renderExposedForm();
-    $this->setRawContent(\Drupal::service('renderer')->renderRoot($output));
-
-    $this->assertFieldByXpath('//form/@id', $this->getExpectedExposedFormId($view), 'Expected form ID found.');
-
-    $view->setDisplay('page_1');
-    $expected_action = $view->display_handler->getUrlInfo()->toString();
-    $this->assertFieldByXPath('//form/@action', $expected_action, 'The expected value for the action attribute was found.');
-    // Make sure the description is shown.
-    $result = $this->xpath('//form//div[contains(@id, :id) and normalize-space(text())=:description]', [':id' => 'edit-type--description', ':description' => t('Exposed description')]);
-    $this->assertEqual(count($result), 1, 'Filter description was found.');
-  }
-
-  /**
    * Tests overriding the default render option with checkboxes.
    */
   public function testExposedFormRenderCheckboxes() {
@@ -265,7 +245,8 @@ public function testExposedBlock() {
 
     // Test there is an exposed form in a block.
     $xpath = $this->buildXPathQuery('//div[@id=:id]/form/@id', [':id' => Html::getUniqueId('block-' . $block->id())]);
-    $this->assertFieldByXpath($xpath, $this->getExpectedExposedFormId($view), 'Expected form found in views block.');
+    $result = $this->xpath($xpath);
+    $this->assertEquals(1, count($result));
 
     // Test there is not an exposed form in the view page content area.
     $xpath = $this->buildXPathQuery('//div[@class="view-content"]/form/@id', [':id' => Html::getUniqueId('block-' . $block->id())]);
@@ -381,7 +362,7 @@ protected function assertIds(array $ids) {
     $elements = $this->cssSelect('div.view-test-exposed-form-sort-items-per-page div.views-row span.field-content');
     $actual_ids = [];
     foreach ($elements as $element) {
-      $actual_ids[] = (int) $element;
+      $actual_ids[] = (int) $element->getText();
     }
 
     return $this->assertIdentical($ids, $actual_ids);
diff --git a/core/modules/views/src/Tests/Plugin/FilterTest.php b/core/modules/views/tests/src/Functional/Plugin/FilterTest.php
similarity index 97%
rename from core/modules/views/src/Tests/Plugin/FilterTest.php
rename to core/modules/views/tests/src/Functional/Plugin/FilterTest.php
index 081835f..2f13e7e 100644
--- a/core/modules/views/src/Tests/Plugin/FilterTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/FilterTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\views\Views;
 use Drupal\views_test_data\Plugin\views\filter\FilterTest as FilterPlugin;
@@ -27,8 +27,8 @@ class FilterTest extends PluginTestBase {
    */
   public static $modules = ['views_ui', 'node'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
 
diff --git a/core/modules/views/src/Tests/Plugin/MenuLinkTest.php b/core/modules/views/tests/src/Functional/Plugin/MenuLinkTest.php
similarity index 93%
rename from core/modules/views/src/Tests/Plugin/MenuLinkTest.php
rename to core/modules/views/tests/src/Functional/Plugin/MenuLinkTest.php
index 06e661f..95d17e1 100644
--- a/core/modules/views/src/Tests/Plugin/MenuLinkTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/MenuLinkTest.php
@@ -1,16 +1,15 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\menu_link_content\Entity\MenuLinkContent;
-use Drupal\views\Tests\ViewTestBase;
 
 /**
  * Tests the menu links created in views.
  *
  * @group views
  */
-class MenuLinkTest extends ViewTestBase {
+class MenuLinkTest extends PluginTestBase {
 
   /**
    * Views used by this test.
@@ -36,8 +35,8 @@ class MenuLinkTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
 
diff --git a/core/modules/views/src/Tests/Plugin/MiniPagerTest.php b/core/modules/views/tests/src/Functional/Plugin/MiniPagerTest.php
similarity index 97%
rename from core/modules/views/src/Tests/Plugin/MiniPagerTest.php
rename to core/modules/views/tests/src/Functional/Plugin/MiniPagerTest.php
index 7e9f57a..31f18e3 100644
--- a/core/modules/views/src/Tests/Plugin/MiniPagerTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/MiniPagerTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\views\Views;
 
@@ -33,8 +33,8 @@ class MiniPagerTest extends PluginTestBase {
    */
   protected $nodes;
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->drupalCreateContentType(['type' => 'page']);
     // Create a bunch of test nodes.
diff --git a/core/modules/views/src/Tests/Plugin/NumericFormatPluralTest.php b/core/modules/views/tests/src/Functional/Plugin/NumericFormatPluralTest.php
similarity index 97%
rename from core/modules/views/src/Tests/Plugin/NumericFormatPluralTest.php
rename to core/modules/views/tests/src/Functional/Plugin/NumericFormatPluralTest.php
index d463336..82e726c 100644
--- a/core/modules/views/src/Tests/Plugin/NumericFormatPluralTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/NumericFormatPluralTest.php
@@ -1,17 +1,16 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\Component\Gettext\PoHeader;
 use Drupal\file\Entity\File;
-use Drupal\views\Tests\ViewTestBase;
 
 /**
  * Tests the creation of numeric fields.
  *
  * @group field
  */
-class NumericFormatPluralTest extends ViewTestBase {
+class NumericFormatPluralTest extends PluginTestBase {
 
   /**
    * Modules to enable.
@@ -27,8 +26,8 @@ class NumericFormatPluralTest extends ViewTestBase {
    */
   public static $testViews = ['numeric_test'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $web_user = $this->drupalCreateUser(['administer views', 'administer languages']);
     $this->drupalLogin($web_user);
diff --git a/core/modules/views/src/Tests/Plugin/PagerTest.php b/core/modules/views/tests/src/Functional/Plugin/PagerTest.php
similarity index 99%
rename from core/modules/views/src/Tests/Plugin/PagerTest.php
rename to core/modules/views/tests/src/Functional/Plugin/PagerTest.php
index 6ba4c06..c8535ae 100644
--- a/core/modules/views/src/Tests/Plugin/PagerTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/PagerTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
 use Drupal\views\Views;
diff --git a/core/modules/views/tests/src/Functional/Plugin/PluginTestBase.php b/core/modules/views/tests/src/Functional/Plugin/PluginTestBase.php
new file mode 100644
index 0000000..211e9bb
--- /dev/null
+++ b/core/modules/views/tests/src/Functional/Plugin/PluginTestBase.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace Drupal\Tests\views\Functional\Plugin;
+
+use Drupal\Tests\views\Functional\ViewTestBase;
+
+/**
+ * Views plugin test base.
+ */
+abstract class PluginTestBase extends ViewTestBase {
+
+}
diff --git a/core/modules/views/src/Tests/Plugin/StyleSummaryTest.php b/core/modules/views/tests/src/Functional/Plugin/StyleSummaryTest.php
similarity index 90%
rename from core/modules/views/src/Tests/Plugin/StyleSummaryTest.php
rename to core/modules/views/tests/src/Functional/Plugin/StyleSummaryTest.php
index cbd569c..3f6710c 100644
--- a/core/modules/views/src/Tests/Plugin/StyleSummaryTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/StyleSummaryTest.php
@@ -1,16 +1,15 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\entity_test\Entity\EntityTest;
-use Drupal\views\Tests\ViewTestBase;
 
 /**
  * Tests the summary style plugin.
  *
  * @group views
  */
-class StyleSummaryTest extends ViewTestBase {
+class StyleSummaryTest extends PluginTestBase {
 
   /**
    * {@inheritdoc}
@@ -58,13 +57,13 @@ public function testSummaryView() {
     $this->assertEqual(4, count($summary_list));
 
     foreach ($summary_list as $summary_list_item) {
-      $this->assertEqual('(5)', trim((string) $summary_list_item));
+      $this->assertEqual('(5)', trim(explode(' ', $summary_list_item->getText())[1]));
     }
 
     $summary_links = $this->cssSelect('ul.views-summary a');
     $this->assertEqual(4, count($summary_links));
     foreach ($summary_links as $index => $summary_link) {
-      $this->assertEqual('type' . $index, trim((string) $summary_link));
+      $this->assertEqual('type' . $index, trim($summary_link->getText()));
     }
 
     $this->clickLink('type1');
@@ -100,13 +99,13 @@ public function testSummaryView() {
     $this->assertEqual(3, count($summary_list));
 
     foreach ($summary_list as $summary_list_item) {
-      $this->assertEqual('(5)', trim((string) $summary_list_item));
+      $this->assertEqual('(5)', trim(explode(' ', $summary_list_item->getText())[1]));
     }
 
     $summary_links = $this->cssSelect('.views-summary-unformatted a');
     $this->assertEqual(3, count($summary_links));
     foreach ($summary_links as $index => $summary_link) {
-      $this->assertEqual('type' . $index, trim((string) $summary_link));
+      $this->assertEqual('type' . $index, trim($summary_link->getText()));
     }
 
     $this->clickLink('type1');
diff --git a/core/modules/views/src/Tests/Plugin/StyleTableTest.php b/core/modules/views/tests/src/Functional/Plugin/StyleTableTest.php
similarity index 90%
rename from core/modules/views/src/Tests/Plugin/StyleTableTest.php
rename to core/modules/views/tests/src/Functional/Plugin/StyleTableTest.php
index 537839f..d77facf 100644
--- a/core/modules/views/src/Tests/Plugin/StyleTableTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/StyleTableTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\views\Entity\View;
 
@@ -21,8 +21,8 @@ class StyleTableTest extends PluginTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
@@ -33,17 +33,17 @@ protected function setUp() {
   public function testAccessibilitySettings() {
     $this->drupalGet('test-table');
 
-    $result = $this->xpath('//caption');
+    $result = $this->xpath('//caption/child::text()');
     $this->assertTrue(count($result), 'The caption appears on the table.');
-    $this->assertEqual(trim((string) $result[0]), 'caption-text');
+    $this->assertEqual(trim($result[0]->getText()), 'caption-text');
 
-    $result = $this->xpath('//summary');
+    $result = $this->xpath('//summary/child::text()');
     $this->assertTrue(count($result), 'The summary appears on the table.');
-    $this->assertEqual(trim((string) $result[0]), 'summary-text');
+    $this->assertEqual(trim($result[0]->getText()), 'summary-text');
 
-    $result = $this->xpath('//caption/details');
+    $result = $this->xpath('//caption/details/child::text()');
     $this->assertTrue(count($result), 'The table description appears on the table.');
-    $this->assertEqual(trim((string) $result[0]), 'description-text');
+    $this->assertEqual(trim($result[0]->getText()), 'description-text');
 
     // Remove the caption and ensure the caption is not displayed anymore.
     $view = View::load('test_table');
@@ -52,8 +52,8 @@ public function testAccessibilitySettings() {
     $view->save();
 
     $this->drupalGet('test-table');
-    $result = $this->xpath('//caption');
-    $this->assertFalse(trim((string) $result[0]), 'Ensure that the caption disappears.');
+    $result = $this->xpath('//caption/child::text()');
+    $this->assertFalse(trim($result[0]->getText()), 'Ensure that the caption disappears.');
 
     // Remove the table summary.
     $display = &$view->getDisplay('default');
@@ -61,7 +61,7 @@ public function testAccessibilitySettings() {
     $view->save();
 
     $this->drupalGet('test-table');
-    $result = $this->xpath('//summary');
+    $result = $this->xpath('//summary/child::text()');
     $this->assertFalse(count($result), 'Ensure that the summary disappears.');
 
     // Remove the table description.
@@ -70,7 +70,7 @@ public function testAccessibilitySettings() {
     $view->save();
 
     $this->drupalGet('test-table');
-    $result = $this->xpath('//caption/details');
+    $result = $this->xpath('//caption/details/child::text()');
     $this->assertFalse(count($result), 'Ensure that the description disappears.');
   }
 
diff --git a/core/modules/views/src/Tests/Plugin/StyleTest.php b/core/modules/views/tests/src/Functional/Plugin/StyleTest.php
similarity index 98%
rename from core/modules/views/src/Tests/Plugin/StyleTest.php
rename to core/modules/views/tests/src/Functional/Plugin/StyleTest.php
index e059275..5d6ef22 100644
--- a/core/modules/views/src/Tests/Plugin/StyleTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/StyleTest.php
@@ -1,9 +1,8 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\views\Views;
-use Drupal\views\Tests\ViewTestBase;
 use Drupal\views_test_data\Plugin\views\row\RowTest;
 use Drupal\views\Plugin\views\row\Fields;
 use Drupal\views\ResultRow;
@@ -15,7 +14,7 @@
  * @group views
  * @see \Drupal\views_test_data\Plugin\views\style\StyleTest.
  */
-class StyleTest extends ViewTestBase {
+class StyleTest extends PluginTestBase {
 
   /**
    * Views used by this test.
@@ -31,8 +30,8 @@ class StyleTest extends ViewTestBase {
    */
   protected $elements;
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
diff --git a/core/modules/views/src/Tests/Plugin/ViewsBulkTest.php b/core/modules/views/tests/src/Functional/Plugin/ViewsBulkTest.php
similarity index 92%
rename from core/modules/views/src/Tests/Plugin/ViewsBulkTest.php
rename to core/modules/views/tests/src/Functional/Plugin/ViewsBulkTest.php
index 269f5b0..1790be6 100644
--- a/core/modules/views/src/Tests/Plugin/ViewsBulkTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/ViewsBulkTest.php
@@ -1,15 +1,13 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
-
-use Drupal\simpletest\WebTestBase;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 /**
  * Tests views bulk operation selection.
  *
  * @group views
  */
-class ViewsBulkTest extends WebTestBase {
+class ViewsBulkTest extends PluginTestBase {
 
   /**
    * An admin user
@@ -25,8 +23,8 @@ class ViewsBulkTest extends WebTestBase {
    */
   public static $modules = ['node', 'views'];
 
-  public function setUp() {
-    parent::setUp();
+  public function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->drupalCreateContentType(['type' => 'page']);
     $this->admin_user = $this->createUser(['bypass node access', 'administer nodes', 'access content overview']);
diff --git a/core/modules/views/src/Tests/Plugin/ViewsFormTest.php b/core/modules/views/tests/src/Functional/Plugin/ViewsFormTest.php
similarity index 86%
rename from core/modules/views/src/Tests/Plugin/ViewsFormTest.php
rename to core/modules/views/tests/src/Functional/Plugin/ViewsFormTest.php
index a730189..d953099 100644
--- a/core/modules/views/src/Tests/Plugin/ViewsFormTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/ViewsFormTest.php
@@ -1,15 +1,13 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
-
-use Drupal\simpletest\WebTestBase;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 /**
  * Tests Views forms functionality.
  *
  * @group views
  */
-class ViewsFormTest extends WebTestBase {
+class ViewsFormTest extends PluginTestBase {
 
   /**
    * Modules to enable.
diff --git a/core/modules/views/src/Tests/Plugin/ViewsSqlExceptionTest.php b/core/modules/views/tests/src/Functional/Plugin/ViewsSqlExceptionTest.php
similarity index 91%
rename from core/modules/views/src/Tests/Plugin/ViewsSqlExceptionTest.php
rename to core/modules/views/tests/src/Functional/Plugin/ViewsSqlExceptionTest.php
index d3c93de..c3ab744 100644
--- a/core/modules/views/src/Tests/Plugin/ViewsSqlExceptionTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/ViewsSqlExceptionTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\views\Views;
 use Drupal\Core\Database\DatabaseExceptionWrapper;
@@ -22,8 +22,8 @@ class ViewsSqlExceptionTest extends PluginTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
diff --git a/core/modules/views/src/Tests/RenderCacheWebTest.php b/core/modules/views/tests/src/Functional/RenderCacheWebTest.php
similarity index 83%
rename from core/modules/views/src/Tests/RenderCacheWebTest.php
rename to core/modules/views/tests/src/Functional/RenderCacheWebTest.php
index fcd38b7..f8dfdd8 100644
--- a/core/modules/views/src/Tests/RenderCacheWebTest.php
+++ b/core/modules/views/tests/src/Functional/RenderCacheWebTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 use Drupal\node\Entity\Node;
 
@@ -60,15 +60,15 @@ public function testEmptyView() {
     $this->assertEqual([], $this->cssSelect('div.region-header div.views-field-title'));
 
     $this->drupalGet($this->nodes[0]->toUrl());
-    $result = (string) $this->cssSelect('div.region-header div.views-field-title')[0]->span;
+    $result = $this->cssSelect('div.region-header div.views-field-title')[0]->getText();
     $this->assertEqual('test title 1', $result);
 
     $this->drupalGet($this->nodes[1]->toUrl());
-    $result = (string) $this->cssSelect('div.region-header div.views-field-title')[0]->span;
+    $result = $this->cssSelect('div.region-header div.views-field-title')[0]->getText();
     $this->assertEqual('test title 2', $result);
 
     $this->drupalGet($this->nodes[0]->toUrl());
-    $result = (string) $this->cssSelect('div.region-header div.views-field-title')[0]->span;
+    $result = $this->cssSelect('div.region-header div.views-field-title')[0]->getText();
     $this->assertEqual('test title 1', $result);
   }
 
diff --git a/core/modules/views/src/Tests/SearchIntegrationTest.php b/core/modules/views/tests/src/Functional/SearchIntegrationTest.php
similarity index 89%
rename from core/modules/views/src/Tests/SearchIntegrationTest.php
rename to core/modules/views/tests/src/Functional/SearchIntegrationTest.php
index 1b6ab89..f4daac7 100644
--- a/core/modules/views/src/Tests/SearchIntegrationTest.php
+++ b/core/modules/views/tests/src/Functional/SearchIntegrationTest.php
@@ -1,8 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Tests\Traits\Core\CronRunTrait;
 
 /**
  * Tests search integration filters.
@@ -11,6 +12,8 @@
  */
 class SearchIntegrationTest extends ViewTestBase {
 
+  use CronRunTrait;
+
   /**
    * Modules to enable.
    *
@@ -108,10 +111,10 @@ public function testSearchIntegration() {
     $this->cronRun();
     $this->drupalGet('test-arg/rocks');
     $xpath = '//div[@class="views-row"]//a';
-    /** @var \SimpleXMLElement[] $results */
+    /** @var \Behat\Mink\Element\NodeElement[] $results */
     $results = $this->xpath($xpath);
-    $this->assertEqual((string) $results[0], "Drupal's search rocks <em>really</em> rocks!");
-    $this->assertEqual((string) $results[1], "Drupal's search rocks.");
+    $this->assertEqual($results[0]->getText(), "Drupal's search rocks <em>really</em> rocks!");
+    $this->assertEqual($results[1]->getText(), "Drupal's search rocks.");
     $this->assertEscaped("Drupal's search rocks <em>really</em> rocks!");
 
     // Test sorting with another set of titles.
@@ -127,8 +130,8 @@ public function testSearchIntegration() {
     $xpath = '//div[@class="views-row"]//a';
     /** @var \SimpleXMLElement[] $results */
     $results = $this->xpath($xpath);
-    $this->assertEqual((string) $results[0], "Testing one one one");
-    $this->assertEqual((string) $results[1], "Testing one two two two");
+    $this->assertEqual($results[0]->getText(), "Testing one one one");
+    $this->assertEqual($results[1]->getText(), "Testing one two two two");
   }
 
   /**
diff --git a/core/modules/views/src/Tests/SearchMultilingualTest.php b/core/modules/views/tests/src/Functional/SearchMultilingualTest.php
similarity index 96%
rename from core/modules/views/src/Tests/SearchMultilingualTest.php
rename to core/modules/views/tests/src/Functional/SearchMultilingualTest.php
index f534219..d6a72bf 100644
--- a/core/modules/views/src/Tests/SearchMultilingualTest.php
+++ b/core/modules/views/tests/src/Functional/SearchMultilingualTest.php
@@ -1,9 +1,10 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\node\NodeInterface;
+use Drupal\Tests\Traits\Core\CronRunTrait;
 
 /**
  * Tests search integration filters with multilingual nodes.
@@ -12,6 +13,8 @@
  */
 class SearchMultilingualTest extends ViewTestBase {
 
+  use CronRunTrait;
+
   /**
    * Modules to enable.
    *
diff --git a/core/modules/views/src/Tests/TaxonomyGlossaryTest.php b/core/modules/views/tests/src/Functional/TaxonomyGlossaryTest.php
similarity index 89%
rename from core/modules/views/src/Tests/TaxonomyGlossaryTest.php
rename to core/modules/views/tests/src/Functional/TaxonomyGlossaryTest.php
index ccda887..c34e6f2 100644
--- a/core/modules/views/src/Tests/TaxonomyGlossaryTest.php
+++ b/core/modules/views/tests/src/Functional/TaxonomyGlossaryTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 use Drupal\taxonomy\Tests\TaxonomyTestTrait;
 
@@ -34,8 +34,8 @@ class TaxonomyGlossaryTest extends ViewTestBase {
    */
   protected $taxonomyTerms;
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
 
diff --git a/core/modules/views/src/Tests/ViewRenderTest.php b/core/modules/views/tests/src/Functional/ViewRenderTest.php
similarity index 84%
rename from core/modules/views/src/Tests/ViewRenderTest.php
rename to core/modules/views/tests/src/Functional/ViewRenderTest.php
index 0b3f0ee..aaf894c 100644
--- a/core/modules/views/src/Tests/ViewRenderTest.php
+++ b/core/modules/views/tests/src/Functional/ViewRenderTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 use Drupal\views\Views;
 
@@ -18,8 +18,8 @@ class ViewRenderTest extends ViewTestBase {
    */
   public static $testViews = ['test_view_render'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
diff --git a/core/modules/views/tests/src/Functional/ViewTestBase.php b/core/modules/views/tests/src/Functional/ViewTestBase.php
new file mode 100644
index 0000000..0465f96
--- /dev/null
+++ b/core/modules/views/tests/src/Functional/ViewTestBase.php
@@ -0,0 +1,158 @@
+<?php
+
+namespace Drupal\Tests\views\Functional;
+
+use Behat\Mink\Exception\ElementNotFoundException;
+use Drupal\Core\Database\Query\SelectInterface;
+use Drupal\Tests\BrowserTestBase;
+use Drupal\views\Tests\ViewResultAssertionTrait;
+use Drupal\views\Tests\ViewTestData;
+use Drupal\views\ViewExecutable;
+
+/**
+ * Defines a base class for Views testing in the full web test environment.
+ *
+ * Use this base test class if you need to emulate a full Drupal installation.
+ * When possible, ViewsKernelTestBase should be used instead. Both base classes
+ * include the same methods.
+ *
+ * @see \Drupal\Tests\views\Kernel\ViewsKernelTestBase
+ * @see \Drupal\simpletest\WebTestBase
+ */
+abstract class ViewTestBase extends BrowserTestBase {
+
+  use ViewResultAssertionTrait;
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['views', 'views_test_config'];
+
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp();
+    if ($import_test_views) {
+      ViewTestData::createTestViews(get_class($this), ['views_test_config']);
+    }
+  }
+
+  /**
+   * Sets up the views_test_data.module.
+   *
+   * Because the schema of views_test_data.module is dependent on the test
+   * using it, it cannot be enabled normally.
+   */
+  protected function enableViewsTestModule() {
+    // Define the schema and views data variable before enabling the test module.
+    \Drupal::state()->set('views_test_data_schema', $this->schemaDefinition());
+    \Drupal::state()->set('views_test_data_views_data', $this->viewsData());
+
+    \Drupal::service('module_installer')->install(['views_test_data']);
+    $this->resetAll();
+    $this->rebuildContainer();
+    $this->container->get('module_handler')->reload();
+
+    // Load the test dataset.
+    $data_set = $this->dataSet();
+    $query = db_insert('views_test_data')
+      ->fields(array_keys($data_set[0]));
+    foreach ($data_set as $record) {
+      $query->values($record);
+    }
+    $query->execute();
+  }
+
+  /**
+   * Orders a nested array containing a result set based on a given column.
+   *
+   * @param array $result_set
+   *   An array of rows from a result set, with each row as an associative
+   *   array keyed by column name.
+   * @param string $column
+   *   The column name by which to sort the result set.
+   * @param bool $reverse
+   *   (optional) Boolean indicating whether to sort the result set in reverse
+   *   order. Defaults to FALSE.
+   *
+   * @return array
+   *   The sorted result set.
+   */
+  protected function orderResultSet($result_set, $column, $reverse = FALSE) {
+    $order = $reverse ? -1 : 1;
+    usort($result_set, function ($a, $b) use ($column, $order) {
+      if ($a[$column] == $b[$column]) {
+        return 0;
+      }
+      return $order * (($a[$column] < $b[$column]) ? -1 : 1);
+    });
+    return $result_set;
+  }
+
+  /**
+   * Asserts the existence of a button with a certain ID and label.
+   *
+   * @param string $id
+   *   The HTML ID of the button
+   * @param string $expected_label
+   *   The expected label for the button.
+   * @param string $message
+   *   (optional) A custom message to display with the assertion. If no custom
+   *   message is provided, the message will indicate the button label.
+   *
+   * @throws \Behat\Mink\Exception\ElementNotFoundException
+   */
+  protected function helperButtonHasLabel($id, $expected_label, $message = 'Label has the expected value: %label.') {
+    $xpath = $this->assertSession()->buildXPathQuery('//button[@id=:value]|//input[@id=:value]', [':value' => $id]);
+    $field = $this->getSession()->getPage()->find('xpath', $xpath);
+
+    if (empty($field)) {
+      throw new ElementNotFoundException($this->getSession()->getDriver(), 'form field', 'id', $field);
+    }
+
+    $this->assertEquals($expected_label, $field->getValue());
+  }
+
+  /**
+   * Executes a view with debugging.
+   *
+   * @param \Drupal\views\ViewExecutable $view
+   *   The view object.
+   * @param array $args
+   *   (optional) An array of the view arguments to use for the view.
+   */
+  protected function executeView(ViewExecutable $view, $args = []) {
+    // A view does not really work outside of a request scope, due to many
+    // dependencies like the current user.
+    $view->setDisplay();
+    $view->preExecute($args);
+    $view->execute();
+    $verbose_message = '<pre>Executed view: ' . ((string) $view->build_info['query']) . '</pre>';
+    if ($view->build_info['query'] instanceof SelectInterface) {
+      $verbose_message .= '<pre>Arguments: ' . print_r($view->build_info['query']->getArguments(), TRUE) . '</pre>';
+    }
+    $this->verbose($verbose_message);
+  }
+
+  /**
+   * Returns the schema definition.
+   */
+  protected function schemaDefinition() {
+    return ViewTestData::schemaDefinition();
+  }
+
+  /**
+   * Returns the views data definition.
+   */
+  protected function viewsData() {
+    return ViewTestData::viewsData();
+  }
+
+  /**
+   * Returns a very simple test dataset.
+   */
+  protected function dataSet() {
+    return ViewTestData::dataSet();
+  }
+
+}
diff --git a/core/modules/views/src/Tests/ViewsEscapingTest.php b/core/modules/views/tests/src/Functional/ViewsEscapingTest.php
similarity index 94%
rename from core/modules/views/src/Tests/ViewsEscapingTest.php
rename to core/modules/views/tests/src/Functional/ViewsEscapingTest.php
index 1ec3a9f..80a8398 100644
--- a/core/modules/views/src/Tests/ViewsEscapingTest.php
+++ b/core/modules/views/tests/src/Functional/ViewsEscapingTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 /**
  * Tests output of Views.
@@ -30,8 +30,8 @@ class ViewsEscapingTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp(TRUE);
 
     $this->enableViewsTestModule();
   }
diff --git a/core/modules/views/src/Tests/ViewsFormMultipleTest.php b/core/modules/views/tests/src/Functional/ViewsFormMultipleTest.php
similarity index 81%
rename from core/modules/views/src/Tests/ViewsFormMultipleTest.php
rename to core/modules/views/tests/src/Functional/ViewsFormMultipleTest.php
index 844a1b1..03d5bce 100644
--- a/core/modules/views/src/Tests/ViewsFormMultipleTest.php
+++ b/core/modules/views/tests/src/Functional/ViewsFormMultipleTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 /**
  * Tests a page with multiple Views forms.
@@ -19,8 +19,8 @@ class ViewsFormMultipleTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
@@ -51,9 +51,9 @@ public function testViewsFormMultiple() {
     // Submit the forms, validate argument returned in message set by handler.
     // @note There is not a way to specify a specific index for a submit button. So
     // the row index returned is always the last occurrence.
-    $this->drupalPostForm(NULL, [], t('Test Button'), [], [], 'views-form-test-form-multiple-default-arg2');
+    $this->getSession()->getPage()->pressButton('edit-field-form-button-test-4--2');
     $this->assertText('The test button at row 4 for test_form_multiple (default) View with args: arg2 was submitted.');
-    $this->drupalPostForm(NULL, [], t('Test Button'), [], [], 'views-form-test-form-multiple-default-arg1');
+    $this->getSession()->getPage()->pressButton('edit-field-form-button-test-4');
     $this->assertText('The test button at row 4 for test_form_multiple (default) View with args: arg1 was submitted.');
   }
 
diff --git a/core/modules/views/src/Tests/ViewsTemplateTest.php b/core/modules/views/tests/src/Functional/ViewsTemplateTest.php
similarity index 88%
rename from core/modules/views/src/Tests/ViewsTemplateTest.php
rename to core/modules/views/tests/src/Functional/ViewsTemplateTest.php
index 4a06908..8f7de40 100644
--- a/core/modules/views/src/Tests/ViewsTemplateTest.php
+++ b/core/modules/views/tests/src/Functional/ViewsTemplateTest.php
@@ -1,7 +1,8 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
+use Drupal\views\Tests\ViewTestData;
 use Drupal\views\Views;
 
 /**
@@ -22,7 +23,7 @@ class ViewsTemplateTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
+  protected function setUp($import_test_views = TRUE) {
     parent::setUp(FALSE);
 
     $this->enableViewsTestModule();
diff --git a/core/modules/views/src/Tests/ViewsThemeIntegrationTest.php b/core/modules/views/tests/src/Functional/ViewsThemeIntegrationTest.php
similarity index 95%
rename from core/modules/views/src/Tests/ViewsThemeIntegrationTest.php
rename to core/modules/views/tests/src/Functional/ViewsThemeIntegrationTest.php
index 1fe836a..9bdb405 100644
--- a/core/modules/views/src/Tests/ViewsThemeIntegrationTest.php
+++ b/core/modules/views/tests/src/Functional/ViewsThemeIntegrationTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 /**
  * Tests the Views theme integration.
@@ -33,8 +33,8 @@ class ViewsThemeIntegrationTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
diff --git a/core/modules/views/src/Tests/Wizard/BasicTest.php b/core/modules/views/tests/src/Functional/Wizard/BasicTest.php
similarity index 96%
rename from core/modules/views/src/Tests/Wizard/BasicTest.php
rename to core/modules/views/tests/src/Functional/Wizard/BasicTest.php
index 7394991..27dc2c7 100644
--- a/core/modules/views/src/Tests/Wizard/BasicTest.php
+++ b/core/modules/views/tests/src/Functional/Wizard/BasicTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Wizard;
+namespace Drupal\Tests\views\Functional\Wizard;
 
 use Drupal\Component\Serialization\Json;
 use Drupal\Component\Utility\SafeMarkup;
@@ -14,8 +14,8 @@
  */
 class BasicTest extends WizardTestBase {
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->drupalPlaceBlock('page_title_block');
   }
@@ -80,7 +80,7 @@ public function testViewsWizardAndListing() {
     $elements = $this->cssSelect('link[href="' . Url::fromRoute('view.' . $view2['id'] . '.feed_1', [], ['absolute' => TRUE])->toString() . '"]');
     $this->assertEqual(count($elements), 1, 'Feed found.');
     $this->drupalGet($view2['page[feed_properties][path]']);
-    $this->assertTrue(!empty($this->cssSelect('rss[version="2.0"]')));
+    $this->assertEmpty($this->cssSelect('rss[version="2.0"]'));
     // The feed should have the same title and nodes as the page.
     $this->assertText($view2['page[title]']);
     $this->assertRaw($node1->url('canonical', ['absolute' => TRUE]));
@@ -134,7 +134,7 @@ public function testViewsWizardAndListing() {
 
     // Confirm that the block is available in the block administration UI.
     $this->drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default'));
-    $this->clickLinkPartialName('Place block');
+    $this->clickLink('Place block');
     $this->assertText($view3['label']);
 
     // Place the block.
@@ -164,7 +164,7 @@ public function testViewsWizardAndListing() {
     // Check that the REST export path works.
     $this->drupalGet($view4['rest_export[path]']);
     $this->assertResponse(200);
-    $data = Json::decode($this->content);
+    $data = Json::decode($this->getSession()->getPage()->getContent());
     $this->assertEqual(count($data), 1, 'Only the node of type page is exported.');
     $node = reset($data);
     $this->assertEqual($node['nid'][0]['value'], $node1->id(), 'The node of type page is exported.');
diff --git a/core/modules/views/src/Tests/Wizard/ItemsPerPageTest.php b/core/modules/views/tests/src/Functional/Wizard/ItemsPerPageTest.php
similarity index 95%
rename from core/modules/views/src/Tests/Wizard/ItemsPerPageTest.php
rename to core/modules/views/tests/src/Functional/Wizard/ItemsPerPageTest.php
index 58f22a8..c480ba9 100644
--- a/core/modules/views/src/Tests/Wizard/ItemsPerPageTest.php
+++ b/core/modules/views/tests/src/Functional/Wizard/ItemsPerPageTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Wizard;
+namespace Drupal\Tests\views\Functional\Wizard;
 
 /**
  * Tests the ability of the views wizard to specify the number of items per
@@ -10,8 +10,8 @@
  */
 class ItemsPerPageTest extends WizardTestBase {
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->drupalPlaceBlock('page_title_block');
   }
@@ -72,7 +72,7 @@ public function testItemsPerPage() {
 
     // Confirm that the block is listed in the block administration UI.
     $this->drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default'));
-    $this->clickLinkPartialName('Place block');
+    $this->clickLink('Place block');
     $this->assertText($view['label']);
 
     // Place the block, visit a page that displays the block, and check that the
diff --git a/core/modules/views/src/Tests/Wizard/MenuTest.php b/core/modules/views/tests/src/Functional/Wizard/MenuTest.php
similarity index 97%
rename from core/modules/views/src/Tests/Wizard/MenuTest.php
rename to core/modules/views/tests/src/Functional/Wizard/MenuTest.php
index 0805de6..853c069 100644
--- a/core/modules/views/src/Tests/Wizard/MenuTest.php
+++ b/core/modules/views/tests/src/Functional/Wizard/MenuTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Wizard;
+namespace Drupal\Tests\views\Functional\Wizard;
 
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Url;
diff --git a/core/modules/views/src/Tests/Wizard/NodeWizardTest.php b/core/modules/views/tests/src/Functional/Wizard/NodeWizardTest.php
similarity index 97%
rename from core/modules/views/src/Tests/Wizard/NodeWizardTest.php
rename to core/modules/views/tests/src/Functional/Wizard/NodeWizardTest.php
index dd63efe..41870b6 100644
--- a/core/modules/views/src/Tests/Wizard/NodeWizardTest.php
+++ b/core/modules/views/tests/src/Functional/Wizard/NodeWizardTest.php
@@ -1,7 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Wizard;
-
+namespace Drupal\Tests\views\Functional\Wizard;
 
 /**
  * Tests node wizard and generic entity integration.
diff --git a/core/modules/views/src/Tests/Wizard/PagerTest.php b/core/modules/views/tests/src/Functional/Wizard/PagerTest.php
similarity index 97%
rename from core/modules/views/src/Tests/Wizard/PagerTest.php
rename to core/modules/views/tests/src/Functional/Wizard/PagerTest.php
index 2ec6d55..c8c697c 100644
--- a/core/modules/views/src/Tests/Wizard/PagerTest.php
+++ b/core/modules/views/tests/src/Functional/Wizard/PagerTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Wizard;
+namespace Drupal\Tests\views\Functional\Wizard;
 
 /**
  * Tests the ability of the views wizard to create views without a pager.
diff --git a/core/modules/views/src/Tests/Wizard/SortingTest.php b/core/modules/views/tests/src/Functional/Wizard/SortingTest.php
similarity index 95%
rename from core/modules/views/src/Tests/Wizard/SortingTest.php
rename to core/modules/views/tests/src/Functional/Wizard/SortingTest.php
index 58926aa..07268e3 100644
--- a/core/modules/views/src/Tests/Wizard/SortingTest.php
+++ b/core/modules/views/tests/src/Functional/Wizard/SortingTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Wizard;
+namespace Drupal\Tests\views\Functional\Wizard;
 
 /**
  * Tests the ability of the views wizard to create views with sorts.
@@ -9,8 +9,8 @@
  */
 class SortingTest extends WizardTestBase {
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->drupalPlaceBlock('page_title_block');
   }
diff --git a/core/modules/views/src/Tests/Wizard/TaggedWithTest.php b/core/modules/views/tests/src/Functional/Wizard/TaggedWithTest.php
similarity index 98%
rename from core/modules/views/src/Tests/Wizard/TaggedWithTest.php
rename to core/modules/views/tests/src/Functional/Wizard/TaggedWithTest.php
index f723950..680d644 100644
--- a/core/modules/views/src/Tests/Wizard/TaggedWithTest.php
+++ b/core/modules/views/tests/src/Functional/Wizard/TaggedWithTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Wizard;
+namespace Drupal\Tests\views\Functional\Wizard;
 
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\field\Entity\FieldConfig;
@@ -65,8 +65,8 @@ class TaggedWithTest extends WizardTestBase {
    */
   protected $tagField;
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     // Create two content types. One will have an autocomplete tagging field,
     // and one won't.
diff --git a/core/modules/views/tests/src/Functional/Wizard/WizardTestBase.php b/core/modules/views/tests/src/Functional/Wizard/WizardTestBase.php
new file mode 100644
index 0000000..0178c08
--- /dev/null
+++ b/core/modules/views/tests/src/Functional/Wizard/WizardTestBase.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace Drupal\Tests\views\Functional\Wizard;
+
+use Drupal\Tests\views\Functional\ViewTestBase;
+
+/**
+ * Views UI wizard tests.
+ */
+abstract class WizardTestBase extends ViewTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['node', 'views_ui', 'block', 'rest'];
+
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
+
+    // Create and log in a user with administer views permission.
+    $views_admin = $this->drupalCreateUser(['administer views', 'administer blocks', 'bypass node access', 'access user profiles', 'view all revisions']);
+    $this->drupalLogin($views_admin);
+    $this->drupalPlaceBlock('local_actions_block');
+  }
+
+}
diff --git a/core/modules/views/tests/src/Kernel/Handler/AreaEmptyTest.php b/core/modules/views/tests/src/Kernel/Handler/AreaEmptyTest.php
new file mode 100644
index 0000000..0f209ca
--- /dev/null
+++ b/core/modules/views/tests/src/Kernel/Handler/AreaEmptyTest.php
@@ -0,0 +1,94 @@
+<?php
+
+namespace Drupal\Tests\views\Kernel\Handler;
+
+use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
+use Drupal\views\Views;
+
+/**
+ * Tests the generic entity area handler.
+ *
+ * @group views
+ * @see \Drupal\views\Plugin\views\area\Entity
+ */
+class AreaEmptyTest extends ViewsKernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp();
+    $this->installEntitySchema('node');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function viewsData() {
+    $data = parent::viewsData();
+    $data['views']['test_example'] = [
+      'title' => 'Test Example area',
+      'help' => 'A area handler which just exists for tests.',
+      'area' => [
+        'id' => 'test_example'
+      ]
+    ];
+
+    return $data;
+  }
+
+  /**
+   * Views used by this test.
+   *
+   * @var array
+   */
+  public static $testViews = ['test_example_area'];
+
+  /**
+   * Tests that the header and footer areas are not rendered if empty.
+   */
+  public function testRenderEmptyHeaderFooter() {
+    $view = Views::getView('test_example_area');
+    $view->initHandlers();
+
+    // Set example empty text.
+    $empty_text = $this->randomMachineName();
+    $empty_header = $this->randomMachineName();
+    $empty_footer = $this->randomMachineName();
+
+    // Set empty text.
+    $view->empty['test_example']->options['string'] = '<p>' . $empty_text . '</p>';
+    // Set example header text.
+    $view->header['test_example']->options['string'] = '<p>' . $empty_header . '</p>';
+    // Set example footer text.
+    $view->footer['test_example']->options['string'] = '<p>' . $empty_footer . '</p>';
+
+    // Verify that the empty header and footer sections have not been rendered.
+    $view->setDisplay('default');
+    $this->executeView($view);
+    $output = $view->render();
+    $output = \Drupal::service('renderer')->renderRoot($output);
+    $this->setRawContent($output);
+    $this->assertText($empty_text);
+    $this->assertNoText($empty_header);
+    $this->assertNoText($empty_footer);
+
+    // Enable displaying the header and footer when the View is empty.
+    $view->header['test_example']->options['empty'] = TRUE;
+    $view->footer['test_example']->options['empty'] = TRUE;
+
+    // Verify that the header and footer sections have been rendered.
+    $this->executeView($view);
+    $output = $view->render();
+    $output = \Drupal::service('renderer')->renderRoot($output);
+    $this->setRawContent($output);
+    $this->assertText($empty_header);
+    $this->assertText($empty_footer);
+  }
+
+}
diff --git a/core/modules/views/src/Tests/Plugin/DisplayExtenderTest.php b/core/modules/views/tests/src/Kernel/Plugin/DisplayExtenderTest.php
similarity index 88%
rename from core/modules/views/src/Tests/Plugin/DisplayExtenderTest.php
rename to core/modules/views/tests/src/Kernel/Plugin/DisplayExtenderTest.php
index 896b134..6f7154d 100644
--- a/core/modules/views/src/Tests/Plugin/DisplayExtenderTest.php
+++ b/core/modules/views/tests/src/Kernel/Plugin/DisplayExtenderTest.php
@@ -1,7 +1,8 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Kernel\Plugin;
 
+use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
 use Drupal\views_test_data\Plugin\views\display_extender\DisplayExtenderTest as DisplayExtenderTestData;
 use Drupal\views\Views;
 
@@ -11,7 +12,7 @@
  * @group views
  * @see \Drupal\views_test_data\Plugin\views\display_extender\DisplayExtenderTest
  */
-class DisplayExtenderTest extends PluginTestBase {
+class DisplayExtenderTest extends ViewsKernelTestBase {
 
   /**
    * Views used by this test.
@@ -20,12 +21,6 @@ class DisplayExtenderTest extends PluginTestBase {
    */
   public static $testViews = ['test_view'];
 
-  protected function setUp() {
-    parent::setUp();
-
-    $this->enableViewsTestModule();
-  }
-
   /**
    * Test display extenders.
    */
diff --git a/core/modules/views/tests/src/Kernel/Plugin/DisplayPageTest.php b/core/modules/views/tests/src/Kernel/Plugin/DisplayPageTest.php
index 8aaaa2d..99f7b8a 100644
--- a/core/modules/views/tests/src/Kernel/Plugin/DisplayPageTest.php
+++ b/core/modules/views/tests/src/Kernel/Plugin/DisplayPageTest.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Menu\MenuTreeParameters;
 use Drupal\Core\Session\AnonymousUserSession;
+use Drupal\views\Entity\View;
 use Drupal\views\Views;
 use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
 use Symfony\Component\HttpFoundation\Request;
@@ -22,7 +23,7 @@ class DisplayPageTest extends ViewsKernelTestBase {
    *
    * @var array
    */
-  public static $testViews = ['test_page_display', 'test_page_display_route', 'test_page_display_menu'];
+  public static $testViews = ['test_page_display', 'test_page_display_route', 'test_page_display_menu', 'test_display_more'];
 
   /**
    * Modules to enable.
@@ -149,4 +150,74 @@ public function testDependencies() {
     $this->assertIdentical($expected, $view->getDependencies());
   }
 
+  /**
+   * Tests the readmore functionality.
+   */
+  public function testReadMore() {
+    /** @var \Drupal\Core\Render\RendererInterface $renderer */
+    $renderer = $this->container->get('renderer');
+
+    if (!isset($this->options['validate']['type'])) {
+      return;
+    }
+    $expected_more_text = 'custom more text';
+
+    $view = Views::getView('test_display_more');
+    $this->executeView($view);
+
+    $output = $view->preview();
+    $output = $renderer->renderRoot($output);
+
+    $this->setRawContent($output);
+    $result = $this->xpath('//a[@class=:class]', [':class' => 'more-link']);
+    $this->assertEqual($result[0]->attributes()->href, \Drupal::url('view.test_display_more.page_1'), 'The right more link is shown.');
+    $this->assertEqual(trim($result[0][0]), $expected_more_text, 'The right link text is shown.');
+
+    // Test the renderMoreLink method directly. This could be directly unit
+    // tested.
+    $more_link = $view->display_handler->renderMoreLink();
+    $more_link = $renderer->renderRoot($more_link);
+    $this->setRawContent($more_link);
+    $result = $this->xpath('//a[@class=:class]', [':class' => 'more-link']);
+    $this->assertEqual($result[0]->attributes()->href, \Drupal::url('view.test_display_more.page_1'), 'The right more link is shown.');
+    $this->assertEqual(trim($result[0][0]), $expected_more_text, 'The right link text is shown.');
+
+    // Test the useMoreText method directly. This could be directly unit
+    // tested.
+    $more_text = $view->display_handler->useMoreText();
+    $this->assertEqual($more_text, $expected_more_text, 'The right more text is chosen.');
+
+    $view = Views::getView('test_display_more');
+    $view->setDisplay();
+    $view->display_handler->setOption('use_more', 0);
+    $this->executeView($view);
+    $output = $view->preview();
+    $output = $renderer->renderRoot($output);
+    $this->setRawContent($output);
+    $result = $this->xpath('//a[@class=:class]', [':class' => 'more-link']);
+    $this->assertTrue(empty($result), 'The more link is not shown.');
+
+    $view = Views::getView('test_display_more');
+    $view->setDisplay();
+    $view->display_handler->setOption('use_more', 0);
+    $view->display_handler->setOption('use_more_always', 0);
+    $view->display_handler->setOption('pager', [
+      'type' => 'some',
+      'options' => [
+        'items_per_page' => 1,
+        'offset' => 0,
+      ],
+    ]);
+    $this->executeView($view);
+    $output = $view->preview();
+    $output = $renderer->renderRoot($output);
+    $this->setRawContent($output);
+    $result = $this->xpath('//a[@class=:class]', [':class' => 'more-link']);
+    $this->assertTrue(empty($result), 'The more link is not shown when view has more records.');
+
+    // Test the default value of use_more_always.
+    $view = View::create()->getExecutable();
+    $this->assertTrue($view->getDisplay()->getOption('use_more_always'), 'Always display the more link by default.');
+  }
+
 }
diff --git a/core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php b/core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php
new file mode 100644
index 0000000..6767fff
--- /dev/null
+++ b/core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Drupal\Tests\views\Kernel\Plugin;
+
+use Drupal\Component\Utility\Html;
+use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
+use Drupal\views\Views;
+
+/**
+ * Tests the exposed form markup.
+ *
+ * @group views
+ * @see \Drupal\views_test_data\Plugin\views\display_extender\DisplayExtenderTest
+ */
+class ExposedFormRenderTest extends ViewsKernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $testViews = ['test_exposed_form_buttons'];
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp();
+    $this->installEntitySchema('node');
+  }
+
+  /**
+   * Tests the exposed form markup.
+   */
+  public function testExposedFormRender() {
+    $view = Views::getView('test_exposed_form_buttons');
+    $this->executeView($view);
+    $exposed_form = $view->display_handler->getPlugin('exposed_form');
+    $output = $exposed_form->renderExposedForm();
+    $this->setRawContent(\Drupal::service('renderer')->renderRoot($output));
+
+    $this->assertFieldByXpath('//form/@id', Html::cleanCssIdentifier('views-exposed-form-' . $view->storage->id() . '-' . $view->current_display), 'Expected form ID found.');
+
+    $view->setDisplay('page_1');
+    $expected_action = $view->display_handler->getUrlInfo()->toString();
+    $this->assertFieldByXPath('//form/@action', $expected_action, 'The expected value for the action attribute was found.');
+    // Make sure the description is shown.
+    $result = $this->xpath('//form//div[contains(@id, :id) and normalize-space(text())=:description]', [':id' => 'edit-type--description', ':description' => t('Exposed description')]);
+    $this->assertEqual(count($result), 1, 'Filter description was found.');
+  }
+
+}
