diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentActionsTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentActionsTest.php
index 3190e8b..4a2e9ca 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentActionsTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentActionsTest.php
@@ -11,6 +11,14 @@
  * Tests actions provided by the Comment module.
  */
 class CommentActionsTest extends CommentTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('dblog');
+
   public static function getInfo() {
     return array(
       'name' => 'Comment actions',
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentAnonymousTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentAnonymousTest.php
index 66eba33..9053928 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentAnonymousTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentAnonymousTest.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Definition of Drupal\comment\Tests\CommentAnonymousTest.
+ * Contains Drupal\comment\Tests\CommentAnonymousTest.
  */
 
 namespace Drupal\comment\Tests;
@@ -11,6 +11,16 @@
  * Tests anonymous commenting.
  */
 class CommentAnonymousTest extends CommentTestBase {
+
+  /**
+   * Use the standard profile.
+   *
+   * @var string
+   *
+   * @todo Remove this dependency if possible.
+   */
+  protected $profile = 'standard';
+
   public static function getInfo() {
     return array(
       'name' => 'Anonymous comments',
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentBlockTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentBlockTest.php
index fc6aabe..0ec3af2 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentBlockTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentBlockTest.php
@@ -11,6 +11,28 @@
  * Tests the Comment module blocks.
  */
 class CommentBlockTest extends CommentTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('block');
+
+  function setUp() {
+    parent::setUp();
+    // Update admin user to have the 'administer blocks' permission.
+    $this->admin_user = $this->drupalCreateUser(array(
+      'administer content types',
+      'administer comments',
+      'skip comment approval',
+      'post comments',
+      'access comments',
+      'access content',
+      'administer blocks',
+     ));
+  }
+
   public static function getInfo() {
     return array(
       'name' => 'Comment blocks',
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentCSSTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentCSSTest.php
new file mode 100644
index 0000000..f40c0d5
--- /dev/null
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentCSSTest.php
@@ -0,0 +1,140 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\comment\Tests\CommentCSSTest.
+ */
+
+namespace Drupal\comment\Tests;
+
+/**
+ * Tests comment CSS classes.
+ */
+class CommentCSSTest extends CommentTestBase {
+
+  /**
+   * Use the standard profile.
+   *
+   * @var string
+   *
+   * @todo Are these dependent on a particular theme? Remove this dependency
+   *   if possible.
+   */
+  protected $profile = 'standard';
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Comment CSS',
+      'description' => 'Tests CSS classes on comments.',
+      'group' => 'Comment',
+    );
+  }
+
+  /**
+   * Tests CSS classes on comments.
+   */
+  function testCommentClasses() {
+    // Create all permutations for comments, users, and nodes.
+    $parameters = array(
+      'node_uid' => array(0, $this->web_user->uid),
+      'comment_uid' => array(0, $this->web_user->uid, $this->admin_user->uid),
+      'comment_status' => array(COMMENT_PUBLISHED, COMMENT_NOT_PUBLISHED),
+      'user' => array('anonymous', 'authenticated', 'admin'),
+    );
+    $permutations = $this->generatePermutations($parameters);
+
+    foreach ($permutations as $case) {
+      // Create a new node.
+      $node = $this->drupalCreateNode(array('type' => 'article', 'uid' => $case['node_uid']));
+
+      // Add a comment.
+      $comment = entity_create('comment', array(
+        'nid' => $node->nid,
+        'uid' => $case['comment_uid'],
+        'status' => $case['comment_status'],
+        'subject' => $this->randomName(),
+        'language' => LANGUAGE_NOT_SPECIFIED,
+        'comment_body' => array(LANGUAGE_NOT_SPECIFIED => array($this->randomName())),
+      ));
+      comment_save($comment);
+
+      // Adjust the current/viewing user.
+      switch ($case['user']) {
+        case 'anonymous':
+          if ($this->loggedInUser) {
+            $this->drupalLogout();
+          }
+          $case['user_uid'] = 0;
+          break;
+
+        case 'authenticated':
+          $this->drupalLogin($this->web_user);
+          $case['user_uid'] = $this->web_user->uid;
+          break;
+
+        case 'admin':
+          $this->drupalLogin($this->admin_user);
+          $case['user_uid'] = $this->admin_user->uid;
+          break;
+      }
+      // Request the node with the comment.
+      $this->drupalGet('node/' . $node->nid);
+
+      // Verify classes if the comment is visible for the current user.
+      if ($case['comment_status'] == COMMENT_PUBLISHED || $case['user'] == 'admin') {
+        // Verify the by-anonymous class.
+        $comments = $this->xpath('//*[contains(@class, "comment") and contains(@class, "by-anonymous")]');
+        if ($case['comment_uid'] == 0) {
+          $this->assertTrue(count($comments) == 1, 'by-anonymous class found.');
+        }
+        else {
+          $this->assertFalse(count($comments), 'by-anonymous class not found.');
+        }
+
+        // Verify the by-node-author class.
+        $comments = $this->xpath('//*[contains(@class, "comment") and contains(@class, "by-node-author")]');
+        if ($case['comment_uid'] > 0 && $case['comment_uid'] == $case['node_uid']) {
+          $this->assertTrue(count($comments) == 1, 'by-node-author class found.');
+        }
+        else {
+          $this->assertFalse(count($comments), 'by-node-author class not found.');
+        }
+
+        // Verify the by-viewer class.
+        $comments = $this->xpath('//*[contains(@class, "comment") and contains(@class, "by-viewer")]');
+        if ($case['comment_uid'] > 0 && $case['comment_uid'] == $case['user_uid']) {
+          $this->assertTrue(count($comments) == 1, 'by-viewer class found.');
+        }
+        else {
+          $this->assertFalse(count($comments), 'by-viewer class not found.');
+        }
+      }
+
+      // Verify the unpublished class.
+      $comments = $this->xpath('//*[contains(@class, "comment") and contains(@class, "unpublished")]');
+      if ($case['comment_status'] == COMMENT_NOT_PUBLISHED && $case['user'] == 'admin') {
+        $this->assertTrue(count($comments) == 1, 'unpublished class found.');
+      }
+      else {
+        $this->assertFalse(count($comments), 'unpublished class not found.');
+      }
+
+      // Verify the new class.
+      if ($case['comment_status'] == COMMENT_PUBLISHED || $case['user'] == 'admin') {
+        $comments = $this->xpath('//*[contains(@class, "comment") and contains(@class, "new")]');
+        if ($case['user'] != 'anonymous') {
+          $this->assertTrue(count($comments) == 1, 'new class found.');
+
+          // Request the node again. The new class should disappear.
+          $this->drupalGet('node/' . $node->nid);
+          $comments = $this->xpath('//*[contains(@class, "comment") and contains(@class, "new")]');
+          $this->assertFalse(count($comments), 'new class not found.');
+        }
+        else {
+          $this->assertFalse(count($comments), 'new class not found.');
+        }
+      }
+    }
+  }
+
+}
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php
index 43f9cc3..ab03d41 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php
@@ -11,6 +11,14 @@
  * Tests fields on comments.
  */
 class CommentFieldsTest extends CommentTestBase {
+
+  /**
+   * Enable the field UI.
+   *
+   * @var array
+   */
+  public static $modules = array('field_ui');
+
   public static function getInfo() {
     return array(
       'name' => 'Comment fields',
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentInterfaceTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentInterfaceTest.php
index a2e5dfd..00650d6 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentInterfaceTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentInterfaceTest.php
@@ -7,7 +7,20 @@
 
 namespace Drupal\comment\Tests;
 
+/**
+ * Tests the comment module administrative and end-user-facing interfaces.
+ */
 class CommentInterfaceTest extends CommentTestBase {
+
+  /**
+   * Use the standard profile.
+   *
+   * @var string
+   *
+   * @todo Remove this dependency.
+   */
+  protected $profile = 'standard';
+
   public static function getInfo() {
     return array(
       'name' => 'Comment interface',
@@ -176,246 +189,6 @@ function testCommentInterface() {
   }
 
   /**
-   * Tests new comment marker.
-   */
-  public function testCommentNewCommentsIndicator() {
-    // Test if the right links are displayed when no comment is present for the
-    // node.
-    $this->drupalLogin($this->admin_user);
-    $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => COMMENT_NODE_OPEN));
-    $this->drupalGet('node');
-    $this->assertNoLink(t('@count comments', array('@count' => 0)));
-    $this->assertNoLink(t('@count new comments', array('@count' => 0)));
-    $this->assertLink(t('Read more'));
-    $count = $this->xpath('//div[@id=:id]/div[@class=:class]/ul/li', array(':id' => 'node-' . $this->node->nid, ':class' => 'link-wrapper'));
-    $this->assertTrue(count($count) == 1, 'One child found');
-
-    // Create a new comment. This helper function may be run with different
-    // comment settings so use comment_save() to avoid complex setup.
-    $comment = entity_create('comment', array(
-      'cid' => NULL,
-      'nid' => $this->node->nid,
-      'node_type' => $this->node->type,
-      'pid' => 0,
-      'uid' => $this->loggedInUser->uid,
-      'status' => COMMENT_PUBLISHED,
-      'subject' => $this->randomName(),
-      'hostname' => ip_address(),
-      'langcode' => LANGUAGE_NOT_SPECIFIED,
-      'comment_body' => array(LANGUAGE_NOT_SPECIFIED => array($this->randomName())),
-    ));
-    comment_save($comment);
-    $this->drupalLogout();
-
-    // Log in with 'web user' and check comment links.
-    $this->drupalLogin($this->web_user);
-    $this->drupalGet('node');
-    $this->assertLink(t('1 new comment'));
-    $this->clickLink(t('1 new comment'));
-    $this->assertRaw('<a id="new"></a>', 'Found "new" marker.');
-    $this->assertTrue($this->xpath('//a[@id=:new]/following-sibling::a[1][@id=:comment_id]', array(':new' => 'new', ':comment_id' => 'comment-1')), 'The "new" anchor is positioned at the right comment.');
-
-    // Test if "new comment" link is correctly removed.
-    $this->drupalGet('node');
-    $this->assertLink(t('1 comment'));
-    $this->assertLink(t('Read more'));
-    $this->assertNoLink(t('1 new comment'));
-    $this->assertNoLink(t('@count new comments', array('@count' => 0)));
-    $count = $this->xpath('//div[@id=:id]/div[@class=:class]/ul/li', array(':id' => 'node-' . $this->node->nid, ':class' => 'link-wrapper'));
-    $this->assertTrue(count($count) == 2, print_r($count, TRUE));
-  }
-
-  /**
-   * Tests CSS classes on comments.
-   */
-  function testCommentClasses() {
-    // Create all permutations for comments, users, and nodes.
-    $parameters = array(
-      'node_uid' => array(0, $this->web_user->uid),
-      'comment_uid' => array(0, $this->web_user->uid, $this->admin_user->uid),
-      'comment_status' => array(COMMENT_PUBLISHED, COMMENT_NOT_PUBLISHED),
-      'user' => array('anonymous', 'authenticated', 'admin'),
-    );
-    $permutations = $this->generatePermutations($parameters);
-
-    foreach ($permutations as $case) {
-      // Create a new node.
-      $node = $this->drupalCreateNode(array('type' => 'article', 'uid' => $case['node_uid']));
-
-      // Add a comment.
-      $comment = entity_create('comment', array(
-        'nid' => $node->nid,
-        'uid' => $case['comment_uid'],
-        'status' => $case['comment_status'],
-        'subject' => $this->randomName(),
-        'language' => LANGUAGE_NOT_SPECIFIED,
-        'comment_body' => array(LANGUAGE_NOT_SPECIFIED => array($this->randomName())),
-      ));
-      comment_save($comment);
-
-      // Adjust the current/viewing user.
-      switch ($case['user']) {
-        case 'anonymous':
-          if ($this->loggedInUser) {
-            $this->drupalLogout();
-          }
-          $case['user_uid'] = 0;
-          break;
-
-        case 'authenticated':
-          $this->drupalLogin($this->web_user);
-          $case['user_uid'] = $this->web_user->uid;
-          break;
-
-        case 'admin':
-          $this->drupalLogin($this->admin_user);
-          $case['user_uid'] = $this->admin_user->uid;
-          break;
-      }
-      // Request the node with the comment.
-      $this->drupalGet('node/' . $node->nid);
-
-      // Verify classes if the comment is visible for the current user.
-      if ($case['comment_status'] == COMMENT_PUBLISHED || $case['user'] == 'admin') {
-        // Verify the by-anonymous class.
-        $comments = $this->xpath('//*[contains(@class, "comment") and contains(@class, "by-anonymous")]');
-        if ($case['comment_uid'] == 0) {
-          $this->assertTrue(count($comments) == 1, 'by-anonymous class found.');
-        }
-        else {
-          $this->assertFalse(count($comments), 'by-anonymous class not found.');
-        }
-
-        // Verify the by-node-author class.
-        $comments = $this->xpath('//*[contains(@class, "comment") and contains(@class, "by-node-author")]');
-        if ($case['comment_uid'] > 0 && $case['comment_uid'] == $case['node_uid']) {
-          $this->assertTrue(count($comments) == 1, 'by-node-author class found.');
-        }
-        else {
-          $this->assertFalse(count($comments), 'by-node-author class not found.');
-        }
-
-        // Verify the by-viewer class.
-        $comments = $this->xpath('//*[contains(@class, "comment") and contains(@class, "by-viewer")]');
-        if ($case['comment_uid'] > 0 && $case['comment_uid'] == $case['user_uid']) {
-          $this->assertTrue(count($comments) == 1, 'by-viewer class found.');
-        }
-        else {
-          $this->assertFalse(count($comments), 'by-viewer class not found.');
-        }
-      }
-
-      // Verify the unpublished class.
-      $comments = $this->xpath('//*[contains(@class, "comment") and contains(@class, "unpublished")]');
-      if ($case['comment_status'] == COMMENT_NOT_PUBLISHED && $case['user'] == 'admin') {
-        $this->assertTrue(count($comments) == 1, 'unpublished class found.');
-      }
-      else {
-        $this->assertFalse(count($comments), 'unpublished class not found.');
-      }
-
-      // Verify the new class.
-      if ($case['comment_status'] == COMMENT_PUBLISHED || $case['user'] == 'admin') {
-        $comments = $this->xpath('//*[contains(@class, "comment") and contains(@class, "new")]');
-        if ($case['user'] != 'anonymous') {
-          $this->assertTrue(count($comments) == 1, 'new class found.');
-
-          // Request the node again. The new class should disappear.
-          $this->drupalGet('node/' . $node->nid);
-          $comments = $this->xpath('//*[contains(@class, "comment") and contains(@class, "new")]');
-          $this->assertFalse(count($comments), 'new class not found.');
-        }
-        else {
-          $this->assertFalse(count($comments), 'new class not found.');
-        }
-      }
-    }
-  }
-
-  /**
-   * Tests the node comment statistics.
-   */
-  function testCommentNodeCommentStatistics() {
-    $langcode = LANGUAGE_NOT_SPECIFIED;
-    // Set comments to have subject and preview disabled.
-    $this->drupalLogin($this->admin_user);
-    $this->setCommentPreview(DRUPAL_DISABLED);
-    $this->setCommentForm(TRUE);
-    $this->setCommentSubject(FALSE);
-    $this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Comment paging changed.');
-    $this->drupalLogout();
-
-    // Creates a second user to post comments.
-    $this->web_user2 = $this->drupalCreateUser(array('access comments', 'post comments', 'create article content', 'edit own comments'));
-
-    // Checks the initial values of node comment statistics with no comment.
-    $node = node_load($this->node->nid);
-    $this->assertEqual($node->last_comment_timestamp, $this->node->created, 'The initial value of node last_comment_timestamp is the node created date.');
-    $this->assertEqual($node->last_comment_name, NULL, 'The initial value of node last_comment_name is NULL.');
-    $this->assertEqual($node->last_comment_uid, $this->web_user->uid, 'The initial value of node last_comment_uid is the node uid.');
-    $this->assertEqual($node->comment_count, 0, 'The initial value of node comment_count is zero.');
-
-    // Post comment #1 as web_user2.
-    $this->drupalLogin($this->web_user2);
-    $comment_text = $this->randomName();
-    $comment = $this->postComment($this->node, $comment_text);
-    $comment_loaded = comment_load($comment->id);
-
-    // Checks the new values of node comment statistics with comment #1.
-    // The node needs to be reloaded with a node_load_multiple cache reset.
-    $node = node_load($this->node->nid, TRUE);
-    $this->assertEqual($node->last_comment_name, NULL, 'The value of node last_comment_name is NULL.');
-    $this->assertEqual($node->last_comment_uid, $this->web_user2->uid, 'The value of node last_comment_uid is the comment #1 uid.');
-    $this->assertEqual($node->comment_count, 1, 'The value of node comment_count is 1.');
-
-    // Prepare for anonymous comment submission (comment approval enabled).
-    config('user.settings')->set('register', USER_REGISTER_VISITORS)->save();
-    $this->drupalLogin($this->admin_user);
-    user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array(
-      'access comments' => TRUE,
-      'post comments' => TRUE,
-      'skip comment approval' => FALSE,
-    ));
-    // Ensure that the poster can leave some contact info.
-    $this->setCommentAnonymous('1');
-    $this->drupalLogout();
-
-    // Post comment #2 as anonymous (comment approval enabled).
-    $this->drupalGet('comment/reply/' . $this->node->nid);
-    $anonymous_comment = $this->postComment($this->node, $this->randomName(), '', TRUE);
-    $comment_unpublished_loaded = comment_load($anonymous_comment->id);
-
-    // Checks the new values of node comment statistics with comment #2 and
-    // ensure they haven't changed since the comment has not been moderated.
-    // The node needs to be reloaded with a node_load_multiple cache reset.
-    $node = node_load($this->node->nid, TRUE);
-    $this->assertEqual($node->last_comment_name, NULL, 'The value of node last_comment_name is still NULL.');
-    $this->assertEqual($node->last_comment_uid, $this->web_user2->uid, 'The value of node last_comment_uid is still the comment #1 uid.');
-    $this->assertEqual($node->comment_count, 1, 'The value of node comment_count is still 1.');
-
-    // Prepare for anonymous comment submission (no approval required).
-    $this->drupalLogin($this->admin_user);
-    user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array(
-      'access comments' => TRUE,
-      'post comments' => TRUE,
-      'skip comment approval' => TRUE,
-    ));
-    $this->drupalLogout();
-
-    // Post comment #3 as anonymous.
-    $this->drupalGet('comment/reply/' . $this->node->nid);
-    $anonymous_comment = $this->postComment($this->node, $this->randomName(), '', array('name' => $this->randomName()));
-    $comment_loaded = comment_load($anonymous_comment->id);
-
-    // Checks the new values of node comment statistics with comment #3.
-    // The node needs to be reloaded with a node_load_multiple cache reset.
-    $node = node_load($this->node->nid, TRUE);
-    $this->assertEqual($node->last_comment_name, $comment_loaded->name, 'The value of node last_comment_name is the name of the anonymous user.');
-    $this->assertEqual($node->last_comment_uid, 0, 'The value of node last_comment_uid is zero.');
-    $this->assertEqual($node->comment_count, 2, 'The value of node comment_count is 2.');
-  }
-
-  /**
    * Tests comment links.
    *
    * The output of comment links depends on various environment conditions:
@@ -594,109 +367,4 @@ function setEnvironment(array $info) {
     return $info;
   }
 
-  /**
-   * Asserts that comment links appear according to the passed environment.
-   *
-   * @param $info
-   *   An associative array describing the environment to pass to
-   *   setEnvironment().
-   */
-  function assertCommentLinks(array $info) {
-    $info = $this->setEnvironment($info);
-
-    $nid = $this->node->nid;
-
-    foreach (array('', "node/$nid") as $path) {
-      $this->drupalGet($path);
-
-      // User is allowed to view comments.
-      if ($info['access comments']) {
-        if ($path == '') {
-          // In teaser view, a link containing the comment count is always
-          // expected.
-          if ($info['comment count']) {
-            $this->assertLink(t('1 comment'));
-
-            // For logged in users, a link containing the amount of new/unread
-            // comments is expected.
-            // See important note about comment_num_new() below.
-            if ($this->loggedInUser && isset($this->comment) && !isset($this->comment->seen)) {
-              $this->assertLink(t('1 new comment'));
-              $this->comment->seen = TRUE;
-            }
-          }
-        }
-      }
-      else {
-        $this->assertNoLink(t('1 comment'));
-        $this->assertNoLink(t('1 new comment'));
-      }
-      // comment_num_new() is based on node views, so comments are marked as
-      // read when a node is viewed, regardless of whether we have access to
-      // comments.
-      if ($path == "node/$nid" && $this->loggedInUser && isset($this->comment)) {
-        $this->comment->seen = TRUE;
-      }
-
-      // User is not allowed to post comments.
-      if (!$info['post comments']) {
-        $this->assertNoLink('Add new comment');
-
-        // Anonymous users should see a note to log in or register in case
-        // authenticated users are allowed to post comments.
-        // @see theme_comment_post_forbidden()
-        if (!$this->loggedInUser) {
-          if (user_access('post comments', $this->web_user)) {
-            // The note depends on whether users are actually able to register.
-            if ($info['user_register'] != USER_REGISTER_ADMINISTRATORS_ONLY) {
-              $this->assertText('Log in or register to post comments');
-            }
-            else {
-              $this->assertText('Log in to post comments');
-            }
-          }
-          else {
-            $this->assertNoText('Log in or register to post comments');
-            $this->assertNoText('Log in to post comments');
-          }
-        }
-      }
-      // User is allowed to post comments.
-      else {
-        $this->assertNoText('Log in or register to post comments');
-
-        // "Add new comment" is always expected, except when there are no
-        // comments or if the user cannot see them.
-        if ($path == "node/$nid" && $info['form'] == COMMENT_FORM_BELOW && (!$info['comment count'] || !$info['access comments'])) {
-          $this->assertNoLink('Add new comment');
-        }
-        else {
-          $this->assertLink('Add new comment');
-
-          // Verify that the "Add new comment" link points to the correct URL
-          // based on the comment form location configuration.
-          if ($info['form'] == COMMENT_FORM_SEPARATE_PAGE) {
-            $this->assertLinkByHref("comment/reply/$nid#comment-form", 0, 'Comment form link destination is on a separate page.');
-            $this->assertNoLinkByHref("node/$nid#comment-form");
-          }
-          else {
-            $this->assertLinkByHref("node/$nid#comment-form", 0, 'Comment form link destination is on node.');
-            $this->assertNoLinkByHref("comment/reply/$nid#comment-form");
-          }
-        }
-
-        // Also verify that the comment form appears according to the configured
-        // location.
-        if ($path == "node/$nid") {
-          $elements = $this->xpath('//form[@id=:id]', array(':id' => 'comment-form'));
-          if ($info['form'] == COMMENT_FORM_BELOW) {
-            $this->assertTrue(count($elements), 'Comment form found below.');
-          }
-          else {
-            $this->assertFalse(count($elements), 'Comment form not found below.');
-          }
-        }
-      }
-    }
-  }
 }
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php
index 9c3af8e..346409f 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php
@@ -25,6 +25,11 @@ class CommentLanguageTest extends WebTestBase {
    */
   public static $modules = array('language', 'language_test', 'comment_test');
 
+  /**
+   * Use the standard profile.
+   *
+   * @todo Remove this dependency if possible.
+   */
   protected $profile = 'standard';
 
   public static function getInfo() {
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php
new file mode 100644
index 0000000..333e364
--- /dev/null
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\comment\Tests\CommentLinksTest.
+ */
+
+namespace Drupal\comment\Tests;
+
+/**
+ * Tests comment links based on environment configurations.
+ */
+class CommentLinksTest extends CommentTestBase {
+
+  /**
+   * Use the standard profile.
+   *
+   * @var string
+   *
+   * @todo Remove this dependency.
+   */
+  protected $profile = 'standard';
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Comment links',
+      'description' => 'Tests comment links based on environment configurations.',
+      'group' => 'Comment',
+    );
+  }
+
+  /**
+   * Tests comment links.
+   *
+   * The output of comment links depends on various environment conditions:
+   * - Various Comment module configuration settings, user registration
+   *   settings, and user access permissions.
+   * - Whether the user is authenticated or not, and whether any comments exist.
+   *
+   * To account for all possible cases, this test creates permutations of all
+   * possible conditions and tests the expected appearance of comment links in
+   * each environment.
+   */
+  function testCommentLinks() {
+    // Bartik theme alters comment links, so use a different theme.
+    theme_enable(array('stark'));
+    variable_set('theme_default', 'stark');
+
+    // Remove additional user permissions from $this->web_user added by setUp(),
+    // since this test is limited to anonymous and authenticated roles only.
+    user_role_delete(key($this->web_user->roles));
+
+    // Matrix of possible environmental conditions and configuration settings.
+    // See setEnvironment() for details.
+    $conditions = array(
+      'authenticated'   => array(FALSE, TRUE),
+      'comment count'   => array(FALSE, TRUE),
+      'access comments' => array(0, 1),
+      'post comments'   => array(0, 1),
+      'form'            => array(COMMENT_FORM_BELOW, COMMENT_FORM_SEPARATE_PAGE),
+      // USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL is irrelevant for this
+      // test; there is only a difference between open and closed registration.
+      'user_register'   => array(USER_REGISTER_VISITORS, USER_REGISTER_ADMINISTRATORS_ONLY),
+      // @todo Complete test coverage for:
+      //'comments'        => array(COMMENT_NODE_OPEN, COMMENT_NODE_CLOSED, COMMENT_NODE_HIDDEN),
+      //// COMMENT_ANONYMOUS_MUST_CONTACT is irrelevant for this test.
+      //'contact '        => array(COMMENT_ANONYMOUS_MAY_CONTACT, COMMENT_ANONYMOUS_MAYNOT_CONTACT),
+    );
+
+    $environments = $this->generatePermutations($conditions);
+    foreach ($environments as $info) {
+      $this->assertCommentLinks($info);
+    }
+  }
+
+}
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentNewIndicatorTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentNewIndicatorTest.php
new file mode 100644
index 0000000..e09d745
--- /dev/null
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentNewIndicatorTest.php
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\comment\Tests\CommentNewIndicatorTest.
+ */
+
+namespace Drupal\comment\Tests;
+
+/**
+ * Tests the 'new' marker on comments.
+ */
+class CommentNewIndicatorTest extends CommentTestBase {
+
+  /**
+   * Use the standard profile.
+   *
+   * @var string
+   *
+   * @todo Remove this dependency.
+   */
+  protected $profile = 'standard';
+
+  public static function getInfo() {
+    return array(
+      'name' => "Comment 'new' indicator",
+      'description' => "Tests the 'new' indicator posted on comments.",
+      'group' => 'Comment',
+    );
+  }
+
+  /**
+   * Tests new comment marker.
+   */
+  public function testCommentNewCommentsIndicator() {
+    // Test if the right links are displayed when no comment is present for the
+    // node.
+    $this->drupalLogin($this->admin_user);
+    $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => COMMENT_NODE_OPEN));
+    $this->drupalGet('node');
+    $this->assertNoLink(t('@count comments', array('@count' => 0)));
+    $this->assertNoLink(t('@count new comments', array('@count' => 0)));
+    $this->assertLink(t('Read more'));
+    $count = $this->xpath('//div[@id=:id]/div[@class=:class]/ul/li', array(':id' => 'node-' . $this->node->nid, ':class' => 'link-wrapper'));
+    $this->assertTrue(count($count) == 1, 'One child found');
+
+    // Create a new comment. This helper function may be run with different
+    // comment settings so use comment_save() to avoid complex setup.
+    $comment = entity_create('comment', array(
+      'cid' => NULL,
+      'nid' => $this->node->nid,
+      'node_type' => $this->node->type,
+      'pid' => 0,
+      'uid' => $this->loggedInUser->uid,
+      'status' => COMMENT_PUBLISHED,
+      'subject' => $this->randomName(),
+      'hostname' => ip_address(),
+      'langcode' => LANGUAGE_NOT_SPECIFIED,
+      'comment_body' => array(LANGUAGE_NOT_SPECIFIED => array($this->randomName())),
+    ));
+    comment_save($comment);
+    $this->drupalLogout();
+
+    // Log in with 'web user' and check comment links.
+    $this->drupalLogin($this->web_user);
+    $this->drupalGet('node');
+    $this->assertLink(t('1 new comment'));
+    $this->clickLink(t('1 new comment'));
+    $this->assertRaw('<a id="new"></a>', 'Found "new" marker.');
+    $this->assertTrue($this->xpath('//a[@id=:new]/following-sibling::a[1][@id=:comment_id]', array(':new' => 'new', ':comment_id' => 'comment-1')), 'The "new" anchor is positioned at the right comment.');
+
+    // Test if "new comment" link is correctly removed.
+    $this->drupalGet('node');
+    $this->assertLink(t('1 comment'));
+    $this->assertLink(t('Read more'));
+    $this->assertNoLink(t('1 new comment'));
+    $this->assertNoLink(t('@count new comments', array('@count' => 0)));
+    $count = $this->xpath('//div[@id=:id]/div[@class=:class]/ul/li', array(':id' => 'node-' . $this->node->nid, ':class' => 'link-wrapper'));
+    $this->assertTrue(count($count) == 2, print_r($count, TRUE));
+  }
+
+}
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentNodeAccessTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentNodeAccessTest.php
index d357bd0..37809c6 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentNodeAccessTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentNodeAccessTest.php
@@ -12,9 +12,8 @@
 /**
  * Tests comments with node access.
  *
- * See http://drupal.org/node/886752 -- verify there is no PostgreSQL error when
- * viewing a node with threaded comments (a comment and a reply), if a node
- * access module is in use.
+ * Verifies there is no PostgreSQL error when viewing a node with threaded
+ * comments (a comment and a reply), if a node access module is in use.
  */
 class CommentNodeAccessTest extends CommentTestBase {
 
@@ -39,7 +38,14 @@ function setUp() {
     node_access_rebuild();
 
     // Re-create user.
-    $this->web_user = $this->drupalCreateUser(array('access comments', 'post comments', 'create article content', 'edit own comments', 'node test view'));
+    $this->web_user = $this->drupalCreateUser(array(
+      'access comments',
+      'post comments',
+      'create article content',
+      'edit own comments',
+      'node test view',
+      'skip comment approval',
+    ));
   }
 
   /**
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentPreviewTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentPreviewTest.php
index e9ca2d9..44a38d5 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentPreviewTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentPreviewTest.php
@@ -11,6 +11,14 @@
  * Tests previewing comments.
  */
 class CommentPreviewTest extends CommentTestBase {
+
+  /**
+   * Use the standard profile.
+   *
+   * @var string
+   */
+  protected $profile = 'standard';
+
   public static function getInfo() {
     return array(
       'name' => 'Comment preview',
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentStatisticsTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentStatisticsTest.php
new file mode 100644
index 0000000..4281e2a
--- /dev/null
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentStatisticsTest.php
@@ -0,0 +1,115 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\comment\Tests\CommentStatisticsTest.
+ */
+
+namespace Drupal\comment\Tests;
+
+/**
+ * Tests the comment module administrative and end-user-facing interfaces.
+ */
+class CommentStatisticsTest extends CommentTestBase {
+
+  /**
+   * Use the standard profile.
+   *
+   * @var string
+   *
+   * @todo Remove this dependency.
+   */
+  protected $profile = 'standard';
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Comment statistics',
+      'description' => 'Test comment statistics on nodes.',
+      'group' => 'Comment',
+    );
+  }
+
+  /**
+   * Tests the node comment statistics.
+   */
+  function testCommentNodeCommentStatistics() {
+    $langcode = LANGUAGE_NOT_SPECIFIED;
+    // Set comments to have subject and preview disabled.
+    $this->drupalLogin($this->admin_user);
+    $this->setCommentPreview(DRUPAL_DISABLED);
+    $this->setCommentForm(TRUE);
+    $this->setCommentSubject(FALSE);
+    $this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Comment paging changed.');
+    $this->drupalLogout();
+
+    // Creates a second user to post comments.
+    $this->web_user2 = $this->drupalCreateUser(array('access comments', 'post comments', 'create article content', 'edit own comments'));
+
+    // Checks the initial values of node comment statistics with no comment.
+    $node = node_load($this->node->nid);
+    $this->assertEqual($node->last_comment_timestamp, $this->node->created, 'The initial value of node last_comment_timestamp is the node created date.');
+    $this->assertEqual($node->last_comment_name, NULL, 'The initial value of node last_comment_name is NULL.');
+    $this->assertEqual($node->last_comment_uid, $this->web_user->uid, 'The initial value of node last_comment_uid is the node uid.');
+    $this->assertEqual($node->comment_count, 0, 'The initial value of node comment_count is zero.');
+
+    // Post comment #1 as web_user2.
+    $this->drupalLogin($this->web_user2);
+    $comment_text = $this->randomName();
+    $comment = $this->postComment($this->node, $comment_text);
+    $comment_loaded = comment_load($comment->id);
+
+    // Checks the new values of node comment statistics with comment #1.
+    // The node needs to be reloaded with a node_load_multiple cache reset.
+    $node = node_load($this->node->nid, TRUE);
+    $this->assertEqual($node->last_comment_name, NULL, 'The value of node last_comment_name is NULL.');
+    $this->assertEqual($node->last_comment_uid, $this->web_user2->uid, 'The value of node last_comment_uid is the comment #1 uid.');
+    $this->assertEqual($node->comment_count, 1, 'The value of node comment_count is 1.');
+
+    // Prepare for anonymous comment submission (comment approval enabled).
+    config('user.settings')->set('register', USER_REGISTER_VISITORS)->save();
+    $this->drupalLogin($this->admin_user);
+    user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array(
+      'access comments' => TRUE,
+      'post comments' => TRUE,
+      'skip comment approval' => FALSE,
+    ));
+    // Ensure that the poster can leave some contact info.
+    $this->setCommentAnonymous('1');
+    $this->drupalLogout();
+
+    // Post comment #2 as anonymous (comment approval enabled).
+    $this->drupalGet('comment/reply/' . $this->node->nid);
+    $anonymous_comment = $this->postComment($this->node, $this->randomName(), '', TRUE);
+    $comment_unpublished_loaded = comment_load($anonymous_comment->id);
+
+    // Checks the new values of node comment statistics with comment #2 and
+    // ensure they haven't changed since the comment has not been moderated.
+    // The node needs to be reloaded with a node_load_multiple cache reset.
+    $node = node_load($this->node->nid, TRUE);
+    $this->assertEqual($node->last_comment_name, NULL, 'The value of node last_comment_name is still NULL.');
+    $this->assertEqual($node->last_comment_uid, $this->web_user2->uid, 'The value of node last_comment_uid is still the comment #1 uid.');
+    $this->assertEqual($node->comment_count, 1, 'The value of node comment_count is still 1.');
+
+    // Prepare for anonymous comment submission (no approval required).
+    $this->drupalLogin($this->admin_user);
+    user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array(
+      'access comments' => TRUE,
+      'post comments' => TRUE,
+      'skip comment approval' => TRUE,
+    ));
+    $this->drupalLogout();
+
+    // Post comment #3 as anonymous.
+    $this->drupalGet('comment/reply/' . $this->node->nid);
+    $anonymous_comment = $this->postComment($this->node, $this->randomName(), '', array('name' => $this->randomName()));
+    $comment_loaded = comment_load($anonymous_comment->id);
+
+    // Checks the new values of node comment statistics with comment #3.
+    // The node needs to be reloaded with a node_load_multiple cache reset.
+    $node = node_load($this->node->nid, TRUE);
+    $this->assertEqual($node->last_comment_name, $comment_loaded->name, 'The value of node last_comment_name is the name of the anonymous user.');
+    $this->assertEqual($node->last_comment_uid, 0, 'The value of node last_comment_uid is zero.');
+    $this->assertEqual($node->comment_count, 2, 'The value of node comment_count is 2.');
+  }
+
+}
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentTestBase.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentTestBase.php
index 60216ab..dc0d934 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentTestBase.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentTestBase.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Definition of Drupal\comment\Tests\CommentTestBase.
+ * Contains Drupal\comment\Tests\CommentTestBase.
  */
 
 namespace Drupal\comment\Tests;
@@ -10,6 +10,9 @@
 use Drupal\comment\Comment;
 use Drupal\simpletest\WebTestBase;
 
+/**
+ * Provides setup and helper methods for comment tests.
+ */
 abstract class CommentTestBase extends WebTestBase {
 
   /**
@@ -17,20 +20,60 @@
    *
    * @var array
    */
-  public static $modules = array('comment', 'search');
-
-  protected $profile = 'standard';
+  public static $modules = array('comment', 'node');
 
+  /**
+   * An administrative user with permission to configure comment settings.
+   *
+   * @var Drupal\user\User
+   */
   protected $admin_user;
+
+  /**
+   * A normal user with permission to post comments.
+   *
+   * @var Drupal\user\User
+   */
   protected $web_user;
+
+  /**
+   * A test node to which comments will be posted.
+   *
+   * @var Drupal\node\Node
+   */
   protected $node;
 
   function setUp() {
     parent::setUp();
 
-    // Create users and test node.
-    $this->admin_user = $this->drupalCreateUser(array('administer content types', 'administer comments', 'administer blocks'));
-    $this->web_user = $this->drupalCreateUser(array('access comments', 'post comments', 'create article content', 'edit own comments'));
+    // Create an article content type only if it does not yet exist, so that
+    // child classes may specify the standard profile.
+    $types = node_type_get_types();
+    if (empty($types['article'])) {
+      $this->drupalCreateContentType(array('type' => 'article', 'name' => t('Article')));
+    }
+
+    // Create two test users.
+    $this->admin_user = $this->drupalCreateUser(array(
+      'administer content types',
+      'administer comments',
+      'skip comment approval',
+      'post comments',
+      'access comments',
+      'access content',
+     ));
+    $this->web_user = $this->drupalCreateUser(array(
+      'access comments',
+      'post comments',
+      'create article content',
+      'edit own comments',
+      'post comments',
+      'skip comment approval',
+      'access comments',
+      'access content',
+    ));
+
+    // Create a test node authored by the web user.
     $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'uid' => $this->web_user->uid));
   }
 
@@ -122,7 +165,6 @@ function commentExists(Comment $comment = NULL, $reply = FALSE) {
     if ($comment) {
       $regex = '/' . ($reply ? '<div class="indented">(.*?)' : '');
       $regex .= '<a id="comment-' . $comment->id . '"(.*?)'; // Comment anchor.
-      $regex .= '<div(.*?)'; // Begin in comment div.
       $regex .= $comment->subject . '(.*?)'; // Match subject.
       $regex .= $comment->comment . '(.*?)'; // Match comment.
       $regex .= '/s';
@@ -278,4 +320,246 @@ function getUnapprovedComment($subject) {
 
     return $match[2];
   }
+
+  /**
+   * Re-configures the environment, module settings, and user permissions.
+   *
+   * @param $info
+   *   An associative array describing the environment to setup:
+   *   - Environment conditions:
+   *     - authenticated: Boolean whether to test with $this->web_user or
+   *       anonymous.
+   *     - comment count: Boolean whether to test with a new/unread comment on
+   *       $this->node or no comments.
+   *   - Configuration settings:
+   *     - form: COMMENT_FORM_BELOW or COMMENT_FORM_SEPARATE_PAGE.
+   *     - user_register: USER_REGISTER_ADMINISTRATORS_ONLY or
+   *       USER_REGISTER_VISITORS.
+   *     - contact: COMMENT_ANONYMOUS_MAY_CONTACT or
+   *       COMMENT_ANONYMOUS_MAYNOT_CONTACT.
+   *     - comments: COMMENT_NODE_OPEN, COMMENT_NODE_CLOSED, or
+   *       COMMENT_NODE_HIDDEN.
+   *   - User permissions:
+   *     These are granted or revoked for the user, according to the
+   *     'authenticated' flag above. Pass 0 or 1 as parameter values. See
+   *     user_role_change_permissions().
+   *     - access comments
+   *     - post comments
+   *     - skip comment approval
+   *     - edit own comments
+   */
+  function setEnvironment(array $info) {
+    static $current;
+
+    // Apply defaults to initial environment.
+    if (!isset($current)) {
+      $current = array(
+        'authenticated' => FALSE,
+        'comment count' => FALSE,
+        'form' => COMMENT_FORM_BELOW,
+        'user_register' => USER_REGISTER_VISITORS,
+        'contact' => COMMENT_ANONYMOUS_MAY_CONTACT,
+        'comments' => COMMENT_NODE_OPEN,
+        'access comments' => 0,
+        'post comments' => 0,
+        // Enabled by default, because it's irrelevant for this test.
+        'skip comment approval' => 1,
+        'edit own comments' => 0,
+      );
+    }
+    // Complete new environment with current environment.
+    $info = array_merge($current, $info);
+
+    // Change environment conditions.
+    if ($current['authenticated'] != $info['authenticated']) {
+      if ($this->loggedInUser) {
+        $this->drupalLogout();
+      }
+      else {
+        $this->drupalLogin($this->web_user);
+      }
+    }
+    if ($current['comment count'] != $info['comment count']) {
+      if ($info['comment count']) {
+        // Create a comment via CRUD API functionality, since
+        // $this->postComment() relies on actual user permissions.
+        $comment = entity_create('comment', array(
+          'cid' => NULL,
+          'nid' => $this->node->nid,
+          'node_type' => $this->node->type,
+          'pid' => 0,
+          'uid' => 0,
+          'status' => COMMENT_PUBLISHED,
+          'subject' => $this->randomName(),
+          'hostname' => ip_address(),
+          'langcode' => LANGUAGE_NOT_SPECIFIED,
+          'comment_body' => array(LANGUAGE_NOT_SPECIFIED => array($this->randomName())),
+        ));
+        comment_save($comment);
+        $this->comment = $comment;
+
+        // comment_num_new() relies on node_last_viewed(), so ensure that no one
+        // has seen the node of this comment.
+        db_delete('history')->condition('nid', $this->node->nid)->execute();
+      }
+      else {
+        $cids = db_query("SELECT cid FROM {comment}")->fetchCol();
+        comment_delete_multiple($cids);
+        unset($this->comment);
+      }
+    }
+
+    // Change comment settings.
+    variable_set('comment_form_location_' . $this->node->type, $info['form']);
+    variable_set('comment_anonymous_' . $this->node->type, $info['contact']);
+    if ($this->node->comment != $info['comments']) {
+      $this->node->comment = $info['comments'];
+      node_save($this->node);
+    }
+
+    // Change user settings.
+    config('user.settings')->set('register', $info['user_register'])->save();
+
+    // Change user permissions.
+    $rid = ($this->loggedInUser ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID);
+    $perms = array_intersect_key($info, array('access comments' => 1, 'post comments' => 1, 'skip comment approval' => 1, 'edit own comments' => 1));
+    user_role_change_permissions($rid, $perms);
+
+    // Output verbose debugging information.
+    // @see Drupal\simpletest\TestBase::error()
+    $t_form = array(
+      COMMENT_FORM_BELOW => 'below',
+      COMMENT_FORM_SEPARATE_PAGE => 'separate page',
+    );
+    $t_contact = array(
+      COMMENT_ANONYMOUS_MAY_CONTACT => 'optional',
+      COMMENT_ANONYMOUS_MAYNOT_CONTACT => 'disabled',
+      COMMENT_ANONYMOUS_MUST_CONTACT => 'required',
+    );
+    $t_comments = array(
+      COMMENT_NODE_OPEN => 'open',
+      COMMENT_NODE_CLOSED => 'closed',
+      COMMENT_NODE_HIDDEN => 'hidden',
+    );
+    $verbose = $info;
+    $verbose['form'] = $t_form[$info['form']];
+    $verbose['contact'] = $t_contact[$info['contact']];
+    $verbose['comments'] = $t_comments[$info['comments']];
+    $message = t('Changed environment:<pre>@verbose</pre>', array(
+      '@verbose' => var_export($verbose, TRUE),
+    ));
+    $this->assert('debug', $message, 'Debug');
+
+    // Update current environment.
+    $current = $info;
+
+    return $info;
+  }
+
+  /**
+   * Asserts that comment links appear according to the passed environment.
+   *
+   * @param $info
+   *   An associative array describing the environment to pass to
+   *   setEnvironment().
+   */
+  function assertCommentLinks(array $info) {
+    $info = $this->setEnvironment($info);
+
+    $nid = $this->node->nid;
+
+    foreach (array('', "node/$nid") as $path) {
+      $this->drupalGet($path);
+
+      // User is allowed to view comments.
+      if ($info['access comments']) {
+        if ($path == '') {
+          // In teaser view, a link containing the comment count is always
+          // expected.
+          if ($info['comment count']) {
+            $this->assertLink(t('1 comment'));
+
+            // For logged in users, a link containing the amount of new/unread
+            // comments is expected.
+            // See important note about comment_num_new() below.
+            if ($this->loggedInUser && isset($this->comment) && !isset($this->comment->seen)) {
+              $this->assertLink(t('1 new comment'));
+              $this->comment->seen = TRUE;
+            }
+          }
+        }
+      }
+      else {
+        $this->assertNoLink(t('1 comment'));
+        $this->assertNoLink(t('1 new comment'));
+      }
+      // comment_num_new() is based on node views, so comments are marked as
+      // read when a node is viewed, regardless of whether we have access to
+      // comments.
+      if ($path == "node/$nid" && $this->loggedInUser && isset($this->comment)) {
+        $this->comment->seen = TRUE;
+      }
+
+      // User is not allowed to post comments.
+      if (!$info['post comments']) {
+        $this->assertNoLink('Add new comment');
+
+        // Anonymous users should see a note to log in or register in case
+        // authenticated users are allowed to post comments.
+        // @see theme_comment_post_forbidden()
+        if (!$this->loggedInUser) {
+          if (user_access('post comments', $this->web_user)) {
+            // The note depends on whether users are actually able to register.
+            if ($info['user_register'] != USER_REGISTER_ADMINISTRATORS_ONLY) {
+              $this->assertText('Log in or register to post comments');
+            }
+            else {
+              $this->assertText('Log in to post comments');
+            }
+          }
+          else {
+            $this->assertNoText('Log in or register to post comments');
+            $this->assertNoText('Log in to post comments');
+          }
+        }
+      }
+      // User is allowed to post comments.
+      else {
+        $this->assertNoText('Log in or register to post comments');
+
+        // "Add new comment" is always expected, except when there are no
+        // comments or if the user cannot see them.
+        if ($path == "node/$nid" && $info['form'] == COMMENT_FORM_BELOW && (!$info['comment count'] || !$info['access comments'])) {
+          $this->assertNoLink('Add new comment');
+        }
+        else {
+          $this->assertLink('Add new comment');
+
+          // Verify that the "Add new comment" link points to the correct URL
+          // based on the comment form location configuration.
+          if ($info['form'] == COMMENT_FORM_SEPARATE_PAGE) {
+            $this->assertLinkByHref("comment/reply/$nid#comment-form", 0, 'Comment form link destination is on a separate page.');
+            $this->assertNoLinkByHref("node/$nid#comment-form");
+          }
+          else {
+            $this->assertLinkByHref("node/$nid#comment-form", 0, 'Comment form link destination is on node.');
+            $this->assertNoLinkByHref("comment/reply/$nid#comment-form");
+          }
+        }
+
+        // Also verify that the comment form appears according to the configured
+        // location.
+        if ($path == "node/$nid") {
+          $elements = $this->xpath('//form[@id=:id]', array(':id' => 'comment-form'));
+          if ($info['form'] == COMMENT_FORM_BELOW) {
+            $this->assertTrue(count($elements), 'Comment form found below.');
+          }
+          else {
+            $this->assertFalse(count($elements), 'Comment form not found below.');
+          }
+        }
+      }
+    }
+  }
+
 }
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/CommentAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/CommentAttributesTest.php
index 01c8069..d16493a 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/CommentAttributesTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/CommentAttributesTest.php
@@ -15,6 +15,15 @@
 class CommentAttributesTest extends CommentTestBase {
 
   /**
+   * Use the standard profile.
+   *
+   * @var string
+   *
+   * @todo Remove this dependency if possible.
+   */
+  protected $profile = 'standard';
+
+  /**
    * Modules to enable.
    *
    * @var array
