---
title: "Extension testing"
manual: "TYPO3 Explained"
version: "main"
permalink: "https://docs.typo3.org/permalink/t3coreapi:testing-extensions@main"
source: "Testing/ExtensionTesting.rst"
rendered: "2026-09-18T10:16:27+00:00"
---

# Extension testing {#extension-testing}

When developing TYPO3 extensions, testing can greatly improve the code quality.

In theory you can test your extension like any other PHP application
and extensions. There are however some conventions that make contribution and
collaboration easier. And there are some tools that should make your life
maintaining an extension easier.

Which tools to use and which rules to apply is highly opinionated. However,
having automatic tests is better than no automatic tests, no matter the strategy
you follow.

The following test strategies should be applied to improve your code quality.

**Table of contents**

-   [Composer install / update before running extensions tests](https://docs.typo3.org/permalink/t3coreapi:composer-install-update-before-running-extensions-tests@main)
-   [Linting](https://docs.typo3.org/permalink/t3coreapi:linting@main)
-   [Coding guidelines (CGL)](https://docs.typo3.org/permalink/t3coreapi:coding-guidelines-cgl@main)
-   [Static code analysis (PHPStan / Psalm)](https://docs.typo3.org/permalink/t3coreapi:static-code-analysis-phpstan-psalm@main)
-   [Unit tests (PHPUnit!)](https://docs.typo3.org/permalink/t3coreapi:unit-tests-phpunit@main)
-   [Functional tests](https://docs.typo3.org/permalink/t3coreapi:functional-tests@main)
-   [Acceptance tests](https://docs.typo3.org/permalink/t3coreapi:acceptance-tests@main)
-   [Organizing and storing the commands](https://docs.typo3.org/permalink/t3coreapi:organizing-and-storing-the-commands@main)

> [!TIP]
> Using the extension kickstarter ([`friendsoftypo3/kickstarter`](https://packagist.org/packages/friendsoftypo3/kickstarter)) you
> can create a testing environment for your extension using the command
> `vendor/bin/typo3 make:testenv`.

## Composer install / update before running extensions tests {#composer-install-update-before-running-extensions-tests}

If you used [`friendsoftypo3/kickstarter`](https://packagist.org/packages/friendsoftypo3/kickstarter) to create your testing
environment all packages are listed in the `composer.json` section
`require-dev`. You must therefore run `composer update` with dev dependencies
using the correct PHP version. The `runTests.sh` script created by the
kickstarter contains a script to do that:

```bash
Build/Scripts/runTests.sh -s composerUpdate
```

If you want to test on a version different to the default PHP version:

```bash
Build/Scripts/runTests.sh -s composerUpdate -p 8.4
```

## Linting {#linting}

A linting test ensures that the syntax of the language used is correct.

In TYPO3 extensions the following languages are commonly linted:

-   PHP in the supported versions
-   TypoScript
-   YAML
-   JavaScript / TypeScript

Depending on your extension, any other file format can be linted
too, if there is tooling for that (for example validating XML files
against a XSD schema).

If you used the [`friendsoftypo3/kickstarter`](https://packagist.org/packages/friendsoftypo3/kickstarter) to create your testing
environment you can run the linting with:

```bash
Build/Scripts/runTests.sh -s lint
```

## Coding guidelines (CGL) {#coding-guidelines-cgl}

If more than one person is working on code, coding guideline are a must-have.
No matter which tool you use or which rules you choose to apply, it is important
that the rules can be applied automatically.

Common tools to help with applying coding guidelines are
[PHP-CS-Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) and
[PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer).

You can find more information in the [Coding guidelines](https://docs.typo3.org/permalink/t3coreapi:cgl@main)
section.

If you used the [`friendsoftypo3/kickstarter`](https://packagist.org/packages/friendsoftypo3/kickstarter) to create your testing
environment you can run the CGL tests with:

```bash
Build/Scripts/runTests.sh -s cgl
```

## Static code analysis (PHPStan / Psalm) {#static-code-analysis-phpstan-psalm}

Static code analysis tools are highly recommended to be used with PHP. The most
common tools used are [PHPStan](https://phpstan.org) and [Psalm](https://psalm.dev). No matter the tool you use or the
rules and levels you apply: You should use one.

There are also static code analysis tools for TypeScript and JavaScript.

If you used the [`friendsoftypo3/kickstarter`](https://packagist.org/packages/friendsoftypo3/kickstarter) to create your testing
environment you can run static code analysis tests, using `phpstan`:

```bash
Build/Scripts/runTests.sh -s phpstan
```

## Unit tests (PHPUnit!) {#unit-tests-phpunit}

Unit tests are executing the code to be tested and define input and their
expected outcome. They are run on an isolated classes or methods.
All relations and services such as database calls, API and curl call **must**
be mocked. Not full instance setup is available. Therefore
[Dependency injection](https://docs.typo3.org/permalink/t3coreapi:dependency-injection@main), the database,
configurations and settings and everything done during
[Bootstrapping](https://docs.typo3.org/permalink/t3coreapi:bootstrapping@main) is not available.

> [!NOTE]
> Rule of thumb: Unit tests are isolated tests not using real services.

See also [Writing unit tests](https://docs.typo3.org/permalink/t3coreapi:testing-writing-unit@main)

If you used the [`friendsoftypo3/kickstarter`](https://packagist.org/packages/friendsoftypo3/kickstarter) to create your testing
environment you can run unit tests like this:

```bash
Build/Scripts/runTests.sh -s unit
```

To run a specific test isolated use:

```bash
Build/Scripts/runTests.sh -s unit -- Tests/Unit/Service/MyServiceTest.php
```

## Functional tests {#functional-tests}

Functional tests, like Unit tests, also execute the code to be tested.
Functional test execute the test code within a fully composed TYPO3
instance (non-composer mode) with configured extensions and configuration,
having full [dependency](https://docs.typo3.org/permalink/t3coreapi:dependency-injection@main) and extension logic
on board and Database backend available.

For this, the
[TYPO3 Testing Framework](https://github.com/TYPO3/testing-framework)
is highly recommended, and performs task like filling the database with
test data (using fixtures) and activating specific Core or third party
extensions (and yours). And, if needed, a backend or frontend user can be
logged in.

A functional test will then test the output of a method or if a method changes
certain other things like the database or the file system. It can also
test more complex functionality of your extension that depends on the
TYPO3 environment being present.

See also [Writing functional tests](https://docs.typo3.org/permalink/t3coreapi:testing-writing-functional@main)

If you used the [`friendsoftypo3/kickstarter`](https://packagist.org/packages/friendsoftypo3/kickstarter) to create your testing
environment you can run unit tests like this:

```bash
Build/Scripts/runTests.sh -s functional
```

To run a specific test isolated use:

```bash
Build/Scripts/runTests.sh -s functional -- Tests/Functional/Service/MyServiceTest.php
```

It is possible to run the tests using different database systems and or PHP
versions. Before you run the tests with a different PHP version, do a
`composerUpdate` with the same version to ensure that composer has been run
with the correct PHP version.

```bash
Build/Scripts/runTests.sh -s composerUpdate -p 8.4
Build/Scripts/runTests.sh -s functional -p 8.4 -d postgres
```

## Acceptance tests {#acceptance-tests}

Acceptance testing in the TYPO3 world is about piloting (remote controlling) a
browser to click through a frontend generated by TYPO3 or clicking through
scenarios in the TYPO3 backend.

See also [Writing acceptance tests](https://docs.typo3.org/permalink/t3coreapi:testing-writing-acceptance@main)

## Organizing and storing the commands {#organizing-and-storing-the-commands}

There are different solutions to store and execute these commands as some are
quite long. For details see [Test runners: organize and execute tests](https://docs.typo3.org/permalink/t3coreapi:testing-organization@main).
