diff --git a/core/scripts/run-tests.sh b/core/scripts/run-tests.sh
index 70bdf4a..5353ebe 100755
--- a/core/scripts/run-tests.sh
+++ b/core/scripts/run-tests.sh
@@ -80,7 +80,7 @@
 }
 
 // Execute tests.
-simpletest_script_execute_batch($tests_to_run);
+$has_fails_or_exceptions = simpletest_script_execute_batch($tests_to_run);
 
 // Stop the timer.
 simpletest_script_reporter_timer_stop();
@@ -98,7 +98,12 @@
 }
 
 // Test complete, exit.
-exit;
+if ($has_fails_or_exceptions) {
+  exit(1);
+}
+else {
+  exit;
+}
 
 /**
  * Print help text.
@@ -502,6 +507,9 @@ function simpletest_script_setup_database($new = FALSE) {
 function simpletest_script_execute_batch($test_classes) {
   global $args, $test_ids;
 
+  // Keep track of any failed tests or tests with exceptions in order to return a status code at the end of the script.
+  $has_fails_or_exceptions = FALSE;
+
   // Multi-process execution.
   $children = array();
   while (!empty($test_classes) || !empty($children)) {
@@ -518,7 +526,7 @@ function simpletest_script_execute_batch($test_classes) {
       // Process phpunit tests immediately since they are fast and we don't need
       // to fork for them.
       if (is_subclass_of($test_class, 'Drupal\Tests\UnitTestCase')) {
-        simpletest_script_run_phpunit($test_id, $test_class);
+        $has_fails_or_exceptions = simpletest_script_run_phpunit($test_id, $test_class);
         continue;
       }
 
@@ -549,7 +557,7 @@ function simpletest_script_execute_batch($test_classes) {
       if (empty($status['running'])) {
         // The child exited, unregister it.
         proc_close($child['process']);
-        if ($status['exitcode']) {
+        if ($status['exitcode'] == 1) {
           echo 'FATAL ' . $child['class'] . ': test runner returned a non-zero error code (' . $status['exitcode'] . ').' . "\n";
           if ($args['die-on-fail']) {
             list($db_prefix, ) = simpletest_last_test_get($child['test_id']);
@@ -560,6 +568,9 @@ function simpletest_script_execute_batch($test_classes) {
             $args['repeat'] = -1;
           }
         }
+        else if ($status['exitcode'] == 2) {
+          $has_fails_or_exceptions = TRUE;
+        }
         // Free-up space by removing any potentially created resources.
         if (!$args['keep-results']) {
           simpletest_script_cleanup($child['test_id'], $child['class'], $status['exitcode']);
@@ -570,6 +581,7 @@ function simpletest_script_execute_batch($test_classes) {
       }
     }
   }
+  return $has_fails_or_exceptions;
 }
 
 /**
@@ -608,9 +620,15 @@ function simpletest_script_run_phpunit($test_id, $class) {
     }
   }
 
+  $has_fails = FALSE;
   foreach ($summaries as $class => $summary) {
     simpletest_script_reporter_display_summary($class, $summary);
+
+    if ($summary['#fail'] || $summary['#exception']) {
+      $has_fails = TRUE;
+    }
   }
+  return $has_fails;
 }
 
 /**
@@ -627,6 +645,10 @@ function simpletest_script_run_one_test($test_id, $test_class) {
 
     simpletest_script_reporter_display_summary($test_class, $test->results);
 
+    if ($test->results['#fail'] || $test->results['#exception']) {
+      exit(2);
+    }
+
     // Finished, kill this runner.
     exit(0);
   }
