diff --git a/core/lib/Drupal/Component/Utility/Random.php b/core/lib/Drupal/Component/Utility/Random.php
index df989c0..41602cc 100644
--- a/core/lib/Drupal/Component/Utility/Random.php
+++ b/core/lib/Drupal/Component/Utility/Random.php
@@ -48,15 +48,21 @@ class Random {
    * @param bool $unique
    *   (optional) If TRUE ensures that the random string returned is unique.
    *   Defaults to FALSE.
+   * @param callable $validator
+   *   (optional) A callable to validate the the string. Defaults to NULL.
    *
    * @return string
    *   Randomly generated string.
    *
    * @see \Drupal\Component\Utility\Random::name()
    */
-  public static function string($length = 8, $unique = FALSE) {
+  public static function string($length = 8, $unique = FALSE, $callable = NULL) {
     $counter = 0;
 
+    // Continue to loop if $unique is TRUE and the string has been generated
+    // already or if $callable is not null and the validate method returns
+    // FALSE. To generate a random string this loop must be carried out at least
+    // once.
     do {
       if ($counter == static::MAXIMUM_TRIES) {
         throw new \RuntimeException('Unable to generate a unique random name');
@@ -66,7 +72,15 @@ public static function string($length = 8, $unique = FALSE) {
         $str .= chr(mt_rand(32, 126));
       }
       $counter++;
-    } while ($unique && isset(static::$strings[$str]));
+
+      $continue = FALSE;
+      if ($unique) {
+        $continue = isset(static::$strings[$str]);
+      }
+      if (!$continue && is_callable($callable)) {
+        $continue = static::validate($callable, $str) === FALSE;
+      }
+    } while ($continue);
 
     if ($unique) {
       static::$strings[$str] = TRUE;
@@ -138,4 +152,17 @@ public static function object($size = 4) {
     return $object;
   }
 
+  /**
+   * @param $callable
+   * @param $value
+   * @return bool
+   */
+  protected static function validate($callable, $value) {
+    if (is_callable($callable)) {
+      return call_user_func($callable, $value);
+    }
+
+    return TRUE;
+  }
+
 }
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
index 3eb5c84..c3434f4 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
@@ -1169,7 +1169,42 @@ protected function settingsSet($name, $value) {
    * @see \Drupal\Component\Utility\Random::string()
    */
   public function randomString($length = 8) {
-    return Random::string($length, TRUE);
+    return Random::string($length, TRUE, array($this, 'randomStringValidate'));
+  }
+
+  /**
+   * Callback for random string validation.
+   *
+   * @see \Drupal\Component\Utility\Random::name()
+   *
+   * @param string $str
+   *   The random string to validate.
+   *
+   * @return bool
+   *   TRUE if the random string is valid, FALSE if not.
+   */
+  public function randomStringValidate($str) {
+    // Consecutive spaces causes issues for xpath
+    if (preg_match('/\s{2,}/', $str)) {
+      return FALSE;
+    }
+
+    // Starting with a space we can not guarantee length in UI.
+    if (preg_match('/^\s/', $str)) {
+      return FALSE;
+    }
+
+    // Ending with a space we can not guarantee length in UI.
+    if (preg_match('/\s$/', $str)) {
+      return FALSE;
+    }
+
+    // Containing \1 matches regex back references.
+    if (preg_match('/\\\\[0-9]/', $str)) {
+      return FALSE;
+    }
+
+    return TRUE;
   }
 
   /**
diff --git a/core/modules/simpletest/tests/Drupal/simpletest/Tests/TestBaseTest.php b/core/modules/simpletest/tests/Drupal/simpletest/Tests/TestBaseTest.php
new file mode 100644
index 0000000..a4a8fda
--- /dev/null
+++ b/core/modules/simpletest/tests/Drupal/simpletest/Tests/TestBaseTest.php
@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\simpletest\TestBaseTest.
+ */
+
+namespace Drupal\simpletest\Tests;
+
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * Test PHPUnit errors are getting converted to Simpletest errors.
+ */
+class TestBaseTest extends UnitTestCase {
+
+  /**
+   * A stub built using the TestBase class.
+   *
+   * @var object
+   */
+  protected $stub;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'TestBase helper functions test',
+      'description' => 'Test helper functions provided by the TetsBase abstract class.',
+      'group' => 'Simpletest',
+
+    );
+  }
+
+  protected function setUp() {
+    $this->stub = $this->getMockForAbstractClass('Drupal\simpletest\TestBase');
+  }
+
+  public function randomStringValidateProvider () {
+    return array(
+      array(' rewrew', FALSE),
+      array('rewrew ', FALSE),
+      array('re  wrew', FALSE),
+      array('re   wrew', FALSE),
+      array('re wrew', TRUE),
+      array('re wr ew', TRUE),
+      array('sdsfs\\5', FALSE),
+      array('sdsfs\5', FALSE),
+      array('sdsfs5', TRUE),
+      array('sds\\fs5', TRUE),
+    );
+  }
+
+  /**
+   * @param string $str
+   * @param bool $expected
+   *
+   * @dataProvider randomStringValidateProvider
+   */
+  public function testRandomStringValidate($str, $expected) {
+    $actual = $this->stub->randomStringValidate($str);
+    $this->assertEquals($expected, $actual);
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Component/Utility/RandomTest.php b/core/tests/Drupal/Tests/Component/Utility/RandomTest.php
index 894ecc2..a698ad8 100644
--- a/core/tests/Drupal/Tests/Component/Utility/RandomTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/RandomTest.php
@@ -18,6 +18,15 @@
  */
 class RandomTest extends UnitTestCase {
 
+  /**
+   * The first random string passed to the test callback.
+   *
+   * @see \Drupal\Tests\Component\Utility\RandomTest::_RandomStringValidate
+   *
+   * @var string
+   */
+  protected $firstStringGenerated = '';
+
   public static function getInfo() {
     return array(
       'name' => 'Random data generation tests',
@@ -27,28 +36,30 @@ public static function getInfo() {
   }
 
   /**
-   * Tests unique random name generation.
+   * Tests unique random string generation.
    *
-   * @see \Drupal\Component\Utility\Random::name()
+   * @see \Drupal\Component\Utility\Random::string()
    */
   public function testRandomStringUniqueness() {
     $strings = array();
+    $random = new Random();
     for ($i = 0; $i <= 50; $i++) {
-      $str = Random::string(1, TRUE);
+      $str = $random::string(1, TRUE);
       $this->assertFalse(isset($strings[$str]), String::format('Generated duplicate random string !string', array('!string' => $str)));
       $strings[$str] = TRUE;
     }
   }
 
   /**
-   * Tests unique random string generation.
+   * Tests unique random name generation.
    *
-   * @see \Drupal\Component\Utility\Random::string()
+   * @see \Drupal\Component\Utility\Random::name()
    */
   public function testRandomNamesUniqueness() {
     $names = array();
+    $random = new Random();
     for ($i = 0; $i <= 10; $i++) {
-      $str = Random::name(1, TRUE);
+      $str = $random->name(1, TRUE);
       $this->assertFalse(isset($names[$str]), String::format('Generated duplicate random name !name', array('!name' => $str)));
       $names[$str] = TRUE;
     }
@@ -64,8 +75,9 @@ public function testRandomNamesUniqueness() {
   public function testRandomNameException() {
     // There are fewer than 100 possibilities so an exception should occur to
     // prevent infinite loops.
+    $random = new Random();
     for ($i = 0; $i <= 100; $i++) {
-      $str = Random::name(1, TRUE);
+      $str = $random->name(1, TRUE);
       $names[$str] = TRUE;
     }
   }
@@ -80,8 +92,9 @@ public function testRandomNameException() {
   public function testRandomStringException() {
     // There are fewer than 100 possibilities so an exception should occur to
     // prevent infinite loops.
+    $random = new Random();
     for ($i = 0; $i <= 100; $i++) {
-      $str = Random::string(1, TRUE);
+      $str = $random::string(1, TRUE);
       $names[$str] = TRUE;
     }
   }
@@ -94,8 +107,9 @@ public function testRandomStringException() {
   public function testRandomNameNonUnique() {
     // There are fewer than 100 possibilities if we were forcing uniqueness so
     // exception would occur.
+    $random = new Random();
     for ($i = 0; $i <= 100; $i++) {
-      Random::name(1);
+      $random::name(1);
     }
     $this->assertTrue(TRUE, 'No exception thrown when uniqueness is not enforced.');
   }
@@ -108,8 +122,9 @@ public function testRandomNameNonUnique() {
   public function testRandomStringNonUnique() {
     // There are fewer than 100 possibilities if we were forcing uniqueness so
     // exception would occur.
+    $random = new Random();
     for ($i = 0; $i <= 100; $i++) {
-      Random::string(1);
+      $random::string(1);
     }
     $this->assertTrue(TRUE, 'No exception thrown when uniqueness is not enforced.');
   }
@@ -122,10 +137,42 @@ public function testRandomStringNonUnique() {
   public function testRandomObject() {
     // For values of 0 and 1 \Drupal\Component\Utility\Random::object() will
     // have different execution paths.
+    $random = new Random();
     for ($i = 0; $i <= 1; $i++) {
-      $obj = Random::object($i);
+      $obj = $random::object($i);
       $this->assertEquals($i, count(get_object_vars($obj)), 'Generated random object has expected number of properties');
     }
   }
 
+  /**
+   * Tests random string validation callbacks.
+   *
+   * @see \Drupal\Component\Utility\Random::name()
+   */
+  public function testRandomStringValidator() {
+    $random = new Random();
+    $this->firstStringGenerated = '';
+    $str = $random::string(1, FALSE, array($this, '_RandomStringValidate'));
+    $this->assertNotEquals($this->firstStringGenerated, $str);
+  }
+
+  /**
+   * Callback for random string validation.
+   *
+   * @see \Drupal\Component\Utility\Random::name()
+   * @see \Drupal\Tests\Component\Utility\RandomTest::testRandomStringValidator()
+   *
+   * @param string $str
+   *   The random string to validate.
+   *
+   * @return bool
+   *   TRUE if the random string is valid, FALSE if not.
+   */
+  public function _RandomStringValidate($str) {
+    if (empty($this->firstStringGenerated)) {
+      $this->firstStringGenerated = $str;
+      return FALSE;
+    }
+    return TRUE;
+  }
 }
