Easy to use architecture testing tool for PHP
๐
Introduction PHP Architecture Tester is a static analysis tool to verify architectural requirements.
It provides a natural language abstraction to define your own architectural rules and test them against your software. You can also integrate phpat easily into your toolchain.
There are four groups of supported assertions: Dependency, Inheritance, Composition and Mixin.
๐ฝ
Installation Just require phpat with Composer:
composer require --dev phpat/phpat
Manual download
If you have dependency conflicts, you can also download the latest PHAR file from Releases.
You will have to use it executing php phpat.phar phpat.yaml
and declare your tests in XML or YAML.
๐ง
Configuration You might want to setup a basic configuration:
# phpat.yaml
src:
path: src/
tests:
path: tests/architecture/
Complete list of options
Name | Description | Default |
---|---|---|
src path |
The root path of your application | no default |
src include |
Files you want to be tested excluding the rest | all files |
src exclude |
Files you want to be excluded in the tests | no files |
composer $ALIAS json |
Path of your composer.json file (multiple) | no files |
composer $ALIAS lock |
Path of your composer.lock file (multiple) | no files |
tests path |
The path where your tests are | no default |
options verbosity |
Output verbosity level (0/1/2) | 1 |
options dry-run |
Report failed suite without error exit code (T/F) | false |
options ignore_docblocks |
Ignore relations on docblocks (T/F) | false |
options ignore_php_extensions |
Ignore relations to core and extensions classes (T/F) | true |
๐
Test definition There are different Selectors to choose which classes will intervene in a rule and a wide range of Assertions.
This could be a test with a couple of rules:
<?php
use PhpAT\Rule\Rule;
use PhpAT\Selector\Selector;
use PhpAT\Test\ArchitectureTest;
use App\Domain\BlackMagicInterface;
class ExampleTest extends ArchitectureTest
{
public function testDomainDoesNotDependOnOtherLayers(): Rule
{
return $this->newRule
->classesThat(Selector::haveClassName('App\Domain\*'))
->excludingClassesThat(Selector::implementInterface(BlackMagicInterface::class))
->canOnlyDependOn()
->classesThat(Selector::havePath('Domain/*'))
->andClassesThat(Selector::haveClassName('App\Application\Shared\Service\KnownBadApproach'))
->build();
}
public function testAllHandlersExtendAbstractCommandHandler(): Rule
{
return $this->newRule
->classesThat(Selector::havePath('Application/*/UseCase/*Handler.php'))
->excludingClassesThat(Selector::extendClass('App\Application\Shared\UseCase\DifferentHandler'))
->andExcludingClassesThat(Selector::includeTrait('App\Legacy\LegacyTrait'))
->andExcludingClassesThat(Selector::haveClassName(\App\Application\Shared\UseCase\AbstractCommandHandler::class))
->mustExtend()
->classesThat(Selector::haveClassName('App\Application\Shared\UseCase\AbstractCommandHandler'))
->build();
}
}
YAML / XML test definition
You can also define tests whether in YAML or XML.
rules:
testAssertionsImplementAssertionInterface:
- classes:
- havePath: Rule/Assertion/*
- excluding:
- haveClassName: PhpAT\Rule\Assertion\*\MustNot*
- havePath: Rule/Assertion/MatchResult.php
- assert: mustExtend
- classes:
- haveClassName: PhpAT\Rule\Assertion\AbstractAssertion
<?xml version="1.0" encoding="UTF-8" ?>
<test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://raw.githubusercontent.com/carlosas/phpat/master/src/Test/Test.xsd">
<rule name="testAssertionsDoNotDependOnVendors">
<classes>
<selector type="havePath">Rule/Assertion/*</selector>
</classes>
<assert>canOnlyDependOn</assert>
<classes>
<selector type="haveClassName">PhpAT\*</selector>
<selector type="haveClassName">Psr\*</selector>
</classes>
</rule>
</test>
๐
Usage Run the bin with your configuration file:
vendor/bin/phpat phpat.yaml
1.0.0
version.
PHP Architecture Tester is in a very early stage, contributions are welcome. Please have a look to the Contribution docs.