orchestra/testbench-browser-kit
Adds Laravel BrowserKit testing to Orchestra Testbench for package development. Swap your base test case to Orchestra\Testbench\BrowserKit\TestCase to use fluent visit/see/form APIs in functional tests across supported Laravel versions.
composer require --dev "orchestra/testbench-browser-kit"
Orchestra\Testbench\TestCase with Orchestra\Testbench\BrowserKit\TestCase in your test base class:
use Orchestra\Testbench\BrowserKit\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
public $baseUrl = 'http://localhost';
}
public function testHomepageLoads()
{
$this->visit('/')
->see('Welcome');
}
DatabaseTransactions, WithoutMiddleware).Route Testing:
Use visit() or visitRoute() for GET requests:
$this->visitRoute('profile.show', ['user' => 1]);
Form Interaction: Chain methods for form submission:
$this->visit('/register')
->type('John', 'name')
->check('terms')
->press('Submit')
->seePageIs('/dashboard');
API Testing:
Use json() for HTTP verbs:
$this->json('POST', '/api/users', ['name' => 'Alice'])
->seeJson(['success' => true]);
Authentication:
Authenticate users with actingAs():
$user = create('App\Models\User');
$this->actingAs($user)->visit('/dashboard');
Middleware Isolation: Disable middleware for specific tests:
$this->withoutMiddleware()->visit('/admin');
Testbench to load your package in isolation:
protected function getPackageProviders($app)
{
return ['YourPackage\\ServiceProvider'];
}
TestCase for reusable assertions:
protected function assertPackageFeatureExists()
{
$this->visit('/package-feature')->see('Expected Text');
}
$this->withSession(['preloaded' => 'data'])->visit('/');
Base URL Mismatch:
$baseUrl (e.g., http://localhost vs. https://example.test).$baseUrl in your TestCase or override it per test:
$this->baseUrl = 'https://example.test';
Middleware Leaks:
withoutMiddleware() can cause tests to fail if middleware (e.g., auth) isn’t mocked.WithoutMiddleware trait or withoutMiddleware() in tests.Session Persistence:
withSession() before the first request in a chain.Route Caching:
setUp():
public function setUp(): void
{
parent::setUp();
$this->app['router']->refreshRoutes();
}
dump() or dd() on the response object:
$response = $this->call('GET', '/');
dd($response->getContent());
$this->withoutMiddleware()->visit('/')->assertResponseOk();
getPackageProviders() and getEnvironmentSetUp() are correctly defined to avoid conflicts with the host app.Custom Assertions:
Extend TestCase to add domain-specific assertions:
public function assertPackageConfigLoaded()
{
$this->assertEquals('expected', config('package.key'));
}
Hooks for Setup/Teardown:
Override setUp()/tearDown() for shared test logic:
protected function setUp(): void
{
parent::setUp();
$this->artisan('package:publish-config');
}
Mocking Dependencies:
Use Laravel’s mocking tools (e.g., Mockery) within tests:
$mock = Mockery::mock('alias:YourPackage');
$this->app->instance('YourPackage', $mock);
Parallel Testing:
Leverage PHPUnit’s --parallel flag for faster test suites, but ensure tests are stateless (e.g., avoid shared DB state).
How can I help you explore Laravel packages today?