Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ta-tikoma/phpunit-architecture-test

PHPUnit Application Architecture Test. For architecture tests
https://github.com/ta-tikoma/phpunit-architecture-test

architecture php phpunit test

Last synced: 7 days ago
JSON representation

PHPUnit Application Architecture Test. For architecture tests

Awesome Lists containing this project

README

        

# PHPUnit Application Architecture Test

**Idea**: write architecture tests as well as feature and unit tests. Protect your architecture code style!

## Example

Don't use repositories in controllers use only in services classes. Take three layers "repositories", "services", "controllers" and add asserts on dependencies.
```php
$controllers = $this->layer()->leaveByNameStart('App\\Controllers');
$services = $this->layer()->leaveByNameStart('App\\Services');
$repositories = $this->layer()->leaveByNameStart('App\\Repositories');

$this->assertDoesNotDependOn($controllers, $repositories);
$this->assertDependOn($controllers, $services);
$this->assertDependOn($services, $repositories);
```

## Installation

#### Install via composer

```bash
composer require --dev ta-tikoma/phpunit-architecture-test
```

#### Add trait to Test class

```php
abstract class TestCase extends BaseTestCase
{
use ArchitectureAsserts;
}
```

## Use

- Create test
- Make layers of application
- Add asserts

```php
public function test_make_layer_from_namespace()
{
$app = $this->layer()->leaveByNameStart('PHPUnit\\Architecture');
$tests = $this->layer()->leaveByNameStart('tests');

$this->assertDoesNotDependOn($app, $tests);
$this->assertDependOn($tests, $app);
}

```

#### Run
```bash
./vendor/bin/phpunit
```

## Test files structure

- tests
- Architecture
- SomeTest.php
- Feature
- Unit

## How to build Layer

- `$this->layer()` take access to layer with all objects and filter for create your layer:
- leave objects in layer only:
- `->leave($closure)` by closure
- `->leaveByPathStart($path)` by object path start
- `->leaveByNameStart($name)` by object name start
- `->leaveByNameRegex($name)` by object name regex
- `->leaveByType($name)` by object type
- remove objects from layer:
- `->exclude($closure)` by closure
- `->excludeByPathStart($path)` by object path start
- `->excludeByNameStart($name)` by object name start
- `->excludeByNameRegex($name)` by object name regex
- `->excludeByType($name)` by object type
- you can create multiple layers with split:
- `->split($closure)` by closure
- `->splitByNameRegex($closure)` by object name

## Asserts

### Dependencies

**Example:** Controllers don't use Repositories only via Services

- `assertDependOn($A, $B)` Layer A must contains dependencies by layer B.
- `assertDoesNotDependOn($A, $B)` Layer A (or layers in array A) must not contains dependencies by layer B (or layers in array B).

### Methods

- `assertIncomingsFrom($A, $B)` Layer A must contains arguments with types from Layer B
- `assertIncomingsNotFrom($A, $B)` Layer A must not contains arguments with types from Layer B
- `assertOutgoingFrom($A, $B)` Layer A must contains methods return types from Layer B
- `assertOutgoingNotFrom($A, $B)` Layer A must not contains methods return types from Layer B
- `assertMethodSizeLessThan($A, $SIZE)` Layer A must not contains methods with size less than SIZE

### Properties

- `assertHasNotPublicProperties($A)` Objects in Layer A must not contains public properties

### Essence

You can use `$layer->essence($path)` method for collect data from layer. For example get visibility of all properties in layer: `$visibilities = $layer->essence('properties.*.visibility');` .

- `assertEach($list, $check, $message)` - each item of list must passed tested by $check-function
- `assertNotOne($list, $check, $message)` - not one item of list must not passed tested by $check-function
- `assertAny($list, $check, $message)` - one or more item of list must not passed tested by $check-function

## Alternatives
- [Deptrac](https://github.com/qossmic/deptrac)
- [PHP Architecture Tester](https://github.com/carlosas/phpat)
- [PHPArch](https://github.com/j6s/phparch)
- [Arkitect](https://github.com/phparkitect/arkitect)

#### Advantages
- Dynamic creation of layers by regular expression (not need declare each module)
- Run along with the rest of tests from [phpunit](https://github.com/sebastianbergmann/phpunit)
- Asserts to method arguments and return types (for check dependent injection)
- Asserts to properties visibility