Introduction to functional tests
Functional testing in TYPO3 world is basically the opposite of unit testing: Instead of looking at rather small, isolated pieces of code, functional testing looks at bigger scenarios with many involved dependencies. A typical scenario creates a full instance with some extensions, puts some rows into the database and calls an entry method, for instance a controller action. That method triggers dependent logic that changes data. The tests end with comparing the changed data or output is identical to some expected data.
This chapter goes into details on functional testing and how the typo3/testing-framework helps with setting up, running and verifying scenarios.
Overview
Functional testing is much about defining the specific scenario that should be set up by the system and isolating it from other scenarios. The basic thinking is that a single scenario that involves a set of loaded extensions, maybe some files and some database rows is a single test case (= one test file), and one or more single tests are executed using this scenario definition.
Single test cases extend \TYPO3\
.
The default implementation of method set
contains all the main magic to set
up a new TYPO3 instance in a sub folder of the existing system, create a database,
create config/
, load extensions, populate the database with tables
needed by the extensions and to link or copy additional fixture files around and finally
bootstrap a basic TYPO3 backend. set
is called before each test, so each single
test is isolated from other tests, even within one test case. There is only one optimization
step: The instance between single tests of one test case is not fully created from scratch,
but the existing instance is just cleaned up (all database tables truncated). This is a measure
to speed up execution, but still, the general thinking is that each test stands for its own
and should not have side effects on other tests.
The \TYPO3\
contains a series
of class properties. Most of them are designed to be overwritten by single test cases,
they tell set
what to do. For instance, there is a property to specify which
extensions should be active for the given scenario. Everyone looking or creating
functional tests should have a look at these properties: They are well documented and
contain examples how to use. These properties are the key to instruct typo3/
what to do.
The "external dependencies" like credentials for the database are submitted as environment
variables. If using the recommended docker based setup to execute tests, these details
are taken care off by the run
. See
the styleguide example for details on how this is
set up and used, and check out Test Runners: Organize and execute tests for details on test runners.
Executing the functional tests on different databases is handled by these
and it is possible to run one test on different databases by calling run
with the according options to do this. The above chapter Extension testing is about executing tests and setting up the runtime, while this
chapter is about writing tests and setting up the scenario.