PHP code example of ralder / phpunit-query-scaling

1. Go to this page and download the library: Download ralder/phpunit-query-scaling library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

ralder / phpunit-query-scaling example snippets


use PHPUnit\Framework\TestCase;
use Ralder\QueryScaling\Assertions\QueryScalingAssertions;
use Ralder\QueryScaling\QueryGrowth;

final class PostIndexQueryTest extends TestCase
{
    use QueryScalingAssertions;

    public function test_index_scales_constantly(): void
    {
        $this->assertQueriesScaleConstantly(
            scales: [2, 5, 10],

            // Populate $scale rows on EVERY scale run; runs against a clean dataset.
            populate: function (int $scale): void {
                Post::factory()->count($scale)->hasComments(2)->create();
            },

            // The measured scenario; exactly $run() queries are counted.
            run: function (): void {
                $posts = Post::with('comments')->get();

                $this->assertTrue($posts->every->comments->isNotEmpty());
            },
        );
    }

    public function test_comment_counts_scale_linearly_at_most(): void
    {
        $this->assertQueryScaling(
            scales: [2, 5, 10],
            expectation: QueryGrowth::atMostSlope(1, 0),
            populate: function (int $scale): void {
                Post::factory()->count($scale)->create();
            },
            run: function (): void {
                // one lookup query per post is acceptable; two per post is not
                Post::all()->each->comments->count();
            },
        );
    }
}

use Ralder\QueryScaling\Assertions\QueryScalingAssertions;
use Ralder\QueryScaling\QueryGrowth;

uses(Tests\TestCase::class, QueryScalingAssertions::class);

test('index scales constantly', function (): void {
    $this->assertQueriesScaleConstantly(
        scales: [2, 5, 10],
        populate: fn (int $scale) => Post::factory()->count($scale)->create(),
        run: function (): void {
            $this->getJson('/api/posts')->assertSuccessful();
        },
    );
});

protected function assertQueriesScaleConstantly(
    array $scales,                    // ascending positive ints, at least two: [2, 5], [2, 5, 10], ...
    Closure(int): void $populate,     // populate $scale entities; runs off-meter
    Closure(): void $run,             // measured scenario
    ?Closure(int): void $warmup = null,        // optional per-scale warmup; runs off-meter
    int $tolerance = 0,                        // absolute query-count spread allowed
    array|string|null $connections = null,     // measured connections; null = the default connection
    ?IsolationStrategy $isolation = null,      // custom isolation override
    bool $showBindings = false,                // print ≤3 example bindings per growing fingerprint
    bool $normalizeLiterals = false,           // opt-in literal folding in fingerprints
): void;

protected function assertQueryScaling(
    array $scales,
    Closure(int): void $populate,
    Closure(): void $run,
    ScalingExpectation $expectation,    // QueryGrowth::constant() / atMostSlope() or your own
    ?Closure(int): void $warmup = null,
    array|string|null $connections = null,
    ?IsolationStrategy $isolation = null,
    bool $showBindings = false,
    bool $normalizeLiterals = false,
): void;

$this->assertQueriesScaleConstantly(
    scales: [2, 5, 10],
    populate: /* writes to both connections */,
    run: fn () => $this->getJson('/api/dashboard'),
    connections: ['mysql', 'tenant'],   // measure exactly these
);