faissaloux/pest-plugin-inside
Pest plugin to run tests from inside your app’s context. Provides helpers to bootstrap Laravel or other frameworks for faster, cleaner integration-style tests without leaving Pest. Simple setup, lightweight, and aimed at improving developer ergonomics.
composer require --dev faissaloux/pest-plugin-inside
// tests/Feature/LowercaseKeysTest.php
use Faissaloux\PestPluginInside\Inside;
it('has lowercase keys in config file', function () {
expect('config/app.php')->toReturnLowercase();
});
expect('path/to/directory')->toReturnLowercase() to validate all files recursively.depth():
expect('stubs')->toReturnUnique(depth: 1);
Validate Laravel config files, service provider return arrays, or migration stubs:
// tests/Feature/ConfigValidationTest.php
it('enforces lowercase keys in app config', function () {
expect('config/app.php')->toReturnLowercase()->toReturnStrings();
});
Scan all PHP files in a directory (e.g., database/migrations) for consistent formatting:
it('validates all migration stubs', function () {
expect('database/migrations')->toReturnSingleWords()->forbidEmpty();
});
Chain multiple expectations for complex rules:
it('validates API response stubs', function () {
expect('stubs/responses')->toReturnLowercase()
->toBeOrdered()
->toReturnUnique();
});
Validate non-PHP files (e.g., .env.example, README.md snippets):
it('ensures README has no empty lines', function () {
expect('README.md')->forbidEmpty();
});
Combine with other Pest plugins (e.g., pest-plugin-laravel) to validate both file content and application behavior:
it('validates config and routes', function () {
expect('config/routes.php')->toReturnLowercase();
// ... other Laravel-specific tests
});
database/migrations:
it('ensures migration stubs use lowercase columns', function () {
expect('database/migrations/stubs')->toReturnLowercase();
});
AppServiceProvider:
it('validates AppServiceProvider bindings', function () {
expect('app/Providers/AppServiceProvider.php')->toReturnStrings();
});
it('ensures model constants are uppercase', function () {
expect('app/Models/User.php')->toReturnUppercase();
});
# .github/workflows/test.yml
jobs:
test:
steps:
- run: composer test
- run: composer test -- --filter "file content validation"
Investigator class to add project-specific validations (see Gotchas for extension points).File Path Resolution:
config/app.php) are resolved from the test file’s directory, not the project root.base_path():
expect(base_path('config/app.php'))->toReturnLowercase();
Windows Line Endings:
\r\n line endings.toReturnStrings() to normalize line breaks or preprocess files in tests.Nested Array Depth:
Case-Sensitive Filesystems:
toReturnLowercase() may pass unexpectedly.toReturnUnique() or add custom assertions.Performance:
app/) can slow down test suites.stubs/).Verbose Failures:
Failed asserting that 'config/app.php' returns lowercase values.
Found non-lowercase: 'CaSe' at line 5.
Isolate Tests:
it('debugs a single file', function () {
expect('config/app.php')->toReturnLowercase()->dump(); // Show raw content
});
Skip Non-Critical Files:
depth: 0 to exclude subdirectories temporarily:
expect('config')->toReturnLowercase(depth: 0);
Extend the plugin by creating a custom Investigator class:
// app/Extensions/CustomInvestigator.php
namespace App\Extensions;
use Faissaloux\PestPluginInside\Investigator;
class CustomInvestigator extends Investigator
{
public function toReturnNoDuplicates(): void
{
$this->assertNoDuplicates($this->getContent());
}
}
Register it in Pest.php:
uses(App\Extensions\CustomInvestigator::class)->in('tests');
Override the getContent() method to transform files before validation:
protected function getContent(): array
{
$content = parent::getContent();
return array_map('strtolower', $content); // Force lowercase for testing
}
Add support for new file types (e.g., .env):
// Override in custom Investigator
protected function isSupportedFile(string $path): bool
{
return parent::isSupportedFile($path) || str_ends_with($path, '.env');
}
Living Documentation: Use the plugin’s assertions as executable specs for file formats. Example:
// tests/Feature/StubFormatTest.php
it('documents expected stub format', function () {
// This test serves as both validation and documentation.
expect('stubs/mailables')->toReturnLowercase()
->toReturnSingleWords()
->toBeOrdered();
});
Dynamic Paths: Use Laravel’s helpers to generate dynamic paths:
expect(resource_path('views/emails/*.blade.php'))->toReturnLowercase();
Exclude Files: Skip specific files/directories by filtering paths:
it('validates all except vendor files', function () {
$files = glob('src/**/*.php');
foreach ($files as $file) {
if (str_contains($file, 'vendor')) continue;
expect($file)->toReturnStrings();
}
});
Combine with PHPStan: Use the plugin alongside PHPStan to catch both runtime and static analysis issues:
composer test && composer stan
How can I help you explore Laravel packages today?