diff --git a/composer.json b/composer.json
index 30e4a8987fa32183849247027b1b5a135dcd095b..a5f5e940a8c3d647fc2e69344f24bd6458f9fcf3 100644
--- a/composer.json
+++ b/composer.json
@@ -66,7 +66,7 @@
 		"fiunchinho/phpunit-randomizer": "^4.0",
 		"friendsofphp/php-cs-fixer": "^2.12.2",
 		"typo3/cms-styleguide": "^9.1",
-		"typo3/testing-framework": "^4.0.2"
+		"typo3/testing-framework": "~4.1.0"
 	},
 	"suggest": {
 		"ext-gd": "GDlib/Freetype is required for building images with text (GIFBUILDER) and can also be used to scale images",
diff --git a/composer.lock b/composer.lock
index 47ba308090197b30e3ee23766a96ba43c9a94627..5e22986778ad2623203a8a184db98edaa78a0051 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "a71e25c63829d22da3013a310006d675",
+    "content-hash": "cb674f386df7a9d87641f393120ecbac",
     "packages": [
         {
             "name": "cogpowered/finediff",
@@ -4722,16 +4722,16 @@
         },
         {
             "name": "typo3/testing-framework",
-            "version": "4.0.2",
+            "version": "4.1.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/TYPO3/testing-framework.git",
-                "reference": "dadfd1c953856429ad2a1b9ab8b8bea779e1f960"
+                "reference": "f3371a5cedc30ada5bc38a4d3b3d92baea1d2873"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/TYPO3/testing-framework/zipball/dadfd1c953856429ad2a1b9ab8b8bea779e1f960",
-                "reference": "dadfd1c953856429ad2a1b9ab8b8bea779e1f960",
+                "url": "https://api.github.com/repos/TYPO3/testing-framework/zipball/f3371a5cedc30ada5bc38a4d3b3d92baea1d2873",
+                "reference": "f3371a5cedc30ada5bc38a4d3b3d92baea1d2873",
                 "shasum": ""
             },
             "require": {
@@ -4778,7 +4778,7 @@
                 "tests",
                 "typo3"
             ],
-            "time": "2018-07-23T11:56:51+00:00"
+            "time": "2018-07-25T20:17:43+00:00"
         },
         {
             "name": "webmozart/assert",
diff --git a/typo3/sysext/core/Classes/Core/SystemEnvironmentBuilder.php b/typo3/sysext/core/Classes/Core/SystemEnvironmentBuilder.php
index 2ed868d234b56f8248401b7ab3783412a373d575..96e3e6e8df4655520f0c3e24c83782235702c604 100644
--- a/typo3/sysext/core/Classes/Core/SystemEnvironmentBuilder.php
+++ b/typo3/sysext/core/Classes/Core/SystemEnvironmentBuilder.php
@@ -267,18 +267,41 @@ class SystemEnvironmentBuilder
      */
     public static function initializeEnvironment(ApplicationContext $context)
     {
-        $sitePath = rtrim(PATH_site, '/');
+        $isCli = PHP_SAPI === 'cli';
+        // Absolute path of the entry script that was called
+        $scriptPath = PATH_thisScript;
+        $rootPath = rtrim(PATH_site, '/');
+        if (getenv('TYPO3_PATH_ROOT')) {
+            $rootPath = GeneralUtility::fixWindowsFilePath(getenv('TYPO3_PATH_ROOT'));
+            $rootPath = rtrim($rootPath, '/');
+            // Check if the root path has been set in the environment (e.g. by the composer installer)
+            if ($isCli && self::usesComposerClassLoading() && StringUtility::endsWith($scriptPath, 'typo3')) {
+                // PATH_thisScript is used for various path calculations based on the document root
+                // Therefore we assume it is always a subdirectory of the document root, which is not the case
+                // in composer mode on cli, as the binary is in the composer bin directory.
+                // Because of that, we enforce the document root path of this binary to be set
+                $scriptName = '/typo3/sysext/core/bin/typo3';
+            } else {
+                // Base the script path on the path taken from the environment
+                // to make relative path calculations work in case only one of both is symlinked
+                // or has the real path
+                $scriptName = substr($scriptPath, strlen($rootPath));
+            }
+            $scriptPath = $rootPath . $scriptName;
+        }
+
+        $sitePath = rtrim($rootPath, '/');
         $projectRootPath = GeneralUtility::fixWindowsFilePath(getenv('TYPO3_PATH_APP'));
         $isDifferentRootPath = ($projectRootPath && $projectRootPath !== $sitePath);
         Environment::initialize(
             $context,
-            PHP_SAPI === 'cli',
+            $isCli,
             self::usesComposerClassLoading(),
             $isDifferentRootPath ? $projectRootPath : $sitePath,
             $sitePath,
             $isDifferentRootPath ? $projectRootPath . '/var'    : $sitePath . '/typo3temp/var',
             $isDifferentRootPath ? $projectRootPath . '/config' : $sitePath . '/typo3conf',
-            PATH_thisScript,
+            $scriptPath,
             self::getTypo3Os() === 'WIN' ? 'WINDOWS' : 'UNIX'
         );
     }
diff --git a/typo3/sysext/core/Classes/Database/ConnectionPool.php b/typo3/sysext/core/Classes/Database/ConnectionPool.php
index 47e5ced106a2b9c039f6277e73349780fccebe13..5f77766343013c5bc79c679096f48e48b3bce24e 100644
--- a/typo3/sysext/core/Classes/Database/ConnectionPool.php
+++ b/typo3/sysext/core/Classes/Database/ConnectionPool.php
@@ -235,4 +235,16 @@ class ConnectionPool
     {
         return $this->customDoctrineTypes;
     }
+
+    /**
+     * Reset internal list of connections. This is an internal method (for now)
+     * currently used in functional tests only to close connections and start
+     * new ones in between single tests.
+     *
+     * @internal May be changed or removed any point in time
+     */
+    public function resetConnections(): void
+    {
+        static::$connections = [];
+    }
 }
diff --git a/typo3/sysext/core/Classes/Utility/GeneralUtility.php b/typo3/sysext/core/Classes/Utility/GeneralUtility.php
index f2c8c7eedc54b36f241361de7d2a085263ac0c38..58aae0174841385fad8c68f8f2e92731259e1fdf 100644
--- a/typo3/sysext/core/Classes/Utility/GeneralUtility.php
+++ b/typo3/sysext/core/Classes/Utility/GeneralUtility.php
@@ -4141,6 +4141,19 @@ class GeneralUtility
         }
     }
 
+    /**
+     * For testing purposes only!
+     * The functional test framework uses this to reset the internal $application context
+     * variable in between multiple tests before it is re-initialized using presetApplicationContext()
+     * which otherwise throws an exception if the internal variable is already set.
+     *
+     * @internal May be changed or removed any time
+     */
+    public static function resetApplicationContext(): void
+    {
+        static::$applicationContext = null;
+    }
+
     /**
      * Get the ApplicationContext
      *
diff --git a/typo3/sysext/core/Tests/Functional/Cache/Backend/MemcachedBackendTest.php b/typo3/sysext/core/Tests/Functional/Cache/Backend/MemcachedBackendTest.php
index 5ee450e3eae7255b2aba4505d8000c9e365ce253..c03545b795c89f7774765d99f6c62d9e54f80641 100644
--- a/typo3/sysext/core/Tests/Functional/Cache/Backend/MemcachedBackendTest.php
+++ b/typo3/sysext/core/Tests/Functional/Cache/Backend/MemcachedBackendTest.php
@@ -29,7 +29,8 @@ class MemcachedBackendTest extends FunctionalTestCase
      */
     protected function setUp()
     {
-        parent::setUp();
+        // Note this functional does NOT call parent::setUp() since it does
+        // not need a full blown instance and database
         if (!extension_loaded('memcache') && !extension_loaded('memcached')) {
             $this->markTestSkipped('Neither "memcache" nor "memcached" extension was available');
         }
diff --git a/typo3/sysext/core/Tests/Functional/Cache/Backend/RedisBackendTest.php b/typo3/sysext/core/Tests/Functional/Cache/Backend/RedisBackendTest.php
index 7e9600937acc6512788ff6316e571f5bc415d94b..45f41a2e4fb9987fcb65f7fd6d75e76e81c1b438 100644
--- a/typo3/sysext/core/Tests/Functional/Cache/Backend/RedisBackendTest.php
+++ b/typo3/sysext/core/Tests/Functional/Cache/Backend/RedisBackendTest.php
@@ -32,6 +32,8 @@ class RedisBackendTest extends FunctionalTestCase
      */
     protected function setUp()
     {
+        // Note this functional does NOT call parent::setUp() since it does
+        // not need a full blown instance and database
         if (!extension_loaded('redis')) {
             $this->markTestSkipped('redis extension was not available');
         }
diff --git a/typo3/sysext/core/composer.json b/typo3/sysext/core/composer.json
index c81f317073388005206acfdb7de33018e9bda222..0033f27c6d4a5a810d302246cf3e1cfb257a3ac4 100644
--- a/typo3/sysext/core/composer.json
+++ b/typo3/sysext/core/composer.json
@@ -47,7 +47,7 @@
 		"fiunchinho/phpunit-randomizer": "^4.0",
 		"friendsofphp/php-cs-fixer": "^2.12.2",
 		"typo3/cms-styleguide": "^9.1",
-		"typo3/testing-framework": "^4.0.2"
+		"typo3/testing-framework": "~4.1.0"
 	},
 	"suggest": {
 		"ext-fileinfo": "Used for proper file type detection in the file abstraction layer",