diff --git a/core/modules/system/tests/modules/deprecation_test/deprecation_test.module b/core/modules/system/tests/modules/deprecation_test/deprecation_test.module
new file mode 100644
index 0000000000..fd1092a3c6
--- /dev/null
+++ b/core/modules/system/tests/modules/deprecation_test/deprecation_test.module
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * A deprecated function.
+ *
+ * @return string
+ *   A known return value of 'known_return_value'.
+ *
+ * @deprecated in Drupal 8.4.x. Might be removed before Drupal 9.0.0. This is
+ *   the deprecation message for deprecated_test_function().
+ */
+function deprecation_test_function() {
+  @trigger_error('This is the deprecation message for deprecation_test_function().', E_USER_DEPRECATED);
+  return 'known_return_value';
+}
diff --git a/core/modules/system/tests/modules/deprecation_test/deprecation_test.routing.yml b/core/modules/system/tests/modules/deprecation_test/deprecation_test.routing.yml
new file mode 100644
index 0000000000..3ef71b806f
--- /dev/null
+++ b/core/modules/system/tests/modules/deprecation_test/deprecation_test.routing.yml
@@ -0,0 +1,6 @@
+deprecation_test.route:
+  path: '/this-calls-a-deprecated-method'
+  defaults:
+    _controller: \Drupal\deprecation_test\DeprecatedController::deprecatedMethod
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/system/tests/modules/deprecation_test/src/DeprecatedController.php b/core/modules/system/tests/modules/deprecation_test/src/DeprecatedController.php
new file mode 100644
index 0000000000..44cf330cc8
--- /dev/null
+++ b/core/modules/system/tests/modules/deprecation_test/src/DeprecatedController.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Drupal\deprecation_test;
+
+/**
+ * Defines a controller that calls a deprecated method.
+ */
+class DeprecatedController {
+
+  /**
+   * Controller callback.
+   *
+   * @return array
+   *   Render array.
+   */
+  public function deprecatedMethod() {
+    return [
+      '#markup' => deprecation_test_function(),
+    ];
+  }
+
+}
diff --git a/core/phpunit.xml.dist b/core/phpunit.xml.dist
index c85258d77f..3d004dbe6b 100644
--- a/core/phpunit.xml.dist
+++ b/core/phpunit.xml.dist
@@ -45,7 +45,7 @@
     </testsuite>
   </testsuites>
   <listeners>
-    <listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener">
+    <listener class="\Drupal\Tests\Listeners\DrupalPhpUnitBridgeListener">
     </listener>
     <listener class="\Drupal\Tests\Listeners\DrupalStandardsListener">
     </listener>
diff --git a/core/tests/Drupal/FunctionalTests/Core/Test/PhpUnitBridgeTest.php b/core/tests/Drupal/FunctionalTests/Core/Test/PhpUnitBridgeTest.php
new file mode 100644
index 0000000000..bc843c31a1
--- /dev/null
+++ b/core/tests/Drupal/FunctionalTests/Core/Test/PhpUnitBridgeTest.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Drupal\FunctionalTests\Core\Test;
+
+use Drupal\Core\Url;
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Tests Drupal's integration with Symfony PHPUnit Bridge.
+ *
+ * @group Test
+ * @group legacy
+ */
+class PhpUnitBridgeTest extends BrowserTestBase {
+
+  protected static $modules = ['deprecation_test'];
+
+  /**
+   * @expectedDeprecation This is the deprecation message for deprecation_test_function().
+   */
+  public function testSilencedError() {
+    $this->assertEquals('known_return_value', deprecation_test_function());
+  }
+
+  /**
+   * @expectedDeprecation This is the deprecation message for deprecation_test_function().
+   */
+  public function testErrorOnSiteUnderTest() {
+    $this->drupalGet(Url::fromRoute('deprecation_test.route'));
+  }
+
+}
diff --git a/core/tests/Drupal/KernelTests/Core/Test/PhpUnitBridgeTest.php b/core/tests/Drupal/KernelTests/Core/Test/PhpUnitBridgeTest.php
new file mode 100644
index 0000000000..3de3982046
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/Test/PhpUnitBridgeTest.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Drupal\KernelTests\Core\Test;
+
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\deprecation_test\Deprecation\FixtureDeprecatedClass;
+
+/**
+ * Test how kernel tests interact with deprecation errors.
+ *
+ * @group Test
+ * @group legacy
+ */
+class PhpUnitBridgeTest extends KernelTestBase {
+
+  public static $modules = ['deprecation_test'];
+
+  /**
+   * @expectedDeprecation Drupal\deprecation_test\FixtureDeprecatedClass is deprecated.
+   */
+  public function testDeprecatedClass() {
+    $deprecated = new FixtureDeprecatedClass();
+    $this->assertEquals('test', $deprecated->testFunction());
+  }
+
+  /**
+   * @expectedDeprecation This is the deprecation message for deprecation_test_function().
+   */
+  public function testDeprecatedFunction() {
+    $this->assertEquals('known_return_value', \deprecation_test_function());
+  }
+
+}
diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index 6a35f15373..55c3d4a16b 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -986,6 +986,7 @@ protected function prepareTemplate(\Text_Template $template) {
       'included_files' => '',
       'globals' => $bootstrap_globals,
     ]);
+    $template->setFile(__DIR__ . '/../../Template/TestCaseMethod.tpl');
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/BrowserTestBase.php b/core/tests/Drupal/Tests/BrowserTestBase.php
index bd50c23b48..0fd4143dd8 100644
--- a/core/tests/Drupal/Tests/BrowserTestBase.php
+++ b/core/tests/Drupal/Tests/BrowserTestBase.php
@@ -262,6 +262,14 @@
   protected $metaRefreshCount = 0;
 
   /**
+   * {@inheritdoc}
+   */
+  protected function prepareTemplate(\Text_Template $template) {
+    parent::prepareTemplate($template);
+    $template->setFile(__DIR__ . '/../../Template/TestCaseMethod.tpl');
+  }
+
+  /**
    * Initializes Mink sessions.
    */
   protected function initMink() {
diff --git a/core/tests/Drupal/Tests/Core/Test/PhpUnitBridgeIsolatedTest.php b/core/tests/Drupal/Tests/Core/Test/PhpUnitBridgeIsolatedTest.php
new file mode 100644
index 0000000000..72806b44c3
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Test/PhpUnitBridgeIsolatedTest.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Drupal\Tests\Core\Test;
+
+use Drupal\Tests\UnitTestCase;
+use Drupal\deprecation_test\Deprecation\FixtureDeprecatedClass;
+
+/**
+ * Test how unit tests interact with deprecation errors in process isolation.
+ *
+ * @runTestsInSeparateProcesses
+ *
+ * @group Test
+ * @group legacy
+ */
+class PhpUnitBridgeIsolatedTest extends UnitTestCase {
+
+  /**
+   * @expectedDeprecation Drupal\deprecation_test\Deprecation\FixtureDeprecatedClass is deprecated.
+   */
+  public function testDeprecatedClass() {
+    $deprecated = new FixtureDeprecatedClass();
+    $this->assertEquals('test', $deprecated->testFunction());
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Test/PhpUnitBridgeTest.php b/core/tests/Drupal/Tests/Core/Test/PhpUnitBridgeTest.php
new file mode 100644
index 0000000000..73ba0de167
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Test/PhpUnitBridgeTest.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Drupal\Tests\Core\Test;
+
+use Drupal\Tests\UnitTestCase;
+use Drupal\deprecation_test\Deprecation\FixtureDeprecatedClass;
+
+/**
+ * Test how unit tests interact with deprecation errors.
+ *
+ * @group Test
+ * @group legacy
+ */
+class PhpUnitBridgeTest extends UnitTestCase {
+
+  /**
+   * @expectedDeprecation Drupal\deprecation_test\Deprecation\FixtureDeprecatedClass is deprecated.
+   */
+  public function testDeprecatedClass() {
+    $deprecated = new FixtureDeprecatedClass();
+    $this->assertEquals('test', $deprecated->testFunction());
+  }
+
+  public function testDeprecatedFunction() {
+    $this->markTestIncomplete('Modules are not loaded for unit tests, so deprecated_test_function() will not be available.');
+    $this->assertEquals('known_return_value', \deprecation_test_function());
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Listeners/DrupalPhpUnitBridgeListener.php b/core/tests/Drupal/Tests/Listeners/DrupalPhpUnitBridgeListener.php
new file mode 100644
index 0000000000..a6880f0177
--- /dev/null
+++ b/core/tests/Drupal/Tests/Listeners/DrupalPhpUnitBridgeListener.php
@@ -0,0 +1,57 @@
+<?php
+
+namespace Drupal\Tests\Listeners;
+
+use Symfony\Bridge\PhpUnit\SymfonyTestsListener;
+
+/**
+ * Wrapper listener for SymfonyTestsListener.
+ *
+ * This listener allows us to tell the deprecation listener to ignore tests
+ * that will be run in isolation. This listener is also registered for tests
+ * that are in isolation, and in those cases we want the listener to handle
+ * expected deprecation errors.
+ */
+class DrupalPhpUnitBridgeListener extends SymfonyTestsListener {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function startTest(\PHPUnit_Framework_Test $test) {
+    if ($this->wouldBeInIsolation($test)) {
+      return;
+    }
+    parent::startTest($test);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function endTest(\PHPUnit_Framework_Test $test, $time) {
+    if ($this->wouldBeInIsolation($test)) {
+      return;
+    }
+    parent::endTest($test, $time);
+  }
+
+  /**
+   * Determines if a test is expected to be run in isolation.
+   *
+   * @param \PHPUnit_Framework_Test $test
+   *   The test in question.
+   *
+   * @return bool
+   *   TRUE if we expect this test to run in isolation, FALSE otherwise.
+   */
+  protected function wouldBeInIsolation(\PHPUnit_Framework_Test $test) {
+    if (!function_exists('__phpunit_run_isolated_test')) {
+      if ($test instanceof \PHPUnit_Framework_TestCase) {
+        $ref_isolated = new \ReflectionProperty($test, 'runTestInSeparateProcess');
+        $ref_isolated->setAccessible(TRUE);
+        return $ref_isolated->getValue($test);
+      }
+    }
+    return FALSE;
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/UnitTestCase.php b/core/tests/Drupal/Tests/UnitTestCase.php
index 8aaeb85743..c7e354a361 100644
--- a/core/tests/Drupal/Tests/UnitTestCase.php
+++ b/core/tests/Drupal/Tests/UnitTestCase.php
@@ -51,6 +51,14 @@ protected function setUp() {
   }
 
   /**
+   * {@inheridoc}
+   */
+  protected function prepareTemplate(\Text_Template $template) {
+    parent::prepareTemplate($template);
+    $template->setFile(__DIR__ . '/../../Template/TestCaseMethod.tpl');
+  }
+
+  /**
    * Generates a unique random string containing letters and numbers.
    *
    * @param int $length
diff --git a/core/tests/Template/TestCaseMethod.tpl b/core/tests/Template/TestCaseMethod.tpl
new file mode 100644
index 0000000000..9652a87a99
--- /dev/null
+++ b/core/tests/Template/TestCaseMethod.tpl
@@ -0,0 +1,106 @@
+<?php
+
+// This template file is copied from PHPUnit. The only change is the addition of
+// DrupalPhpUnitBridgeListener().
+
+if (!defined('STDOUT')) {
+    // php://stdout does not obey output buffering. Any output would break
+    // unserialization of child process results in the parent process.
+    define('STDOUT', fopen('php://temp', 'w+b'));
+    define('STDERR', fopen('php://stderr', 'wb'));
+}
+
+{iniSettings}
+ini_set('display_errors', 'stderr');
+set_include_path('{include_path}');
+
+$composerAutoload = {composerAutoload};
+$phar             = {phar};
+
+ob_start();
+
+if ($composerAutoload) {
+    require_once $composerAutoload;
+    define('PHPUNIT_COMPOSER_INSTALL', $composerAutoload);
+} else if ($phar) {
+    require $phar;
+}
+
+function __phpunit_run_isolated_test()
+{
+    if (!class_exists('{className}')) {
+        require_once '{filename}';
+    }
+
+    $result = new PHPUnit_Framework_TestResult;
+
+    if ({collectCodeCoverageInformation}) {
+        $result->setCodeCoverage(
+            new PHP_CodeCoverage(
+                null,
+                unserialize('{codeCoverageFilter}')
+            )
+        );
+    }
+
+    $result->beStrictAboutTestsThatDoNotTestAnything({isStrictAboutTestsThatDoNotTestAnything});
+    $result->beStrictAboutOutputDuringTests({isStrictAboutOutputDuringTests});
+    $result->beStrictAboutTestSize({isStrictAboutTestSize});
+    $result->beStrictAboutTodoAnnotatedTests({isStrictAboutTodoAnnotatedTests});
+
+    $listener = new Drupal\Tests\Listeners\DrupalPhpUnitBridgeListener();
+    $result->addListener($listener);
+
+    $test = new {className}('{methodName}', unserialize('{data}'), '{dataName}');
+    $test->setDependencyInput(unserialize('{dependencyInput}'));
+    $test->setInIsolation(TRUE);
+
+    ob_end_clean();
+    $test->run($result);
+    $output = '';
+    if (!$test->hasExpectationOnOutput()) {
+        $output = $test->getActualOutput();
+    }
+
+    @rewind(STDOUT); /* @ as not every STDOUT target stream is rewindable */
+    if ($stdout = stream_get_contents(STDOUT)) {
+        $output = $stdout . $output;
+    }
+
+    print serialize(
+      array(
+        'testResult'    => $test->getResult(),
+        'numAssertions' => $test->getNumAssertions(),
+        'result'        => $result,
+        'output'        => $output
+      )
+    );
+}
+
+$configurationFilePath = '{configurationFilePath}';
+
+if ('' !== $configurationFilePath) {
+    $configuration = PHPUnit_Util_Configuration::getInstance($configurationFilePath);
+    $configuration->handlePHPConfiguration();
+    unset($configuration);
+}
+
+function __phpunit_error_handler($errno, $errstr, $errfile, $errline, $errcontext)
+{
+   return true;
+}
+
+set_error_handler("__phpunit_error_handler");
+
+{constants}
+{included_files}
+{globals}
+
+restore_error_handler();
+
+if (isset($GLOBALS['__PHPUNIT_BOOTSTRAP'])) {
+    require_once $GLOBALS['__PHPUNIT_BOOTSTRAP'];
+    unset($GLOBALS['__PHPUNIT_BOOTSTRAP']);
+}
+
+__phpunit_run_isolated_test();
