volt-test / laravel-performance-testing
A Laravel package for performance testing with VoltTest
Requires
- php: ^8.2
- illuminate/support: ^10.0|^11.0|^12.0
- volt-test/php-sdk: ^1.0.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.14
- orchestra/testbench: ^10.0
- phpstan/phpstan: ^1.10
- phpstan/phpstan-deprecation-rules: ^1.1
- phpunit/phpunit: ^11.5.3
This package is auto-updated.
Last update: 2025-07-06 22:49:00 UTC
README
A Laravel package for performance testing with the VoltTest PHP SDK. Easily create and run load tests for your Laravel applications with built-in route discovery, CSRF handling, and comprehensive reporting.
This package is built on top of the VoltTest PHP SDK and provides a seamless Laravel integration layer with additional Laravel-specific features like automatic route discovery, CSRF token handling, and Artisan commands.
For more information about the core VoltTest functionality, visit php.volt-test.com.
Table of Contents
- About Laravel Performance Testing VoltTest
- Requirements
- Features
- Installation
- Configuration
- Quick Start
- Creating Tests
- API Testing
- CSV Data Sources
- Available Methods
- Running Tests
- Reports
- Advanced Configuration
- Testing Tips
- Troubleshooting
- Learn More
About Laravel Performance Testing VoltTest
This Laravel package extends the VoltTest PHP SDK with Laravel-specific functionality. While the core VoltTest PHP SDK provides the foundation for performance testing, this package adds:
- Laravel Integration - Service provider, facades, and configuration
- Artisan Commands - CLI commands for test creation and execution
- Route Discovery - Automatic Laravel route detection and test generation
- Laravel Scenarios - Enhanced scenario class with Laravel-specific methods
For comprehensive documentation about VoltTest core features, load testing concepts, and advanced configuration options, please visit php.volt-test.com.
Requirements
- PHP 8.2+
- VoltTest PHP SDK 1.1.0+
Features
- 🚀 Easy Laravel Integration - Seamlessly integrates with Laravel applications
- 🔍 Automatic Route Discovery - Discover and test your application routes automatically
- 📊 Comprehensive Reporting - Detailed performance reports with metrics
- 🎯 URL Load Testing - Direct URL testing without creating test classes
- ⚡ Artisan Commands - Convenient CLI commands for test creation and execution
- 🔧 Configurable - Flexible configuration options for different environments
- 📄 CSV Data Sources - Load dynamic test data from CSV files for realistic performance testing
Installation
You can install the package via Composer:
composer require volt-test/laravel-performance-testing --dev
The package will automatically register its service provider.
Publish the configuration file:
php artisan vendor:publish --tag=volttest-config
Configuration
The configuration file config/volttest.php
contains all the settings for your performance tests:
return [ // Test Configuration 'name' => env('VOLTTEST_NAME', 'Laravel Application Test'), 'description' => env('VOLTTEST_DESCRIPTION', 'Performance test for Laravel application'), // Load Configuration 'virtual_users' => env('VOLTTEST_VIRTUAL_USERS', 10), 'duration' => env('VOLTTEST_DURATION'), // e.g., '1m', '30s', '2h' 'ramp_up' => env('VOLTTEST_RAMP_UP', null), // Debug Configuration 'http_debug' => env('VOLTTEST_HTTP_DEBUG', false), // Test Paths 'test_paths' => app_path('VoltTests'), // Reports 'reports_path' => storage_path('volttest/reports'), 'save_reports' => env('VOLTTEST_SAVE_REPORTS', true), // Base URL 'use_base_url' => env('VOLTTEST_USE_BASE_URL', true), 'base_url' => env('VOLTTEST_BASE_URL', 'http://localhost:8000'), // CSV Data Source Configuration 'csv_data' => [ 'path' => storage_path('volttest/data'), // Default CSV location 'validate_files' => true, // Check file exists before run 'default_distribution' => 'unique', // Default distribution mode 'default_headers' => true, // Default header setting ], ];
Quick Start
1. Create Your First Test
Generate a new performance test with route discovery:
php artisan volttest:make UserTest --routes --select
This creates a test class at app/VoltTests/UserTest.php
:
<?php namespace App\VoltTests; use VoltTest\Laravel\Contracts\VoltTestCase; use VoltTest\Laravel\VoltTestManager; class UserTest implements VoltTestCase { public function define(VoltTestManager $manager): void { $scenario = $manager->scenario('UserTest'); // Step 1: Home Page $scenario->step('Home Page') ->get('/') ->expectStatus(200); // Step 2: Get Registration Page to extract CSRF token $scenario->step('Get Registration Page') ->get('/register') ->expectStatus(200) ->extractCsrfToken('csrf_token'); // Extract CSRF token for registration // Step 2: User Registration $scenario->step('User Registration') ->post('/register', [ '_token' => '${csrf_token}', 'name' => 'John Doe', 'email' => 'john@example.com', 'password' => 'password', 'password_confirmation' => 'password', ]) ->header('Content-Type', 'application/x-www-form-urlencoded') ->expectStatus(201); } }
2. Run Your Test
Execute the performance test:
php artisan volttest:run UserTest
Or run all tests:
php artisan volttest:run
3. Direct URL Testing
Test any URL directly without creating a test class:
# Simple GET request php artisan volttest:run https://example.com --users=10 --duration=1m # POST request with data php artisan volttest:run https://api.example.com/users \ --method=POST \ --headers='{"Authorization":"Bearer token"}' \ --body='{"name":"John","email":"john@example.com"}' \ --content-type="application/json" \ --code-status=201
Creating Tests
Using Route Discovery
Generate tests with automatic route discovery:
# Include all routes php artisan volttest:make ApiTest --routes # Filter by pattern php artisan volttest:make ApiTest --routes --filter="api/*" # Filter by HTTP method php artisan volttest:make ApiTest --routes --method=GET # Include only authenticated routes php artisan volttest:make ApiTest --routes --auth # Interactive route selection php artisan volttest:make ApiTest --routes --select --filter="api/*"
Manual Test Creation
Create a test class manually:
<?php namespace App\VoltTests; use VoltTest\Laravel\Contracts\VoltTestCase; use VoltTest\Laravel\VoltTestManager; class CheckoutTest implements VoltTestCase { public function define(VoltTestManager $manager): void { $scenario = $manager->scenario('E-commerce Checkout Flow'); // Browse products $scenario->step('Browse Products') ->get('/products') ->expectStatus(200) ->extractHtml('product_id', '.product:first-child', 'data-id'); // To know how to extract the product ID, you can use a CSS selector that matches the first product element. // Reference: https://php.volt-test.com/docs/Steps#html-response // Add to cart $scenario->step('Add to Cart') ->post('/cart/add', [ '_token' => '${csrf_token}', 'product_id' => '${product_id}', 'quantity' => 1, ]) ->expectStatus(200) ->thinkTime('2s'); // Checkout $scenario->step('Checkout') ->get('/checkout') ->expectStatus(200) ->extractCsrfToken('checkout_token'); // Complete order $scenario->step('Complete Order') ->post('/checkout/complete', [ '_token' => '${checkout_token}', 'payment_method' => 'credit_card', 'shipping_address' => 'Test Address', ]) ->expectStatus(302); // Redirect after successful order } }
API Testing
Create API-focused tests:
<?php namespace App\VoltTests; use VoltTest\Laravel\Contracts\VoltTestCase; use VoltTest\Laravel\VoltTestManager; class ApiTest implements VoltTestCase { public function define(VoltTestManager $manager): void { $scenario = $manager->scenario('API Performance Test'); // Login to get token $scenario->step('API Login') ->post('/api/login', [ 'email' => 'test@example.com', 'password' => 'password', ]) ->header('Accept', 'application/json') ->expectStatus(200) ->extractJson('auth_token', 'meta.token'); // Extract the authentication token from the response // Reference: https://php.volt-test.com/docs/Steps#json-response // Get user data $scenario->step('Get User Data') ->get('/api/user') ->header('Authorization', 'Bearer ${auth_token}') ->header('Accept', 'application/json') ->expectStatus(200) ->extractJson('user_id', 'data.id'); // Update user $scenario->step('Update User') ->put('/api/user/${user_id}', [ 'name' => 'Updated Name', 'email' => 'updated@example.com', ]) ->header('Authorization', 'Bearer ${auth_token}') ->header('Content-Type', 'application/json') ->expectStatus(200); } }
Available Methods
Scenario Methods
// HTTP Methods $scenario->step('Step Name') ->get('/path') ->post('/path', $data) ->put('/path', $data) ->patch('/path', $data) ->delete('/path');
Headers Data
// Headers $scenario->step('Step Name') ->header('Authorization', 'Bearer token') ->header('Accept', 'application/json');
Assertions
// Expectations $scenario->step('Step Name') ->expectStatus(200) ->expectStatus(201, 'custom_validation_name');
Extracting Data
// Data Extraction $scenario->step('Step Name') ->extractJson('variable_name', 'path.to.value') // Reference: https://php.volt-test.com/docs/Steps#json-response ->extractHeader('variable_name', 'Header-Name') // Reference: https://php.volt-test.com/docs/Steps#header-response ->extractHtml('variable_name', 'css-selector', 'attribute') // Reference: https://php.volt-test.com/docs/Steps#html-response ->extractRegex('variable_name', '/pattern/') // Reference: https://php.volt-test.com/docs/Steps#regular-expressions ->extractCsrfToken('csrf_token'); // Laravel-specific CSRF token extraction or u can use `extractHtml` with the CSRF token input field // Think Time $scenario->step('Step Name') ->thinkTime('2s'); // Pause between requests
Running Tests
Command Syntax
php artisan volttest:run [test] [options]
Arguments
test
(optional) - The test class to run OR URL to test
Available Options
Option | Description | Example |
---|---|---|
--path= |
Path to search for test classes | --path=tests/Performance |
--debug |
Enable HTTP debugging | --debug |
--users= |
Number of virtual users (default: 10) | --users=50 |
--duration= |
Test duration (optional) | --duration=2m |
--stream |
Stream test output to console | --stream |
--url |
Treat the test argument as a URL for direct load testing | --url |
--method= |
HTTP method for URL testing (default: GET) | --method=POST |
--headers= |
JSON string of headers for URL testing | --headers='{"Authorization":"Bearer token"}' |
--body= |
Request body for URL testing (for POST/PUT) | --body='{"name":"John"}' |
--content-type= |
Content type for URL testing | --content-type=application/json |
--code-status= |
Expected HTTP status code for URL testing (default: 200) | --code-status=201 |
--scenario-name= |
Custom scenario name for URL testing | --scenario-name="API Load Test" |
Basic Execution
# Run all tests php artisan volttest:run # Run specific test php artisan volttest:run UserTest # Run with custom configuration php artisan volttest:run --users=20 --duration=2m --debug # Stream output in real-time php artisan volttest:run --stream
Duration Formats
The --duration
option accepts various time formats:
30s
- 30 seconds5m
- 5 minutes2h
- 2 hours90s
- 90 seconds (1.5 minutes)
Header Formats
The --headers
option accepts JSON format:
# Single header --headers='{"Authorization":"Bearer token"}' # Multiple headers --headers='{"Authorization":"Bearer token","Accept":"application/json","X-Custom":"value"}' # Complex headers with special characters --headers='{"User-Agent":"VoltTest/1.0","Content-Type":"application/json; charset=utf-8"}'
Body Formats
The --body
option supports different formats depending on content type:
# JSON body (use with --content-type=application/json) --body='{"name":"John","email":"john@example.com","age":30}' # Form data (use with --content-type=application/x-www-form-urlencoded) --body="name=John&email=john@example.com&age=30" # Plain text --body="This is plain text content" # XML (use with --content-type=application/xml) --body='<?xml version="1.0"?><user><name>John</name><email>john@example.com</email></user>'
Advanced Options
# Custom test path php artisan volttest:run --path=tests/Performance # Multiple configuration options php artisan volttest:run UserTest \ --users=50 \ --duration=5m \ --debug \ --stream
Reports
Console Output
Test results are displayed in the console with metrics including:
- Duration and total requests
- Success rate and requests per second
- Response time statistics (min, max, avg, median, P95, P99)
Saved Reports
Reports are automatically saved as JSON files in storage/volttest/reports/
:
{ "timestamp": "2025-06-23 21:22:39", "metadata": { "generator": "VoltTest Laravel Package" }, "summary": { "duration": "5.521942656s", "total_requests": 100, "success_rate": 48, "requests_per_second": 18.11, "success_requests": 48, "failed_requests": 52 }, "response_times": { "min": "22.361918ms", "max": "2.061161165s", "avg": "343.184136ms", "median": "106.130464ms", "p95": "1.592337048s", "p99": "1.84969821s" }, "metrics": { "duration": "5.521942656s", "totalRequests": 100, "successRate": 48, "requestsPerSecond": 18.11, "successRequests": 48, "failedRequests": 52, "responseTime": { "min": "22.361918ms", "max": "2.061161165s", "avg": "343.184136ms", "median": "106.130464ms", "p95": "1.592337048s", "p99": "1.84969821s" } } }
CSV Data Sources
Load dynamic test data from CSV files for more realistic and scalable performance testing scenarios.
Quick Example
- Create a CSV file at
storage/volttest/data/users.csv
:
name,email,password
John Doe,user1@example.com,password123
Jane Smith,user2@example.com,password456
Bob Wilson,user3@example.com,password789
- Use the data in your test:
<?php namespace App\VoltTests; use VoltTest\Laravel\Contracts\VoltTestCase; use VoltTest\Laravel\VoltTestManager; class RegisterTest implements VoltTestCase { public function define(VoltTestManager $manager): void { // Configure CSV data source $scenario = $manager->scenario('RegisterTest') ->dataSource('users.csv'); // Step 1: Get Register Page $scenario->step('Register') ->get('/register') ->header('Content-Type', 'application/x-www-form-urlencoded') ->extractCsrfToken('token') ->expectStatus(200); // Step 2: Submit Registration $scenario->step('Register') ->post('/register', [ '_token' => '${token}', 'name' => '${name}', // From CSV column 'email' => '${email}', // From CSV column 'password' => '${password}', // From CSV column 'password_confirmation' => '${password}', ]) ->header('Content-Type', 'application/x-www-form-urlencoded') ->expectStatus(302); // Step 3: Access Dashboard $scenario->step('Get Dashboard') ->get('/dashboard') ->header('Content-Type', 'text/html') ->expectStatus(200); } }
Distribution Modes
unique
: Each virtual user gets a different CSV row (recommended for user authentication)random
: Each virtual user gets a random CSV row (good for product browsing)sequential
: Virtual users cycle through CSV rows in order (predictable patterns)
E-commerce Example
// CSV file: storage/volttest/data/products.csv // product_id,sku,name,price,category // 1,SKU001,Laptop,999.99,electronics // 2,SKU002,Mouse,29.99,accessories $scenario = $manager->scenario('Product Browsing') ->dataSource('products.csv', 'random', true); $scenario->step('View Product') ->get('/products/${product_id}') ->expectStatus(200); $scenario->step('Add to Cart') ->post('/cart/add', [ 'product_id' => '${product_id}', 'quantity' => '1' ]) ->expectStatus(200);
Advanced CSV Usage
// Multiple scenarios with different data sources $userScenario = $manager->scenario('User Actions') ->dataSource('users.csv', 'unique') // Each user gets different account ->weight(70); // 70% of traffic $adminScenario = $manager->scenario('Admin Actions') ->dataSource('admins.csv', 'random') // Admins can overlap ->weight(30); // 30% of traffic
📖 Complete CSV Documentation
For detailed information including:
- File format requirements and validation
- All distribution modes with use cases
- Configuration options and file paths
- Troubleshooting and performance tips
- Advanced patterns and best practices
Read the complete CSV Data Source guide →
Advanced Configuration
Custom Test Paths
// config/volttest.php 'test_paths' => [ app_path('VoltTests'), base_path('tests/Performance'), base_path('custom/performance/tests'), ],
Custom Reports Path
// config/volttest.php 'reports_path' => storage_path('app/performance-reports'), 'save_reports' => true,
Testing Tips
1. Use Think Time
Add realistic delays between requests:
$scenario->step('Browse Products') ->get('/products') ->thinkTime('3s'); // User reading time
2. Extract Dynamic Values
Handle dynamic content properly:
$scenario->step('Login') ->get('/login') ->extractCsrfToken() ->post('/login', [ '_token' => '${csrf_token}', 'email' => 'user@example.com', 'password' => 'password', ]);
3. Test User Journeys
Create realistic user flows:
// Complete user journey $scenario->step('Homepage')->get('/'); $scenario->step('Browse Products')->get('/products'); $scenario->step('View Product')->get('/products/1'); $scenario->step('Add to Cart')->post('/cart/add', $data); $scenario->step('Checkout')->get('/checkout'); $scenario->step('Complete Order')->post('/orders', $orderData);
4. Handle Authentication
For API testing with authentication:
$scenario->step('Login') ->post('/api/login', $credentials) ->extractJson('token', 'access_token'); $scenario->step('Protected Resource') ->get('/api/protected') ->header('Authorization', 'Bearer ${token}');
Troubleshooting
Common Issues
Route Discovery Not Working
- Make sure routes are properly registered
- Check that middleware is correctly applied
- Use
--select
option to manually choose routes
Base URL Problems
- Set
VOLTTEST_BASE_URL
to your application URL - Ensure your application is running during tests
- For Docker setups, use the correct internal URL
Debug Mode
Enable debugging to see HTTP request/response details:
php artisan volttest:run --debug --stream
Or in configuration:
'http_debug' => true,
Testing
Run the package tests:
composer test
Learn More
- Laravel tutorial for php sdk - Step-by-step guide to using VoltTest with Laravel
- VoltTest PHP SDK Documentation - Complete guide to VoltTest core features
- Performance Testing types - Load testing concepts and types
- VoltTest API Reference - Full API documentation