davro / php-bit
Behavioral Integrity Testing (BIT) library for PHP to detect and prevent behavioral drift in applications.
Requires
- php: ^8.0
- ext-json: *
- sebastian/diff: ^5.1
- symfony/console: ^6.4
Requires (Dev)
- phpunit/phpunit: ^10.0
This package is auto-updated.
Last update: 2025-03-09 05:40:04 UTC
README
The Behavioral Integrity Testing (BIT) library is a PHP tool designed to help developers detect and prevent behavioral drift in their applications. It allows you to capture a baseline of your system's behavior (e.g., API responses, database states) and monitor it over time to detect unintended changes.
Features
- Capture Baselines: Store a snapshot of your system's behavior for future comparison.
- Monitor Behavior: Compare the current behavior against the stored baseline to detect drift.
- Detect Drift: Identify specific differences between the current behavior and the baseline.
- CLI Support: Use the command-line interface to capture baselines and extract drift details.
Installation
You can install the BIT library via Composer:
composer require davro/php-bit
Usage
To use the BIT library, you can capture a baseline response first. This is the response that you want to compare all future responses against.
Code: Capture a Baseline with no Drift, monitor status returns true.
$response = ['status' => 'success']; BIT::captureBaseline('test-response', $response); // Returns true if the response is the same as the baseline $status = BIT::monitor('test-response', $response);
Code: Capture a Baseline with Drift, monitor status returns false.
$response = ['status' => 'success']; BIT::captureBaseline('test-response', $response); // Monitor a different response (drift detected) $differentResponse = ['status' => 'failure']; $status = BIT::monitor('test-response', $differentResponse);
Code: Capture a Baseline with Drift, monitor status and fetch diff.
$response = ['status' => 'success']; BIT::captureBaseline('test-response', $response); // Detect drift with a different response $differentResponse = ['status' => 'failure']; $result = BIT::detectDrift('test-response', $differentResponse); // Returns true if drift is detected $drift = $result['drift_detected']; // Returns the diff between the baseline and the current response $resultDiff = $result['diff']; // Result Diff // '+ "status": "failure"' // '- "status": "success"'
Command Line: Capture a Baseline
Use the bit:capture command to capture a baseline of your system's behavior. The baseline will be stored as a JSON file in the storage/baselines/ directory.
php bin/bit bit:capture test-response '{"status":"success"}'
Command Line: Extract Baseline Data.
If no data argument is provided, the command will return the stored baseline data:
php bin/bit bit:extract test-response Stored Baseline: { "status": "success" }
Command Line: Extract Details with Drift
If drift is detected, the command will output a summary and details of the differences: Use the bit:extract command to compare the current behavior against the stored baseline and extract drift details.
php bin/bit bit:extract test-response '{"status":"failure"}' Drift Detected: true Summary: 1 fields modified. Details: - Modified: status => "failure"
Command Line: Extract Details with Drift and adding Additional fields
If drift is detected, the command will output a summary and details of the differences: Use the bit:extract command to compare the current behavior against the stored baseline and extract drift details.
php bin/bit bit:extract test-response '{"status":"failure","new_field1":"new_value1", "new_field2":"new_value2"}' Drift Detected: true Summary: 2 fields added, 1 fields modified. Details: - Added: new_field1 => "new_value1" - Added: new_field2 => "new_value2" - Modified: status => "failure"
Command Line: Delete a Baseline
php bin/bit bit:delete test-response
Output if successful:
Baseline deleted for key: test-response
Output if baseline not found:
<error>Baseline not found for key: test-response</error>
Explanation of the Code DeleteCommand Class:
The command takes one argument: key (the baseline identifier).
It checks if the baseline file exists in the storage/baselines/ directory.
If the file exists, it deletes it using unlink().
If the file does not exist, it outputs an error message.
Error Handling:
The command handles cases where the baseline does not exist or the file cannot be deleted.
Command Line: Clear All Baselines
php bin/bit bit:clear
Output if successful:
Cleared 3 baselines.
Output if no baselines exist:
No baselines found to clear.
Output if deletion fails:
<error>Failed to delete baseline: test-response.json</error>
Explanation of the Code ClearCommand Class:
The command scans the storage/baselines/ directory for JSON files.
It deletes each file using unlink() and keeps track of the number of deleted files.
If no baselines are found, it outputs a message saying No baselines found to clear.
Error Handling:
The command handles cases where files cannot be deleted and outputs an error message for each failure.
Code: Using the Library
You can also use the BIT library directly in your PHP code:
use BIT\BIT; // Capture a baseline BIT::captureBaseline('test-response', ['status' => 'success']); // Monitor behavior $result = BIT::getDriftDetails('test-response', ['status' => 'failure', 'new_field' => 'value']); if ($result['drift_detected']) { echo "Drift Detected: true\n"; echo "Summary: " . $result['summary'] . "\n"; echo "Details:\n"; foreach ($result['details'] as $detail) { echo "- {$detail['type']}: {$detail['field']} => {$detail['value']}\n"; } }
BIT Performance Profiler
BIT\Performance\Profiler is a lightweight PHP utility for measuring execution times of operations within your application. It helps detect performance regressions and track execution time over multiple runs.
📌 Features
- ✅ Start and stop timers for named operations
- ✅ Measure execution time with microsecond precision
- ✅ Track multiple operations independently
- ✅ Detect performance regressions over time
- ✅ Useful for debugging, logging, and optimizing performance
Include the profiler:
use BIT\Performance\Profiler;
🛠️ Usage 1️⃣ Basic Execution Time Measuremeny
use BIT\Performance\Profiler; Profiler::start('database_query'); $result = someDatabaseQuery(); // Simulated operation $executionTime = Profiler::stop('database_query'); echo "Query executed in: {$executionTime} seconds";
✅ Ensures operations are benchmarked for performance analysis.
2️⃣ Measuring Multiple Operations
Profiler::start('api_call'); usleep(70000); // Simulate 70ms delay Profiler::stop('api_call'); Profiler::start('file_read'); usleep(50000); // Simulate 50ms delay Profiler::stop('file_read'); print_r(Profiler::getExecutionTimes());
✅ Stores and retrieves execution times for multiple operations.
3️⃣ Handling Exceptions for Missing Start Calls If stop() is called without a corresponding start(), an exception is thrown:
try { Profiler::stop('missing_operation'); } catch (\Exception $e) { echo "Error: " . $e->getMessage(); }
🔴 Output:
Error: No matching start() call for 'missing_operation'
✅ Prevents incorrect usage of the profiler.
Configuration
By default, baselines are stored in the storage/baselines/ directory. You can customize the storage directory by setting the BIT_STORAGE_DIR environment variable:
export BIT_STORAGE_DIR=/path/to/your/storage
Contributing
Contributions are welcome! If you'd like to contribute to the BIT library, please follow these steps:
Fork the repository.
Create a new branch for your feature or bugfix.
Submit a pull request with a detailed description of your changes.
License
The BIT library is open-source software licensed under the MIT License.
Roadmap
Here are some planned features for future releases:
- Custom Storage Backends: Support for databases, cloud storage, and in-memory storage.
- Advanced Diffing: Improved diffing for nested structures and contextual diffs.
- Framework Integration: Middleware and service providers for Laravel, Symfony, and Slim.
- Reporting and Visualization: Generate HTML reports and visualize drift trends.
-
Add More CLI Commands Expand the CLI tool with additional commands.
-
Add Framework Integration Make the library easier to use in popular PHP frameworks like Laravel, Symfony, and Slim by:
- Creating service providers or bundles.
- Adding middleware for automatic behavior monitoring in web applications.
- Enhance Diffing and Reporting Improve the drift detection and reporting capabilities by:
- Adding support for nested structures (e.g., arrays within arrays, objects within objects).
- Generating HTML reports with detailed diffs and summaries.
- Visualizing drift trends over time using graphs and charts.
- Add Support for Custom Storage Backends Allow users to store baselines in different backends, such as:
- Databases (e.g., MySQL, PostgreSQL).
- Cloud Storage (e.g., AWS S3, Google Cloud Storage).
- In-Memory Storage for short-lived use cases.
- Write More Tests Ensure the library is reliable by adding comprehensive tests for all features and edge cases. For example:
- Test the CLI commands (bit:capture, bit:extract).
- Test edge cases like invalid JSON input, missing baselines, and empty data.
- Engage the Community Share PHP BIT with the PHP community to get feedback and contributions:
- Post about it on forums like Reddit or Dev.to.
- Share it on social media (e.g., Twitter, LinkedIn).
- Submit it to PHP newsletters or blogs.
Support
If you encounter any issues or have questions, please open an issue on GitHub.
📌 Contributing
Want to improve the BIT Library
Fork the repository Submit a PR with improvements Open an issue for feature requests or bug reports