Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Convention Laravel Package

testo/convention

Testo naming-convention plugin that discovers tests by file and class name patterns instead of explicit attributes. Ideal for adopting Testo in existing codebases with established conventions or integrating third-party suites without Testo attributes.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install Testo and the Convention Plugin:
    composer require --dev php-testo/testo testo/convention
    
  2. Configure Testo in testo.php (create if missing):
    return [
        'plugins' => [
            'testo/convention' => [
                'file_patterns' => ['*Test.php'],
                'class_patterns' => ['*Test', 'TestCase'],
                'method_patterns' => ['test*'],
            ],
        ],
    ];
    
  3. Run Tests via Testo CLI:
    vendor/bin/testo
    
    • Verify discovery by checking output for recognized test files/classes.

First Use Case

Migrate a PHPUnit Test Suite:

  • Rename TestCase classes to follow *Test convention (e.g., UserTest instead of UserTestCase).
  • Ensure test methods start with test (e.g., testUserCreation).
  • Run vendor/bin/testo—no annotations needed.

Implementation Patterns

Workflows

1. Convention-Based Discovery

  • File Patterns: Match test files (e.g., Feature/*Test.php, Unit/**/*Test.php).
    'file_patterns' => [
        'Feature/**/*Test.php',
        'Unit/**/*Spec.php',
    ],
    
  • Class Patterns: Match test class names (e.g., *Test, *Spec).
    'class_patterns' => ['*Test', '*Spec'],
    
  • Method Patterns: Match test methods (e.g., test*, it_*).
    'method_patterns' => ['test*', 'it_*'],
    

2. Hybrid Discovery

Combine conventions with explicit attributes (for gradual migration):

'testo/convention' => [
    'file_patterns' => ['*Test.php'],
    'fallback_to_attributes' => true, // Use @test attributes if conventions fail
],

3. Laravel Integration

Wrap Testo’s discovery in a Laravel TestResolver:

// app/Providers/TestoServiceProvider.php
public function boot()
{
    TestCase::macro('runTestoTests', function () {
        $testo = new \Testo\Testo();
        $testo->addPlugin(new \Testo\Convention\ConventionPlugin());
        return $testo->run();
    });
}

4. CI/CD Pipeline

Add Testo to composer.json scripts:

"scripts": {
    "test": "php artisan test && vendor/bin/testo",
    "test:testo": "vendor/bin/testo --filter=Feature"
}

Integration Tips

  • Exclude Paths: Avoid scanning vendor/ or node_modules/:
    'excluded_paths' => ['vendor/', 'node_modules/'],
    
  • Custom Assertions: Extend Testo’s assertions to match Laravel’s TestCase:
    use Testo\Assertions;
    Assertions::extend('seeInDatabase', function ($expected, $actual) {
        // Custom Laravel DB assertion logic
    });
    
  • Parallel Execution: Use testo run --parallel alongside PHPUnit/Pest.

Gotchas and Tips

Pitfalls

  1. False Positives/Negatives:

    • Issue: Non-test classes matching *Test (e.g., UserTestHelper).
    • Fix: Refine class_patterns or use method_patterns as a secondary filter.
    'method_patterns' => ['test*'], // Only methods starting with 'test' are tests
    
  2. Namespace Conflicts:

    • Issue: Testo discovers App\Tests\UserTest but Laravel’s autoloader can’t resolve it.
    • Fix: Ensure test files are in tests/ or app/Tests/ and autoloaded in composer.json:
      "autoload": {
          "psr-4": {
              "App\\Tests\\": "tests/"
          }
      }
      
  3. Performance Overhead:

    • Issue: Scanning large codebases slows down test discovery.
    • Fix: Limit file_patterns to test directories and cache results:
    'cache_discovery' => true, // Cache discovered tests for faster runs
    
  4. Testo Plugin API Changes:

    • Issue: Breaking changes in Testo’s plugin system (e.g., ConventionPlugin API shifts).
    • Fix: Pin Testo to a specific version in composer.json:
      "require-dev": {
          "php-testo/testo": "1.0.0",
          "testo/convention": "0.1.*"
      }
      
  5. IDE Support:

    • Issue: PHPStorm/VSCode doesn’t recognize Testo tests.
    • Fix: Use .idea/testRunConfigurations or vscode/settings.json to manually map Testo test files.

Debugging

  • Enable Verbose Output:

    vendor/bin/testo --verbose
    
    • Shows discovered files/classes and why they were included/excluded.
  • Dry Run:

    vendor/bin/testo --dry-run
    
    • Lists tests without executing them.
  • Log Discovery: Configure Testo’s logger in testo.php:

    'logging' => [
        'level' => 'debug',
        'output' => 'stderr',
    ],
    

Extension Points

  1. Custom Conventions: Extend the ConventionPlugin to add dynamic patterns:

    use Testo\Convention\ConventionPlugin;
    
    class CustomConventionPlugin extends ConventionPlugin
    {
        protected function getFilePatterns(): array
        {
            return array_merge(parent::getFilePatterns(), ['Custom/**/*Spec.php']);
        }
    }
    
  2. Pre/Post-Processing: Hook into Testo’s lifecycle to modify discovered tests:

    $testo->on('discovered', function ($tests) {
        // Filter or transform tests before execution
        return array_filter($tests, fn ($test) => str_contains($test->getName(), 'Feature'));
    });
    
  3. Laravel-Specific Extensions: Create a TestoTestCase that integrates with Laravel’s TestCase:

    use Illuminate\Foundation\Testing\TestCase as LaravelTestCase;
    use Testo\TestCase as TestoTestCase;
    
    class LaravelTestoTestCase extends LaravelTestCase
    {
        use TestoTestCase;
    
        protected function createApplication()
        {
            $app = require __DIR__.'/../../bootstrap/app.php';
            $app->make(Kernel::class)->bootstrap();
            return $app;
        }
    }
    

Configuration Quirks

  • Case Sensitivity: Patterns are case-sensitive by default. Use strtolower() in custom plugins for case-insensitive matching.
  • Globbing: Testo uses PHP’s glob() for pattern matching. Complex globs (e.g., {a,b}Test.php) may behave unexpectedly.
  • Priority: Conventions are checked before attributes. Set fallback_to_attributes: true to allow both.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
graham-campbell/flysystem
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
directorytree/opensearch-client
directorytree/opensearch-adapter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin