PHPackages                             jobmetric/package-tester-composer-plugin - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. jobmetric/package-tester-composer-plugin

ActiveComposer-plugin[Utility &amp; Helpers](/categories/utility)

jobmetric/package-tester-composer-plugin
========================================

Composer plugin for package tester to manage local package development workflow.

119PHP

Since Feb 12Pushed 3mo agoCompare

[ Source](https://github.com/jobmetric/package-tester-composer-plugin)[ Packagist](https://packagist.org/packages/jobmetric/package-tester-composer-plugin)[ RSS](/packages/jobmetric-package-tester-composer-plugin/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

[![Contributors](https://camo.githubusercontent.com/9bae2985be8362e67583b785d2e4a3afc06d8247bee9ff5af66fc7445be4ec4d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6e7472696275746f72732f6a6f626d65747269632f7061636b6167652d7465737465722d636f6d706f7365722d706c7567696e2e7376673f7374796c653d666f722d7468652d6261646765)](https://github.com/jobmetric/package-tester-composer-plugin/graphs/contributors)[![Forks](https://camo.githubusercontent.com/7e9cf094511f00e552371ee80446683008cafe5647ee1474609673160ec0e008/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f666f726b732f6a6f626d65747269632f7061636b6167652d7465737465722d636f6d706f7365722d706c7567696e2e7376673f7374796c653d666f722d7468652d6261646765266c6162656c3d466f726b)](https://github.com/jobmetric/package-tester-composer-plugin/network/members)[![Stargazers](https://camo.githubusercontent.com/9159d4858143afd64fd791228776fab51949d2f02f5e01977a0aa1c81f0b7947/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6a6f626d65747269632f7061636b6167652d7465737465722d636f6d706f7365722d706c7567696e2e7376673f7374796c653d666f722d7468652d6261646765)](https://github.com/jobmetric/package-tester-composer-plugin/stargazers)[![MIT License](https://camo.githubusercontent.com/7ec0d15cfb47f72e90946c1d1107370fc48f7e9f0b7cd860f84f58237523a90e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6a6f626d65747269632f7061636b6167652d7465737465722d636f6d706f7365722d706c7567696e2e7376673f7374796c653d666f722d7468652d6261646765)](https://github.com/jobmetric/package-tester-composer-plugin/blob/master/LICENCE.md)[![LinkedIn](https://camo.githubusercontent.com/eb590f47a3fca74584d18db8dd3e985ae3d786f50cd41b7530c3af3885da233c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d4c696e6b6564496e2d626c75652e7376673f7374796c653d666f722d7468652d6261646765266c6f676f3d6c696e6b6564696e26636f6c6f72423d353535)](https://linkedin.com/in/majidmohammadian)[![PHP Version](https://camo.githubusercontent.com/164bbc3cbc39e773c897eaeb2b2f830e9be69e41f29001a934aef004fcc1ff49/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d2533453d382e302e312d3737374242343f7374796c653d666f722d7468652d6261646765266c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://camo.githubusercontent.com/164bbc3cbc39e773c897eaeb2b2f830e9be69e41f29001a934aef004fcc1ff49/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d2533453d382e302e312d3737374242343f7374796c653d666f722d7468652d6261646765266c6f676f3d706870266c6f676f436f6c6f723d7768697465)[![Composer Plugin](https://camo.githubusercontent.com/64178e29cbc147e301452d1b76926dbb7ff739369bcf19c0cb646af97bc834b8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6d706f7365722d506c7567696e2d3838353633303f7374796c653d666f722d7468652d6261646765266c6f676f3d636f6d706f736572266c6f676f436f6c6f723d7768697465)](https://camo.githubusercontent.com/64178e29cbc147e301452d1b76926dbb7ff739369bcf19c0cb646af97bc834b8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6d706f7365722d506c7567696e2d3838353633303f7374796c653d666f722d7468652d6261646765266c6f676f3d636f6d706f736572266c6f676f436f6c6f723d7768697465)

Package Tester Composer Plugin
==============================

[](#package-tester-composer-plugin)

A powerful Composer plugin designed to manage local package development workflow by automatically discovering and registering test namespaces from packages into the root package's autoload-dev configuration.

📋 Table of Contents
-------------------

[](#-table-of-contents)

- [Overview](#overview)
- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
- [How It Works](#how-it-works)
- [Configuration](#configuration)
- [Architecture](#architecture)
- [Usage](#usage)
- [API Reference](#api-reference)
- [Contributing](#contributing)
- [License](#license)

Overview
--------

[](#overview)

`package-tester-composer-plugin` is a Composer plugin that streamlines the testing workflow for Laravel packages in a monorepo or multi-package development environment. It automatically discovers packages with test configurations and injects their PSR-4 autoload mappings into the root package, enabling seamless test execution across multiple packages.

### Why Use This Plugin?

[](#why-use-this-plugin)

When developing multiple packages locally, managing autoload configurations for tests can become tedious. This plugin automates the process by:

- Scanning your vendor directory for packages with `package-tester.json` configuration files
- Extracting test namespace mappings from each package's `composer.json`
- Injecting these mappings into the root package's `autoload-dev` configuration
- Persisting configuration for runtime command usage

Features
--------

[](#features)

- 🔍 **Automatic Package Discovery** - Scans vendor directory for packages with test configurations
- 📝 **PSR-4 Namespace Injection** - Automatically registers test namespaces in autoload-dev
- 🎯 **Smart Test Detection** - Auto-discovers test directories (Unit, Feature, Integration, etc.)
- 💾 **Configuration Persistence** - Saves discovered packages for runtime usage
- 🔧 **Flexible Configuration** - Supports both explicit and auto-discovered test paths
- 🧹 **Clean Uninstall** - Removes all persisted configurations when uninstalled
- 📦 **Laravel Integration** - Includes a Laravel service provider for easy integration

Requirements
------------

[](#requirements)

RequirementVersionPHP&gt;= 8.0.1Composer&gt;= 2.0composer/composer^2.9Installation
------------

[](#installation)

Install the plugin via Composer:

```
composer require jobmetric/package-tester-composer-plugin --dev
```

The plugin will automatically activate and start discovering packages on subsequent `composer install` or `composer update` commands.

How It Works
------------

[](#how-it-works)

### Plugin Lifecycle

[](#plugin-lifecycle)

```
┌─────────────────────────────────────────────────────┐
│                 Composer Event Flow                 │
├─────────────────────────────────────────────────────┤
│                                                     │
│  composer install/update                            │
│           │                                         │
│           ▼                                         │
│  ┌──────────────────┐                               │
│  │ Plugin Activated │                               │
│  └────────┬─────────┘                               │
│           │                                         │
│           ▼                                         │
│  ┌───────────────────────────────────────────────┐  │
│  │         PRE_AUTOLOAD_DUMP Event               │  │
│  │  ┌─────────────────────────────────────────┐  │  │
│  │  │ 1. Discover packages with tests         │  │  │
│  │  │ 2. Extract autoload-dev configurations  │  │  │
│  │  │ 3. Inject namespaces into root package  │  │  │
│  │  │ 4. Persist configuration to JSON file   │  │  │
│  │  └─────────────────────────────────────────┘  │  │
│  └───────────────────────────────────────────────┘  │
│           │                                         │
│           ▼                                         │
│  ┌─────────────────────┐                            │
│  │ Autoload files      │                            │
│  │ generated with      │                            │
│  │ injected namespaces │                            │
│  └─────────────────────┘                            │
│                                                     │
└─────────────────────────────────────────────────────┘

```

### Discovery Process

[](#discovery-process)

1. **Package Scanning**: The plugin scans the `vendor` directory for packages
2. **Configuration Check**: Each package is checked for a `package-tester.json` file
3. **Metadata Extraction**: Package information and autoload-dev mappings are extracted
4. **Namespace Injection**: Test namespaces are injected into the root package's autoload-dev
5. **Persistence**: Configuration is saved to `.package-tester/config.json` for runtime use

Configuration
-------------

[](#configuration)

### Package Configuration (package-tester.json)

[](#package-configuration-package-testerjson)

To enable test discovery for your package, create a `package-tester.json` file in your package root:

```
{
    "runner": {
        "enabled": true
    },
    "namespace": {
        "path": "tests",
        "option": [],
        "filter": null
    },
    "dependency-packages": []
}
```

#### Configuration Options

[](#configuration-options)

OptionTypeDescription`runner.enabled`booleanEnable/disable test runner for this package`namespace.path`stringPath to test directory (relative to package root)`namespace.option`arrayAdditional PHPUnit options`namespace.filter`string|nullFilter pattern for tests`dependency-packages`arrayList of dependent packages### Composer.json autoload-dev

[](#composerjson-autoload-dev)

The plugin reads the `autoload-dev` section from each package's `composer.json`:

```
{
    "autoload-dev": {
        "psr-4": {
            "YourPackage\\Tests\\": "tests/"
        }
    }
}
```

Architecture
------------

[](#architecture)

### Directory Structure

[](#directory-structure)

```
package-tester-composer-plugin/
├── src/
│   ├── Plugin.php                              # Main plugin class
│   ├── PackageTesterComposerPluginServiceProvider.php  # Laravel service provider
│   ├── Discoverers/
│   │   ├── Discoverer.php                      # Entry point for discovery
│   │   ├── PackageDiscoverer.php               # Scans vendor for packages
│   │   └── PackageAnalyzer.php                 # Analyzes individual packages
│   └── Extra/
│       └── ConfigExtra.php                     # Configuration persistence
├── composer.json
├── CONTRIBUTING.md
├── LICENCE.md
└── README.md

```

### Core Components

[](#core-components)

#### Plugin (`src/Plugin.php`)

[](#plugin-srcpluginphp)

The main plugin class that implements Composer's `PluginInterface` and `EventSubscriberInterface`. It:

- Activates/deactivates the plugin
- Subscribes to the `PRE_AUTOLOAD_DUMP` event
- Coordinates package discovery and namespace injection

#### Discoverer (`src/Discoverers/Discoverer.php`)

[](#discoverer-srcdiscoverersdiscovererphp)

Entry point for package discovery operations. Acts as a facade for `PackageDiscoverer`.

#### PackageDiscoverer (`src/Discoverers/PackageDiscoverer.php`)

[](#packagediscoverer-srcdiscovererspackagediscovererphp)

Scans the vendor directory and extracts test configurations from packages that have `package-tester.json` files.

**Key Methods:**

- `discover()` - Initiates the discovery process
- `getPackages()` - Returns all discovered packages
- `getPackage(string $name)` - Gets a specific package by name
- `hasPackage(string $name)` - Checks if a package exists
- `getTestPaths(string $name)` - Gets test paths for a package

#### PackageAnalyzer (`src/Discoverers/PackageAnalyzer.php`)

[](#packageanalyzer-srcdiscovererspackageanalyzerphp)

Analyzes individual packages to extract test configuration and metadata.

**Features:**

- Auto-discovers test directories (tests, test, Tests, Test)
- Finds test subdirectories (Unit, Feature, Integration, Functional, Api)
- Ignores fixture directories (Fixtures, Stubs, data, etc.)

#### ConfigExtra (`src/Extra/ConfigExtra.php`)

[](#configextra-srcextraconfigextraphp)

Manages runtime configuration persistence in `.package-tester/config.json`.

**Key Methods:**

- `save(array $packages)` - Persists package configuration
- `load()` - Loads persisted configuration
- `clear()` - Removes persisted configuration

Usage
-----

[](#usage)

### Basic Usage

[](#basic-usage)

Once installed, the plugin works automatically. Run composer commands as usual:

```
# Install dependencies and trigger package discovery
composer install

# Update dependencies and re-discover packages
composer update

# Regenerate autoload files with verbose output
composer dump-autoload -v
```

### Verbose Output

[](#verbose-output)

Use verbose flags to see detailed discovery information:

```
# Show registered namespaces
composer dump-autoload -v

# Show skipped namespaces
composer dump-autoload -vv

# Show warnings about missing directories
composer dump-autoload -vvv
```

### Example Output

[](#example-output)

```
Package Tester: Discovering and registering test namespaces...
  + YourPackage\Tests\ => vendor/yourvendor/yourpackage/tests/
  + AnotherPackage\Tests\ => vendor/yourvendor/anotherpackage/tests/
Package Tester: Registered 2 package(s) test namespaces.

```

### Laravel Integration

[](#laravel-integration)

The plugin includes a Laravel service provider that registers the `ConfigExtra` class as a singleton:

```
use JobMetric\PackageTesterComposerPlugin\Extra\ConfigExtra;

// Resolve from container
$configExtra = app(ConfigExtra::class);

// Load discovered packages
$packages = $configExtra->load();
```

API Reference
-------------

[](#api-reference)

### Plugin Class

[](#plugin-class)

```
namespace JobMetric\PackageTesterComposerPlugin;

class Plugin implements PluginInterface, EventSubscriberInterface
{
    // Activate the plugin
    public function activate(Composer $composer, IOInterface $io): void;

    // Deactivate the plugin
    public function deactivate(Composer $composer, IOInterface $io): void;

    // Uninstall the plugin (clears configuration)
    public function uninstall(Composer $composer, IOInterface $io): void;

    // Get subscribed events
    public static function getSubscribedEvents(): array;

    // Handle pre-autoload-dump event
    public function onPreAutoloadDump(Event $event): void;
}
```

### PackageDiscoverer Class

[](#packagediscoverer-class)

```
namespace JobMetric\PackageTesterComposerPlugin\Discoverers;

class PackageDiscoverer
{
    // Discover all packages with test configuration
    public function discover(): static;

    // Get all discovered packages
    public function getPackages(): array;

    // Get a specific package by name
    public function getPackage(string $packageName): ?array;

    // Check if a package exists
    public function hasPackage(string $packageName): bool;

    // Get the count of discovered packages
    public function count(): int;

    // Get test paths for a specific package
    public function getTestPaths(string $packageName): array;
}
```

### ConfigExtra Class

[](#configextra-class)

```
namespace JobMetric\PackageTesterComposerPlugin\Extra;

class ConfigExtra
{
    // Save package configuration
    public function save(array $packages): void;

    // Load persisted configuration
    public function load(): array;

    // Clear persisted configuration
    public function clear(): void;
}
```

### Persisted Configuration Structure

[](#persisted-configuration-structure)

The plugin persists discovered package configurations to `.package-tester/config.json`. This file contains only the `autoload_dev` mappings:

```
{
    "jobmetric/laravel-env-modifier": {
        "autoload_dev": {
            "JobMetric\\EnvModifier\\Tests\\": "tests/"
        }
    },
    "vendor/another-package": {
        "autoload_dev": {
            "Vendor\\AnotherPackage\\Tests\\": "tests/"
        }
    }
}
```

Troubleshooting
---------------

[](#troubleshooting)

### Common Issues

[](#common-issues)

**Package not discovered:**

- Ensure `package-tester.json` exists in the package root
- Check that `runner.enabled` is not set to `false`
- Verify the package is installed in the vendor directory

**Namespace not injected:**

- Check that the test directory exists
- Ensure `autoload-dev` is properly configured in `composer.json`
- Run `composer dump-autoload -v` to see verbose output

**Configuration not persisted:**

- Check write permissions for the project directory
- Ensure `.package-tester` directory can be created

Contributing
------------

[](#contributing)

Thank you for considering contributing to Package Tester Composer Plugin! Please read our [Contributing Guide](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.

### Development Setup

[](#development-setup)

```
# Clone the repository
git clone https://github.com/jobmetric/package-tester-composer-plugin.git

# Install dependencies
composer install

# Run tests
composer test
```

License
-------

[](#license)

The Package Tester Composer Plugin is open-sourced software licensed under the [MIT license](LICENCE.md).

Authors
-------

[](#authors)

- **Majid Mohammadian** - *Full Stack Developer* - [LinkedIn](https://www.linkedin.com/in/majidmohammadian/)
- **Matin Bagheri** - *PHP Developer* - [LinkedIn](https://www.linkedin.com/in/bagherimatin/)

Support
-------

[](#support)

- 📧 Email:
- 🐛 Issues: [GitHub Issues](https://github.com/jobmetric/package-tester-composer-plugin/issues)
- 📚 Documentation:

###  Health Score

22

—

LowBetter than 22% of packages

Maintenance55

Moderate activity, may be stable

Popularity10

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity12

Early-stage or recently created project

 Bus Factor1

Top contributor holds 69.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/b00d08bd4b0b765ee2d33719a535e6cb49c04fb945078a0809d5c05e6f16ee96?d=identicon)[majidmohammadian](/maintainers/majidmohammadian)

---

Top Contributors

[![MajidMohammadian](https://avatars.githubusercontent.com/u/2099965?v=4)](https://github.com/MajidMohammadian "MajidMohammadian (9 commits)")[![Bagheri-Matin](https://avatars.githubusercontent.com/u/239607447?v=4)](https://github.com/Bagheri-Matin "Bagheri-Matin (4 commits)")

### Embed Badge

![Health badge](/badges/jobmetric-package-tester-composer-plugin/health.svg)

```
[![Health](https://phpackages.com/badges/jobmetric-package-tester-composer-plugin/health.svg)](https://phpackages.com/packages/jobmetric-package-tester-composer-plugin)
```

###  Alternatives

[phpsagas/orchestrator

Main component controls and coordinates saga participants

3228.0k1](/packages/phpsagas-orchestrator)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
