diff --git a/core/tests/Drupal/Tests/Scripts/TestSiteApplicationTest.php b/core/tests/Drupal/Tests/Core/Scripts/TestSiteApplicationTest.php
similarity index 86%
rename from core/tests/Drupal/Tests/Scripts/TestSiteApplicationTest.php
rename to core/tests/Drupal/Tests/Core/Scripts/TestSiteApplicationTest.php
index 50d9f99640..7b6d08ea2a 100644
--- a/core/tests/Drupal/Tests/Scripts/TestSiteApplicationTest.php
+++ b/core/tests/Drupal/Tests/Core/Scripts/TestSiteApplicationTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\Tests\Scripts;
+namespace Drupal\Tests\Core\Scripts;
 
 use Drupal\Component\FileSystem\FileSystem;
 use Drupal\Core\Database\Database;
@@ -25,6 +25,9 @@
  * @see \Drupal\TestSite\TestSiteApplication
  * @see \Drupal\TestSite\Commands\TestSiteInstallCommand
  * @see \Drupal\TestSite\Commands\TestSiteTearDownCommand
+ *
+ * @todo Move this into a separate Scripts namespace after
+ *   https://www.drupal.org/project/drupal/issues/2878269
  */
 class TestSiteApplicationTest extends UnitTestCase {
 
@@ -36,6 +39,27 @@ protected function setUp() {
     $this->root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))));
   }
 
+  /**
+   * Gets the connection object for the specified database key and target.
+   *
+   * Skip the test when there is no database available.
+   *
+   * @param string $target
+   *   The database target name.
+   * @param string $key
+   *   The database connection key. Defaults to NULL which means the active key.
+   *
+   * @return \Drupal\Core\Database\Connection
+   *   The corresponding connection object.
+   */
+  protected function getDatabaseConnection($target, $key = NULL) {
+    try {
+      return Database::getConnection($target, $key);
+    } catch (\PDOException $e) {
+      $this->markTestSkipped('This test requires a valid database connection.');
+    }
+  }
+
   /**
    * @coversNothing
    */
@@ -44,7 +68,7 @@ public function testInstallWithNonExistingFile() {
     $php_binary_path = $php_binary_finder->find();
 
     // Create a connection to the DB configured in SIMPLETEST_DB.
-    $connection = Database::getConnection('default', $this->addTestDatabase(''));
+    $connection = $this->getDatabaseConnection('default', $this->addTestDatabase(''));
     $table_count = count($connection->schema()->findTables('%'));
 
     $command_line = $php_binary_path . ' core/scripts/test-site.php install --setup-file "this-class-does-not-exist" --db-url "' . getenv('SIMPLETEST_DB') . '"';
@@ -64,7 +88,7 @@ public function testInstallWithFileWithNoClass() {
     $php_binary_path = $php_binary_finder->find();
 
     // Create a connection to the DB configured in SIMPLETEST_DB.
-    $connection = Database::getConnection('default', $this->addTestDatabase(''));
+    $connection = $this->getDatabaseConnection('default', $this->addTestDatabase(''));
     $table_count = count($connection->schema()->findTables('%'));
 
     $command_line = $php_binary_path . ' core/scripts/test-site.php install --setup-file core/tests/fixtures/empty_file.php.module --db-url "' . getenv('SIMPLETEST_DB') . '"';
@@ -84,7 +108,7 @@ public function testInstallWithNonSetupClass() {
     $php_binary_path = $php_binary_finder->find();
 
     // Create a connection to the DB configured in SIMPLETEST_DB.
-    $connection = Database::getConnection('default', $this->addTestDatabase(''));
+    $connection = $this->getDatabaseConnection('default', $this->addTestDatabase(''));
     $table_count = count($connection->schema()->findTables('%'));
 
     // Use __FILE__ to test absolute paths.
@@ -92,7 +116,7 @@ public function testInstallWithNonSetupClass() {
     $process = new Process($command_line, $this->root, ['COLUMNS' => PHP_INT_MAX]);
     $process->run();
 
-    $this->assertContains('The class Drupal\Tests\Scripts\TestSiteApplicationTest contained in', $process->getErrorOutput());
+    $this->assertContains('The class Drupal\Tests\Core\Scripts\TestSiteApplicationTest contained in', $process->getErrorOutput());
     $this->assertContains('needs to implement \Drupal\TestSite\TestSetupInterface', $process->getErrorOutput());
     $this->assertSame(1, $process->getExitCode());
     $this->assertCount($table_count, $connection->schema()->findTables('%'), 'No additional tables created in the database');
@@ -106,6 +130,11 @@ public function testInstallScript() {
     if (!is_writable($simpletest_path)) {
       $this->markTestSkipped("Requires the directory $simpletest_path to exist and be writable");
     }
+    // Skip the test if there is no database connection available. We don't
+    // actually need the connection, but we want to give the test a chance to
+    // skip if there is no database configured.
+    $this->getDatabaseConnection('default', $this->addTestDatabase(''));
+
     $php_binary_finder = new PhpExecutableFinder();
     $php_binary_path = $php_binary_finder->find();
 
@@ -208,6 +237,11 @@ public function testInstallInDifferentLanguage() {
     if (!is_writable($simpletest_path)) {
       $this->markTestSkipped("Requires the directory $simpletest_path to exist and be writable");
     }
+    // Skip the test if there is no database connection available. We don't
+    // actually need the connection, but we want to give the test a chance to
+    // skip if there is no database configured.
+    $this->getDatabaseConnection('default', $this->addTestDatabase(''));
+
     $php_binary_finder = new PhpExecutableFinder();
     $php_binary_path = $php_binary_finder->find();
 
@@ -264,6 +298,10 @@ public function testTearDownDbPrefixValidation() {
    *   The database key of the added connection.
    */
   protected function addTestDatabase($db_prefix) {
+    // If SIMPLETEST_DB is not set, it will be FALSE. It could also be empty.
+    if (empty(getenv('SIMPLETEST_DB'))) {
+      $this->markTestSkipped('Needs the SIMPLETEST_DB environmental variable in order to install to a database.');
+    }
     $database = Database::convertDbUrlToConnectionInfo(getenv('SIMPLETEST_DB'), $this->root);
     $database['prefix'] = ['default' => $db_prefix];
     $target = __CLASS__ . $db_prefix;
