Test Suites
Organize TestCases and expose functionality for all of the associated TestCases in one place. A fundamental concept for integration testing capabilities provided by AsyncUnit!
A test suite is a way to organize TestCase
implementations together. A client interacting with the framework could then allow you to filter which tests get run by only running a specific test suite. However, a TestSuite
can be much more than that as it is a first-class citizen and a fundamental aspect of how the framework operates.
In our example we're going to assume the code under test has a heavy initialization cost or is not something that works well with the existing Amp PHPUnit wrapper. We're going to implement a TestSuite
that will instantiate just one of these Heavy
objects for all of the tests associated to it. Additionally, the TestSuite
will perform some operation before each test to ensure that the object is properly setup.
Defining a TestSuite
The first thing is define the TestSuite
.
For those familiar with unit testing it should be clear what's happening in the code above. Let's take a step-by-step look at what's happening.
The BeforeAll Hook
The "TestCase Hooks" article introduces the #[BeforeAll]
Attribute. In that scenario the Attribute was used on a TestCase
where this time it is declared on a TestSuite
. There's a couple things to note about this hook though; it isn't a static method and it is run before all associated TestCase
implementations are executed. A TestSuite
lives higher up the test hierarchy and therefore so does its hooks!
This hook also set some arbitrary data; in this case an instance of Heavy
, that we make use of later on. This use case, instantiating objects with a heavy initialization cost for later use, is the primary reason for the existence of the test suite functionality! A single TestSuite
object is created for all associated tests so that this type of state can be shared.
The BeforeEachTest Hook
This hook is not one covered in "TestCase Hooks"; because it is only available to the TestSuite
type. Since a TestSuite
lives higher up if we were to run BeforeEach
it would only execute one time for each TestCase
but this should run for each test. This hook allows doing just that. We simply get our previously created object and perform some operation on it.
The AfterEachTest Hook
This hook is the parallel to BeforeEachTest
and is run after each test is finished processing. This implementation simply frees up whatever resources were being used by Heavy
and ensures that at some point the object gets garbage collected.
Declaring a TestSuite
Now that a TestSuite
has been implemented the appropriate TestCase
need to be associated to it. There's currently 2 ways in which to do this. Making a TestSuite
the default or explicitly declaring on each TestCase
what suite it belongs to.
Making a TestSuite the default
This will cause every single TestCase
that does not explicitly declare a TestSuite
to be associated to the class being annotated. There can only be 1 default suite at a time. Simply use the DefaultTestSuite
Attribute.
Declare on each TestCase
It is also possible to explicitly state which TestSuite
a TestCase
belongs to. In this case put the annotation on the TestCase
and use the AttachToTestSuite
Attribute. For example...
There's currently a known limitation on the AttachToTestSuite
Attribute that requires you to define the TestSuite
using class constant notation. Defining your TestSuite
with a literal string is not currently supported. Future improvements to the static analyzer will remediate this problem.
There's always a TestSuite
It is important to realize that even if there is no explicit TestSuite
there is still an instance created and all of the TestCase
and tests are associated to it. If the parser can't find an explicit TestSuite
AsyncUnit will create an instance of ImplicitTestSuite
to use instead. This implementation performs no operations and has no hooks defined.
Understand the Hook lifecycle
Before you implement your own TestSuite
with custom hooks ensure the ramifications are well understood. With great power comes great responsiblity and implementing an explicit TestSuite
, while sometimes necessary, also brings an additional level of complexity. Make sure you've read over the Hooks reference!
Last updated