Weave 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

Testing Laravel Package

orchestra/testing

Testing utilities for Orchestra Platform and Laravel packages, providing test case helpers, package bootstrapping, and assertions that simplify unit and integration testing for extensions and applications built on PHP.

View on GitHub
Deep Wiki
Context7

Getting Started

orchestra/testing is a dev-only test harness for Orchestra Platform extensions. Day to day, its leverage is narrow but concrete: it gives you a base TestCase that boots an Orchestra-aware application, registers your extension's service provider, and lets you assert providers, routes, config, and migrations are wired the way a real Orchestra install wires them. If your app is not on Orchestra, stop here — use native Laravel testing plus orchestra/testbench and a small internal base TestCase.

Minimal setup:

composer require --dev orchestra/testing

Pin it against the rest of the platform line. The only listed release note (v5.0.0) targets Laravel 7, so treat version compatibility as an open question, not an assumption:

"require-dev": {
    "orchestra/testing": "^5.0",
    "orchestra/testbench": "^5.0"
}

Run composer why-not orchestra/testing on a throwaway branch first and confirm PHP, Laravel, PHPUnit, Testbench, and your Orchestra Platform major all agree. Mismatched pins surface later as confusing container/bootstrap failures, not as clear errors.

Where to look first:

  • vendor/orchestra/testing/src/ — the base TestCase, its traits/concerns, and assertion helpers. This is your real API reference; published docs are thin.
  • vendor/orchestra/testing/tests/ — the package's own test suite is the most reliable documentation.
  • Your extension's service provider and extension.json manifest — most failures trace back to provider registration or stale manifest metadata, not the harness itself.

Create a project-level base test case instead of extending the package class in every test:

namespace Vendor\Extension\Tests;

use Orchestra\Testing\TestCase as OrchestraTestCase;

abstract class TestCase extends OrchestraTestCase
{
    protected function getPackageProviders($app)
    {
        return [\Vendor\Extension\ExtensionServiceProvider::class];
    }

    protected function getEnvironmentSetUp($app)
    {
        $app['config']->set('database.default', 'testing');
        $app['config']->set('database.connections.testing', [
            'driver'   => 'sqlite',
            'database' => ':memory:',
            'prefix'   => '',
        ]);
    }
}

First useful test — prove the provider loads and a route resolves:

class ExtensionBootTest extends TestCase
{
    /** @test */
    public function it_registers_the_provider_and_resolves_a_route()
    {
        $this->assertArrayHasKey(
            \Vendor\Extension\ExtensionServiceProvider::class,
            $this->app->getLoadedProviders()
        );

        $this->get('/extension/dashboard')->assertOk();
    }
}

Run it narrowly while orienting:

./vendor/bin/phpunit --filter=ExtensionBootTest

That single test touches bootstrap, provider registration, routing, and config in one place — it is the whole spike.

Implementation Patterns

One base test case, everything inherits it. Centralize the package base class, required traits, database configuration, and migration loading in tests/TestCase.php. Sprinkling package traits across individual test classes produces inconsistent lifecycle behaviour and failures that look random because each file boots slightly differently.

Assert the boot contract, not the helper. The helpers exist to get you an Orchestra-shaped application; your assertions should be about your extension:

public function test_extension_manifest_and_routes_are_wired()
{
    $this->assertArrayHasKey(ExtensionServiceProvider::class, $this->app->getLoadedProviders());
    $this->assertTrue($this->app->bound('extension.dashboard'));
    $this->assertNotNull(config('extension.name'));
}

Snapshot the route table instead of one assertion per route. For controller-heavy extensions, asserting the registered route names/URIs in one test catches accidental route removal during refactors far more cheaply than a get() assertion per endpoint.

Drive migrations the way production does. If your extension ships migrations via the Orchestra manifest, let the harness run them rather than calling loadMigrationsFrom() inside each test. Testing the migration path is half the point; a test that bypasses the manifest passes while a real install breaks.

Assert resolved facades by class, not by name. Facade-name assertions break quietly on aliasing changes:

$this->assertInstanceOf(Dashboard::class, $this->app->make('extension.dashboard'));

Isolate to require-dev and to selected test classes. Do not rewire phpunit.xml's global bootstrap for the whole repo. Point only your Orchestra extension suites at the Orchestra-aware base case and leave plain-Laravel tests on native tooling. That keeps removal cost at zero.

Convert incrementally and measure. On a branch, convert one boot test, one route test, and one migration test. Diff the boilerplate (lines removed, CI wall-clock delta, tests that no longer express cleanly). Only then convert the rest — never rewrite the suite in one pass.

Pin the trio and bump them together. orchestra/testing, orchestra/testbench, and the Orchestra Platform version are effectively one unit. A CI matrix with one job per supported Laravel major is the only reliable way to catch PHPUnit API and bootstrap drift before a red Friday-afternoon build.

Gotchas and Tips

Treat the version signal as a red flag, not a detail. Score 0.3, no stars, zero dependents, and a v5.0.0 whose only listed change is "support for Laravel Framework v7." There is no public evidence of modern Laravel/PHPUnit support. Validate the full matrix on a disposable branch before it touches shared CI.

Thin docs are the real onboarding cost. Plan on source reading and mirroring the package's own tests/. Write a short internal note on when to use these helpers versus Testbench + native Laravel; otherwise new team members guess, and their guesses look like flaky tests.

Stale manifest cache is the classic failure. After editing extension.json, tests can boot with the previous manifest and fail incomprehensibly. Clear the manifest/cache between runs or force a fresh bootstrap in the base case. When a test passes alone but fails in suite, check this first.

Watch for global state leaking between tests. A Testbench-derived harness boots and tears down a container per test; anything registered globally (singletons resolved too early, static caches, real filesystem writes outside the test skeleton) bleeds across tests. Order-dependent failures usually mean a leaked binding, not a package bug.

Debug boot failures by bisecting the base case. Strip getEnvironmentSetUp() to nothing, confirm the base case boots, then re-add config, providers, and migrations one at a time. Orchestra bootstrap errors describe the symptom (a missing binding) far from the cause (a provider that never registered).

Never let it gate feature delivery. It is dev-only with no production runtime exposure and effectively no upstream support. If a Composer conflict or PHPUnit upgrade breaks the harness, pin, vendor, or fork with a named owner and an exit plan — do not block a release.

Keep the fallback executable. Removal should be one line: swap the base class for Testbench's TestCase (or a small internal base case) and delete the dependency. If you have customized so heavily that this is hard, you have rebuilt the package and should own it deliberately.

Don't ship it as an org standard. Its blast radius is Orchestra-shaped extensions. Introducing it into plain-Laravel services "for consistency" buys an unmaintained dependency and an unproven harness in exchange for nothing.

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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo