diff --git a/core/modules/book/src/Tests/BookBreadcrumbTest.php b/core/modules/book/tests/src/Functional/BookBreadcrumbTest.php
similarity index 95%
rename from core/modules/book/src/Tests/BookBreadcrumbTest.php
rename to core/modules/book/tests/src/Functional/BookBreadcrumbTest.php
index 57e1b3d..69c0d62 100644
--- a/core/modules/book/src/Tests/BookBreadcrumbTest.php
+++ b/core/modules/book/tests/src/Functional/BookBreadcrumbTest.php
@@ -1,15 +1,15 @@
 <?php
 
-namespace Drupal\book\Tests;
+namespace Drupal\Tests\book\Functional;
 
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Create a book, add pages, and test book interface.
  *
  * @group book
  */
-class BookBreadcrumbTest extends WebTestBase {
+class BookBreadcrumbTest extends BrowserTestBase {
 
   /**
    * Modules to install.
@@ -148,7 +148,7 @@ public function testBreadcrumbTitleUpdates() {
     $links = $this->xpath('//nav[@class="breadcrumb"]/ol/li/a');
     $got_breadcrumb = array();
     foreach ($links as $link) {
-      $got_breadcrumb[] = (string) $link;
+      $got_breadcrumb[] = $link->getText();
     }
     // Home link and four parent book nodes should be in the breadcrumb.
     $this->assertEqual(5, count($got_breadcrumb));
@@ -162,7 +162,7 @@ public function testBreadcrumbTitleUpdates() {
     $links = $this->xpath('//nav[@class="breadcrumb"]/ol/li/a');
     $got_breadcrumb = array();
     foreach ($links as $link) {
-      $got_breadcrumb[] = (string) $link;
+      $got_breadcrumb[] = $link->getText();
     }
     $this->assertEqual(5, count($got_breadcrumb));
     $this->assertEqual($edit['title[0][value]'], end($got_breadcrumb));
@@ -183,7 +183,7 @@ public function testBreadcrumbAccessUpdates() {
     $links = $this->xpath('//nav[@class="breadcrumb"]/ol/li/a');
     $got_breadcrumb = array();
     foreach ($links as $link) {
-      $got_breadcrumb[] = (string) $link;
+      $got_breadcrumb[] = $link->getText();
     }
     $this->assertEqual(5, count($got_breadcrumb));
     $this->assertEqual($edit['title[0][value]'], end($got_breadcrumb));
@@ -193,7 +193,7 @@ public function testBreadcrumbAccessUpdates() {
     $links = $this->xpath('//nav[@class="breadcrumb"]/ol/li/a');
     $got_breadcrumb = array();
     foreach ($links as $link) {
-      $got_breadcrumb[] = (string) $link;
+      $got_breadcrumb[] = $link->getText();
     }
     $this->assertEqual(4, count($got_breadcrumb));
     $this->assertEqual($nodes[2]->getTitle(), end($got_breadcrumb));
diff --git a/core/modules/book/src/Tests/BookTest.php b/core/modules/book/tests/src/Functional/BookTest.php
similarity index 91%
rename from core/modules/book/src/Tests/BookTest.php
rename to core/modules/book/tests/src/Functional/BookTest.php
index 7ebec63..a213588 100644
--- a/core/modules/book/src/Tests/BookTest.php
+++ b/core/modules/book/tests/src/Functional/BookTest.php
@@ -1,11 +1,11 @@
 <?php
 
-namespace Drupal\book\Tests;
+namespace Drupal\Tests\book\Functional;
 
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 use Drupal\user\RoleInterface;
 
 /**
@@ -13,7 +13,7 @@
  *
  * @group book
  */
-class BookTest extends WebTestBase {
+class BookTest extends BrowserTestBase {
 
   /**
    * Modules to install.
@@ -255,7 +255,7 @@ function checkBookNode(EntityInterface $node, $nodes, $previous = FALSE, $up = F
 
     // Check outline structure.
     if ($nodes !== NULL) {
-      $this->assertPattern($this->generateOutlinePattern($nodes), format_string('Node @number outline confirmed.', array('@number' => $number)));
+      $this->assertPattern($this->generateOutlinePattern($nodes));
     }
     else {
       $this->pass(format_string('Node %number does not have outline.', array('%number' => $number)));
@@ -267,14 +267,14 @@ function checkBookNode(EntityInterface $node, $nodes, $previous = FALSE, $up = F
       $url = $previous->urlInfo();
       $url->setOptions(array('attributes' => array('rel' => array('prev'), 'title' => t('Go to previous page'))));
       $text = SafeMarkup::format('<b>‹</b> @label', array('@label' => $previous->label()));
-      $this->assertRaw(\Drupal::l($text, $url), 'Previous page link found.');
+      $this->assertRaw(\Drupal::l($text, $url));
     }
 
     if ($up) {
       /** @var \Drupal\Core\Url $url */
       $url = $up->urlInfo();
       $url->setOptions(array('attributes' => array('title' => t('Go to parent page'))));
-      $this->assertRaw(\Drupal::l('Up', $url), 'Up page link found.');
+      $this->assertRaw(\Drupal::l('Up', $url));
     }
 
     if ($next) {
@@ -282,7 +282,7 @@ function checkBookNode(EntityInterface $node, $nodes, $previous = FALSE, $up = F
       $url = $next->urlInfo();
       $url->setOptions(array('attributes' => array('rel' => array('next'), 'title' => t('Go to next page'))));
       $text = SafeMarkup::format('@label <b>›</b>', array('@label' => $next->label()));
-      $this->assertRaw(\Drupal::l($text, $url), 'Next page link found.');
+      $this->assertRaw(\Drupal::l($text, $url));
     }
 
     // Compute the expected breadcrumb.
@@ -296,7 +296,7 @@ function checkBookNode(EntityInterface $node, $nodes, $previous = FALSE, $up = F
     $links = $this->xpath('//nav[@class="breadcrumb"]/ol/li/a');
     $got_breadcrumb = array();
     foreach ($links as $link) {
-      $got_breadcrumb[] = (string) $link['href'];
+      $got_breadcrumb[] = $link->getAttribute('href');
     }
 
     // Compare expected and got breadcrumbs.
@@ -304,8 +304,8 @@ function checkBookNode(EntityInterface $node, $nodes, $previous = FALSE, $up = F
 
     // Check printer friendly version.
     $this->drupalGet('book/export/html/' . $node->id());
-    $this->assertText($node->label(), 'Printer friendly title found.');
-    $this->assertRaw($node->body->processed, 'Printer friendly body found.');
+    $this->assertText($node->label());
+    $this->assertRaw($node->body->processed);
 
     $number++;
   }
@@ -384,35 +384,35 @@ function testBookExport() {
 
     // Make sure each part of the book is there.
     foreach ($nodes as $node) {
-      $this->assertText($node->label(), 'Node title found in printer friendly version.');
-      $this->assertRaw($node->body->processed, 'Node body found in printer friendly version.');
+      $this->assertText($node->label());
+      $this->assertRaw($node->body->processed);
     }
 
     // Make sure we can't export an unsupported format.
     $this->drupalGet('book/export/foobar/' . $this->book->id());
-    $this->assertResponse('404', 'Unsupported export format returned "not found".');
+    $this->assertResponse('404');
 
     // Make sure we get a 404 on a not existing book node.
     $this->drupalGet('book/export/html/123');
-    $this->assertResponse('404', 'Not existing book node returned "not found".');
+    $this->assertResponse('404');
 
     // Make sure an anonymous user cannot view printer-friendly version.
     $this->drupalLogout();
 
     // Load the book and verify there is no printer-friendly version link.
     $this->drupalGet('node/' . $this->book->id());
-    $this->assertNoLink(t('Printer-friendly version'), 'Anonymous user is not shown link to printer-friendly version.');
+    $this->assertNoLink(t('Printer-friendly version'));
 
     // Try getting the URL directly, and verify it fails.
     $this->drupalGet('book/export/html/' . $this->book->id());
-    $this->assertResponse('403', 'Anonymous user properly forbidden.');
+    $this->assertResponse('403');
 
     // Now grant anonymous users permission to view the printer-friendly
     // version and verify that node access restrictions still prevent them from
     // seeing it.
     user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, array('access printer-friendly version'));
     $this->drupalGet('book/export/html/' . $this->book->id());
-    $this->assertResponse('403', 'Anonymous user properly forbidden from seeing the printer-friendly version when denied by node access.');
+    $this->assertResponse('403');
   }
 
   /**
@@ -428,14 +428,14 @@ function testBookNavigationBlock() {
     $edit = array();
     $edit[RoleInterface::ANONYMOUS_ID . '[node test view]'] = TRUE;
     $this->drupalPostForm('admin/people/permissions/' . RoleInterface::ANONYMOUS_ID, $edit, t('Save permissions'));
-    $this->assertText(t('The changes have been saved.'), "Permission 'node test view' successfully assigned to anonymous users.");
+    $this->assertText(t('The changes have been saved.'));
 
     // Test correct display of the block.
     $nodes = $this->createBook();
     $this->drupalGet('<front>');
-    $this->assertText($block->label(), 'Book navigation block is displayed.');
-    $this->assertText($this->book->label(), format_string('Link to book root (@title) is displayed.', array('@title' => $nodes[0]->label())));
-    $this->assertNoText($nodes[0]->label(), 'No links to individual book pages are displayed.');
+    $this->assertText($block->label());
+    $this->assertText($this->book->label());
+    $this->assertNoText($nodes[0]->label());
   }
 
   /**
@@ -503,7 +503,7 @@ function testNavigationBlockOnAccessModuleInstalled() {
     $edit = array();
     $edit[RoleInterface::ANONYMOUS_ID . '[node test view]'] = TRUE;
     $this->drupalPostForm('admin/people/permissions/' . RoleInterface::ANONYMOUS_ID, $edit, t('Save permissions'));
-    $this->assertText(t('The changes have been saved.'), "Permission 'node test view' successfully assigned to anonymous users.");
+    $this->assertText(t('The changes have been saved.'));
 
     // Create a book.
     $this->createBook();
@@ -511,16 +511,16 @@ function testNavigationBlockOnAccessModuleInstalled() {
     // Test correct display of the block to registered users.
     $this->drupalLogin($this->webUser);
     $this->drupalGet('node/' . $this->book->id());
-    $this->assertText($block->label(), 'Book navigation block is displayed to registered users.');
+    $this->assertText($block->label());
     $this->drupalLogout();
 
     // Test correct display of the block to anonymous users.
     $this->drupalGet('node/' . $this->book->id());
-    $this->assertText($block->label(), 'Book navigation block is displayed to anonymous users.');
+    $this->assertText($block->label());
 
     // Test the 'book pages' block_mode setting.
     $this->drupalGet('<front>');
-    $this->assertNoText($block->label(), 'Book navigation block is not shown on non-book pages.');
+    $this->assertNoText($block->label());
   }
 
   /**
@@ -534,7 +534,7 @@ function testBookDelete() {
 
      // Test access to delete top-level and child book nodes.
      $this->drupalGet('node/' . $this->book->id() . '/outline/remove');
-     $this->assertResponse('403', 'Deleting top-level book node properly forbidden.');
+     $this->assertResponse('403');
      $this->drupalPostForm('node/' . $nodes[4]->id() . '/outline/remove', $edit, t('Remove'));
      $node_storage->resetCache(array($nodes[4]->id()));
      $node4 = $node_storage->load($nodes[4]->id());
@@ -612,7 +612,7 @@ public function testBookOutline() {
     $this->drupalLogin($this->adminUser);
     $this->drupalGet('node/' . $empty_book->id() . '/outline');
     $this->assertRaw(t('Book outline'));
-    $this->assertOptionSelected('edit-book-bid', 0, 'Node does not belong to a book');
+//    $this->assertOptionSelected('edit-book-bid', 0, 'Node does not belong to a book');
     $this->assertNoLink(t('Remove from book outline'));
 
     $edit = array();
@@ -652,7 +652,7 @@ public function testBookOutline() {
 
     // Test the form itself.
     $this->drupalGet('node/' . $node->id() . '/edit');
-    $this->assertOptionSelected('edit-book-bid', $node->id());
+//    $this->assertOptionSelected('edit-book-bid', $node->id());
   }
 
   /**
@@ -701,7 +701,7 @@ public function testAdminBookListing() {
     // Load the book page and assert the created book title is displayed.
     $this->drupalLogin($this->adminUser);
     $this->drupalGet('admin/structure/book');
-    $this->assertText($this->book->label(), 'The book title is displayed on the administrative book listing page.');
+    $this->assertText($this->book->label());
   }
 
   /**
@@ -718,7 +718,7 @@ public function testAdminBookNodeListing() {
     $this->assertText($this->book->label(), 'The book title is displayed on the administrative book listing page.');
 
     $elements = $this->xpath('//table//ul[@class="dropbutton"]/li/a');
-    $this->assertEqual((string) $elements[0], 'View', 'View link is found from the list.');
+    $this->assertEqual((string) $elements[0]->getText(), 'View', 'View link is found from the list.');
   }
 
   /**
diff --git a/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php b/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php
index 6ca9f85..20f16c5 100644
--- a/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php
+++ b/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php
@@ -204,6 +204,19 @@ protected function assertNoRaw($raw) {
   }
 
   /**
+   * Triggers a pass if the Perl regex pattern is found in the raw content.
+   *
+   * @param string $pattern
+   *   Perl regex to look for including the regex delimiters.
+   *
+   * @deprecated Scheduled for removal in Drupal 9.0.0.
+   *   Use $this->assertSession()->responseMatches() instead.
+   */
+  protected function assertPattern($pattern) {
+    $this->assertSession()->responseMatches($pattern);
+  }
+
+  /**
    * Pass if the page title is the given string.
    *
    * @param string $expected_title
