The guide for developers contributing to AsyncUnit.
Thanks for taking an interest in contributing to AsyncUnit! Because this guide is for contributors to the library itself some assumptions are made about the audience of this document.
- You understand how to write tests for AsyncUnit and have those tests run on the command line.
The library is effectively split into two modules in a monolithic repository. The first module is the framework module; it can be found in the
framework_src/directory and includes everything in the
Cspray\Labrador\AsyncUnitnamespace. The second module is the cli module; it can be found in the
cli_src/directory and includes everything in the
Cspray\Labrador\AsyncUnitClinamespace. Each module also has a corresponding
cli_test/, respectively, where the test suite for each module is located. The test suites utilize PHPUnit to ensure that each module behaves as it is expected to.
This is, if it wasn't obvious, the most important module. It constitutes the bulk of the functionality; everything needed to analyze your tests, instantiate the appropriate objects, invoke the correct hooks, and emit events about the processing of those tests. By itself, however, the framework will only execute your test suite; it does not provide any output about what has happened and would be inconvenient to run. That requires a client that knows how to interact with the framework. The bundled CLI will likely be the first client you use to run tests.
The CLI is a client of the framework that knows how to run tests from the context of a terminal or console. It is likely going to the client you use most often to interact with the framework and is currently the only supported client available. This is a Symfony Console application that, at the moment, is minimal in nature and only allows running a set of tests specified in 1 or more directories. Future versions will increase the functionality of this feature.
From a high level the framework is split into two stages; a compilation phase and a runtime phase. The goal of the compilation phase is to parse the tests in the directories you have configured into a set of models that represent what code should actually be executed during runtime. The goal of the runtime phase is to instantiate TestSuites and TestCases, invoke appropriate hooks and tests, and emit events related to the execution of the actual test code based on the models that were output from the compilation phase.
The compilation phase is one of the first things that happens when you execute the CLI tool and should happen fairly early in any custom clients. Simply put, the library can't do much without the models that should be generated during this phase! The public API of the compilation phase is very simple; you should be utilizing a
Cspray\Labrador\AsyncUnit\Parser\Parserimplementation to initiate test compilation. By default the
Cspray\Labrador\AsyncUnit\Parser\StaticAnalysisParseris used. This implementation makes use of PHP-Parser to statically analyze tests for the appropriate information needed to run them.
StaticAnalysisParserdelegates the responsibility for the actual parsing to other objects, all of these objects live in the
Cspray\Labrador\AsyncUnit\Parsernamespace. The first is the
AsyncUnitModelNodeVisitor. It is responsible for interacting with the PHP-Parser API and converting the
Nodethat are generated into AsyncUnit models. The second is the
AsyncUnitModelCollector. The node visitor attaches all created models to this implementation. After all code has been traversed the collector can then ensure all the appropriate tests are associated to the appropriate test cases that are associated to the appropriate test suites. It also takes care of ensuring that some other things related to test suite and test case inheritance are taken care of. For example, if a
TestCaseare marked as disabled this implementation ensure that all the corresponding tests are also marked disabled.
The runtime phase is what happens after the Parser is done and is fully asynchronous. Where compilation's responsibilities are split between 2 classes the responsibility for the runtime phase lies solely with the
Cspray\Labrador\AsyncUnit\TestSuiteRunner. This class knows how to instantiate and invoke the correct tests and hooks based on the
ParserResultgenerated from the compilation phase. Based on the outcome of these test invocations a series of events will be emitted that informs you about what has happened. Please check out the "Events" Reference for more information.
At this point the CLI is a fairly simple Symfony Console project that determines which tests to parse, either from arguments to the
runcommand, or based on a configuration if using the default command. Ultimately the documentation for Symfony Console is outside the scope of this guide and understanding the CLI is ensuring you know how both the Console package and the AsyncUnit framework operate.