diff --git a/core/modules/simpletest/drupal_web_test_case.php b/core/modules/simpletest/drupal_web_test_case.php
index 91fd2c75240c06eb00209eac12d70e42e4c793de..5c711fb832a48cd4214de075fb6969d275382a8e 100644
--- a/core/modules/simpletest/drupal_web_test_case.php
+++ b/core/modules/simpletest/drupal_web_test_case.php
@@ -95,6 +95,16 @@ public function __construct($test_id = NULL) {
     $this->testId = $test_id;
   }
 
+  /**
+   * Checks the matching requirements for DrupalTestCase.
+   *
+   * @return
+   *   Array of errors containing a list of unmet requirements.
+   */
+  protected function checkRequirements() {
+    return array();
+  }
+
   /**
    * Internal helper: stores the assert.
    *
@@ -481,34 +491,46 @@ public function run(array $methods = array()) {
     if ($methods) {
       $class_methods = array_intersect($class_methods, $methods);
     }
-    foreach ($class_methods as $method) {
-      // If the current method starts with "test", run it - it's a test.
-      if (strtolower(substr($method, 0, 4)) == 'test') {
-        // Insert a fail record. This will be deleted on completion to ensure
-        // that testing completed.
-        $method_info = new ReflectionMethod($class, $method);
-        $caller = array(
-          'file' => $method_info->getFileName(),
-          'line' => $method_info->getStartLine(),
-          'function' => $class . '->' . $method . '()',
-        );
-        $completion_check_id = DrupalTestCase::insertAssert($this->testId, $class, FALSE, t('The test did not complete due to a fatal error.'), 'Completion check', $caller);
-        $this->setUp();
-        if ($this->setup) {
-          try {
-            $this->$method();
-            // Finish up.
+    $missing_requirements = $this->checkRequirements();
+    if (!empty($missing_requirements)) {
+      $missing_requirements_object = new ReflectionObject($this);
+      $caller = array(
+        'file' => $missing_requirements_object->getFileName(),
+      );
+      foreach ($missing_requirements as $missing_requirement) {
+        DrupalTestCase::insertAssert($this->testId, $class, FALSE, $missing_requirement, 'Requirements check.', $caller);
+      }
+    }
+    else {
+      foreach ($class_methods as $method) {
+        // If the current method starts with "test", run it - it's a test.
+        if (strtolower(substr($method, 0, 4)) == 'test') {
+          // Insert a fail record. This will be deleted on completion to ensure
+          // that testing completed.
+          $method_info = new ReflectionMethod($class, $method);
+          $caller = array(
+            'file' => $method_info->getFileName(),
+            'line' => $method_info->getStartLine(),
+            'function' => $class . '->' . $method . '()',
+          );
+          $completion_check_id = DrupalTestCase::insertAssert($this->testId, $class, FALSE, t('The test did not complete due to a fatal error.'), 'Completion check', $caller);
+          $this->setUp();
+          if ($this->setup) {
+            try {
+              $this->$method();
+              // Finish up.
+            }
+            catch (Exception $e) {
+              $this->exceptionHandler($e);
+            }
+            $this->tearDown();
           }
-          catch (Exception $e) {
-            $this->exceptionHandler($e);
+          else {
+            $this->fail(t("The test cannot be executed because it has not been set up properly."));
           }
-          $this->tearDown();
-        }
-        else {
-          $this->fail(t("The test cannot be executed because it has not been set up properly."));
+          // Remove the completion check record.
+          DrupalTestCase::deleteAssert($completion_check_id);
         }
-        // Remove the completion check record.
-        DrupalTestCase::deleteAssert($completion_check_id);
       }
     }
     // Clear out the error messages and restore error handler.
diff --git a/core/modules/simpletest/simpletest.test b/core/modules/simpletest/simpletest.test
index a4bf08ce64977dd27ff899a233ddd2ca69ec9146..716b36e7e6b07b74a405e5925b76acd5d0e92bbb 100644
--- a/core/modules/simpletest/simpletest.test
+++ b/core/modules/simpletest/simpletest.test
@@ -570,3 +570,52 @@ class SimpleTestBrokenSetUp extends DrupalWebTestCase {
     }
   }
 }
+
+/**
+ * Tests missing requirements to run test.
+ */
+class SimpleTestMissingCheckedRequirements extends DrupalWebTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Broken requirements test',
+      'description' => 'Tests a test case with missing requirements.',
+      'group' => 'SimpleTest',
+    );
+  }
+
+  function setUp() {
+    parent::setUp('simpletest');
+    $admin_user = $this->drupalCreateUser(array('administer unit tests'));
+    $this->drupalLogin($admin_user);
+  }
+
+  /**
+   * Overrides checkRequirements().
+   */
+  protected function checkRequirements() {
+    if (drupal_valid_test_ua()) {
+      return array(
+        'Test is not allowed to run.'
+      );
+    }
+    return parent::checkRequirements();
+  }
+
+  /**
+   * Ensures test will not run when requirements are missing.
+   */
+  protected function testCheckRequirements() {
+    // If this is the main request, run the web test script and then assert
+    // that the child tests did not run.
+    if (!drupal_valid_test_ua()) {
+      // Run this test from web interface.
+      $edit['SimpleTestMissingCheckedRequirements'] = TRUE;
+      $this->drupalPost('admin/config/development/testing', $edit, t('Run tests'));
+      $this->assertRaw('Test is not allowed to run.', 'Test check for requirements came up.');
+      $this->assertNoText('Test ran when it failed requirements check.', 'Test requirements stopped test from running.');
+    }
+    else {
+      $this->fail('Test ran when it failed requirements check.');
+    }
+  }
+}
diff --git a/core/modules/simpletest/tests/image.test b/core/modules/simpletest/tests/image.test
index 60599bee529a3f7c47595791bf12863397d02dde..daf5394ef5694c3dc6dd3825b9ac79018a8fd340 100644
--- a/core/modules/simpletest/tests/image.test
+++ b/core/modules/simpletest/tests/image.test
@@ -216,6 +216,16 @@ class ImageToolkitGdTestCase extends DrupalWebTestCase {
     );
   }
 
+  protected function checkRequirements() {
+    image_get_available_toolkits();
+    if (!function_exists('image_gd_check_settings') || !image_gd_check_settings()) {
+      return array(
+        'Image manipulations for the GD toolkit cannot run because the GD toolkit is not available.',
+      );
+    }
+    return parent::checkRequirements();
+  }
+
   /**
    * Function to compare two colors by RGBa.
    */
@@ -254,12 +264,6 @@ class ImageToolkitGdTestCase extends DrupalWebTestCase {
    * the expected height and widths for the final images.
    */
   function testManipulations() {
-    // If GD isn't available don't bother testing this.
-    if (!function_exists('image_gd_check_settings') || !image_gd_check_settings()) {
-      $this->pass(t('Image manipulations for the GD toolkit were skipped because the GD toolkit is not available.'));
-      return;
-    }
-
     // Typically the corner colors will be unchanged. These colors are in the
     // order of top-left, top-right, bottom-right, bottom-left.
     $default_corners = array($this->red, $this->green, $this->blue, $this->transparent);
diff --git a/core/modules/simpletest/tests/upgrade/upgrade.test b/core/modules/simpletest/tests/upgrade/upgrade.test
index c53050e296892235097193b6420c182d6e7eab8a..29793b257c35f8f73cd9b62ab88f4e23b81bbca2 100644
--- a/core/modules/simpletest/tests/upgrade/upgrade.test
+++ b/core/modules/simpletest/tests/upgrade/upgrade.test
@@ -27,20 +27,24 @@ abstract class UpgradePathTestCase extends DrupalWebTestCase {
    */
   var $loadedModules = array();
 
+  /**
+   * Checks that zlib is enabled in order to run the upgrade tests.
+   */
+  protected function checkRequirements() {
+    if (!function_exists('gzopen')) {
+      return array(
+        'Missing zlib requirement for upgrade tests.',
+      );
+    }
+    return parent::checkRequirements();
+  }
+
   /**
    * Override of DrupalWebTestCase::setUp() specialized for upgrade testing.
    */
   protected function setUp() {
     global $user, $language, $conf;
 
-    // We are going to set a missing zlib requirement property for usage during
-    // the performUpgrade() and tearDown() calls. Also set that the tests failed.
-    if (!function_exists('gzopen')) {
-      $this->missing_zlib_requirement = TRUE;
-      parent::setUp();
-      return;
-    }
-
     // Load the Update API.
     require_once DRUPAL_ROOT . '/core/includes/update.inc';
 
@@ -145,11 +149,6 @@ abstract class UpgradePathTestCase extends DrupalWebTestCase {
   protected function tearDown() {
     global $user, $language;
 
-    if (!empty($this->missing_zlib_requirement)) {
-      parent::tearDown();
-      return;
-    }
-
     // In case a fatal error occurred that was not in the test process read the
     // log to pick up any fatal errors.
     simpletest_log_read($this->testId, $this->databasePrefix, get_class($this), TRUE);
@@ -246,11 +245,6 @@ abstract class UpgradePathTestCase extends DrupalWebTestCase {
   protected function performUpgrade($register_errors = TRUE) {
     $update_url = $GLOBALS['base_url'] . '/core/update.php';
 
-    if (!empty($this->missing_zlib_requirement)) {
-      $this->fail(t('Missing zlib requirement for upgrade tests.'));
-      return FALSE;
-    }
-
     // Load the first update screen.
     $this->drupalGet($update_url, array('external' => TRUE));
     if (!$this->assertResponse(200)) {