diff --git a/core/modules/simpletest/drupal_web_test_case.php b/core/modules/simpletest/drupal_web_test_case.php
index ca66143..9161af8 100644
--- a/core/modules/simpletest/drupal_web_test_case.php
+++ b/core/modules/simpletest/drupal_web_test_case.php
@@ -74,6 +74,18 @@ abstract class DrupalTestCase {
   protected $skipClasses = array(__CLASS__ => TRUE);
 
   /**
+   * Flag to indicate whether the test has been set up.
+   *
+   * The setUp() method isolates the test from the parent Drupal site by
+   * creating a random prefix for the database and setting up a clean file
+   * storage directory. The tearDown() method then cleans up this test
+   * environment. We must ensure that setUp() has been run. Otherwise,
+   * tearDown() will act on the parent Drupal site rather than the test
+   * environment, destroying live data.
+   */
+  protected $setup = FALSE;
+
+  /**
    * Constructor for DrupalTestCase.
    *
    * @param $test_id
@@ -127,7 +139,15 @@ abstract class DrupalTestCase {
     );
 
     // Store assertion for display after the test has completed.
-    Database::getConnection('default', 'simpletest_original_default')
+    try {
+      $connection = Database::getConnection('default', 'simpletest_original_default');
+    }
+    catch (DatabaseConnectionNotDefinedException $e) {
+      // If the test was not set up, the simpletest_original_default
+      // connection does not exist.
+      $connection = Database::getConnection('default', 'default');
+    }
+    $connection
       ->insert('simpletest')
       ->fields($assertion)
       ->execute();
@@ -474,14 +494,19 @@ abstract class DrupalTestCase {
         );
         $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();
-        try {
-          $this->$method();
-          // Finish up.
+        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();
         // Remove the completion check record.
         DrupalTestCase::deleteAssert($completion_check_id);
       }
@@ -691,6 +716,7 @@ class DrupalUnitTestCase extends DrupalTestCase {
       unset($module_list['locale']);
       module_list(TRUE, FALSE, FALSE, $module_list);
     }
+    $this->setup = TRUE;
   }
 
   protected function tearDown() {
@@ -1357,6 +1383,7 @@ class DrupalWebTestCase extends DrupalTestCase {
     variable_set('mail_system', array('default-system' => 'TestingMailSystem'));
 
     drupal_set_time_limit($this->timeLimit);
+    $this->setup = TRUE;
   }
 
   /**
diff --git a/core/modules/simpletest/simpletest.test b/core/modules/simpletest/simpletest.test
index 7a02aa1..b3df0a2 100644
--- a/core/modules/simpletest/simpletest.test
+++ b/core/modules/simpletest/simpletest.test
@@ -503,3 +503,53 @@ class SimpleTestMissingDependentModuleUnitTest extends DrupalUnitTestCase {
     $this->fail(t('Running test with missing required module.'));
   }
 }
+
+/**
+ * Tests a test case that does not run parent::setUp() in its setUp() method.
+ *
+ * If a test case does not call parent::setUp(), running
+ * DrupalTestCase::tearDown() would destroy the main site's database tables.
+ * Therefore, we ensure that tests which are not set up properly are skipped.
+ *
+ * @see DrupalTestCase
+ */
+class SimpleTestBrokenSetUp extends DrupalWebTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Broken SimpleTest method',
+      'description' => 'Tests a test case that does not call parent::setUp().',
+      'group' => 'SimpleTest'
+    );
+  }
+
+  function setUp() {
+    // If the test is being run from the main site, set up normally.
+    if (!drupal_valid_test_ua()) {
+      parent::setUp('simpletest');
+      // Create and log in user.
+      $admin_user = $this->drupalCreateUser(array('administer unit tests'));
+      $this->drupalLogin($admin_user);
+    }
+    // If the test is being run from within simpletest, set up the broken test.
+    else {
+      $this->pass(t('The test setUp() method has been run.'));
+      // Don't call parent::setUp(). This should trigger an error message.
+    }
+  }
+
+  /**
+   * Runs this test case from within the simpletest child site.
+   */
+  function testBreakSetUp() {
+    // Only execute the test method from within the child site.
+    if (!drupal_valid_test_ua()) {
+      // Run this test from web interface.
+      $edit['SimpleTestBrokenSetUp'] = TRUE;
+      $this->drupalPost('admin/config/development/testing', $edit, t('Run tests'));
+
+      // Verify that the test is skipped.
+      $this->assertRaw(t('The test setUp() method has been run.'));
+      $this->assertRaw(t('The test cannot be executed because it has not been set up properly.'));
+    }
+  }
+}
diff --git a/core/modules/simpletest/tests/upgrade/upgrade.test b/core/modules/simpletest/tests/upgrade/upgrade.test
index 69a5384..c53050e 100644
--- a/core/modules/simpletest/tests/upgrade/upgrade.test
+++ b/core/modules/simpletest/tests/upgrade/upgrade.test
@@ -136,6 +136,7 @@ abstract class UpgradePathTestCase extends DrupalWebTestCase {
     $this->variable_set('site_mail', 'simpletest@example.com');
 
     drupal_set_time_limit($this->timeLimit);
+    $this->setup = TRUE;
   }
 
   /**
