Smoke Testing

As you do automated deployments, you should check if the website is up and running before switching it to the live site. This is called a Smoke Test. We will give an example for using the built-in HTTP smoke test.

First, you need to create a virtual host with document root in "<deploymentDirectory>/releases/next/Web". While a deployment is running, the new website will be available under this URL and can be used for testing.

Then, add a test as follows to the deployment configuration:

<?php

$workflow = new \TYPO3\Surf\Domain\Model\SimpleWorkflow();

$smokeTestOptions = [
        'url' => 'http://your-website.com',
        'remote' => true,
        'expectedStatus' => 200,
        'expectedRegexp' => '/somethingYouExpectOnThePage/'
];
$workflow->defineTask('MyCompany\\MyPackage\\SmokeTest', \TYPO3\Surf\Task\Test\HttpTestTask::class, $smokeTestOptions);

$workflow->addTask('MyCompany\\MyPackage\\SmokeTest', 'test', $application);

The HTTP test has the following options:

Most important options:

  • url (required): URL which should be loaded

  • remote: if TRUE, the smoke test is triggered through the SSH channel on the remote host via command-line CURL. If false, it is triggered from the deploying host.

  • expectedStatus: expected HTTP status code

  • expectedHeaders: HTTP Header Strings which are expected (can be a multiline string, each header being on a separate line)

  • expectedRegexp: Regular Expression to test the contents of the HTTP response against

Further options:

  • timeout (only if remote=FALSE): HTTP timeout to use

  • port (only if remote=FALSE): HTTP Port to use

  • method (only if remote=FALSE): HTTP method to use (default GET)

  • username (only if remote=FALSE): HTTP Authentication username

  • password (only if remote=FALSE): HTTP Authentication Password

  • data (only if remote=FALSE): HTTP payload

  • proxy (only if remote=FALSE): HTTP Proxy to use

  • proxyPort (only if remote=FALSE): HTTP Proxy port to use

  • additionalCurlParameters (only if remote=TRUE): list of parameters which is directly passed to CURL. Especially useful to e.g. disable SSL certificate check (with --insecure)

Tests in test stage and caches

In the test stage, the caches of the application is not flushed in order not to affect the live page. A possible solution is to disable caches when running smoke tests in the test stage on "next" release.

TYPO3

AdditionalConfiguration.php:

if ($context->isTesting()){
        foreach ($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'] as $cacheName => $cacheConfiguration) {
                $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'][$cacheName]['backend'] = \TYPO3\CMS\Core\Cache\Backend\NullBackend::class;
        }
}

.htaccess:

# Add Rewrite rule near https://github.com/TYPO3/typo3/blob/main/typo3/sysext/install/Resources/Private/FolderStructureTemplateFiles/root-htaccess#L270
RewriteCond %{HTTP_HOST} ^next\.example\.com$
RewriteRule .? - [E=TYPO3_CONTEXT:Testing]

If you are not able to set environment variables via .htaccess, you can use composer autoloading and a PHP file. Thanks to the team of jweiland.net for this solution.

Root composer.json:

{
        "autoload": {
                "files": ["scripts/typo3context.php"]
        }
}

typo3context.php:

<?php
// Set the application context in this file because it is not possible to set environment variables
// via .htaccess e.g. on domainFACTORY/jweiland.net servers
$context = 'Production';

// detect application context by domain
if (array_key_exists('HTTP_HOST', $_SERVER)) {
        if (0 === strpos($_SERVER['HTTP_HOST'], 'next.')) {
                $context = 'Testing';
        }
}
putenv('TYPO3_CONTEXT=' . $context);