Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як тестувати код з паузами через Sleep і вимірювати швидкість через Benchmark?

Проблема sleep(): код з паузами (очікування між повторами, обмеження частоти запитів до API) робить тести повільними, а перевірити, скільки саме чекав код, неможливо.

Клас Sleep - обгортка над sleep/usleep, яку можна підробити в тестах:

use Illuminate\Support\Sleep;

Sleep::for(500)->milliseconds();
Sleep::for(2)->seconds();
Sleep::until(now()->addMinute());

// між запитами до API з лімітом частоти
foreach ($pages as $page) {
    $client->fetch($page);
    Sleep::for(1)->second();
}

У тесті:

use Illuminate\Support\Sleep;

Sleep::fake();

$importer->run();

Sleep::assertSlept(fn (Carbon\CarbonInterval $d) => $d->totalSeconds === 1, times: 3);
Sleep::assertSequence([
    Sleep::for(1)->second(),
    Sleep::for(2)->seconds(),
]);
Sleep::assertNeverSlept();

Тест проходить миттєво, а затримки перевіряються явно. Sleep::fake(syncWithCarbon: true) ще й пересуває «поточний час» Carbon на тривалість паузи.

Бонус: хелпер retry() під капотом чекає через Sleep, тож Sleep::fake() робить миттєвими й тести з повторними спробами.

Benchmark - швидко порівняти варіанти коду:

use Illuminate\Support\Benchmark;

Benchmark::dd([
    'eager' => fn () => Post::with('author')->get(),
    'lazy' => fn () => Post::all()->each->author,
], iterations: 10);
// ["eager" => "12.3ms", "lazy" => "48.7ms"]

$ms = Benchmark::measure(fn () => $report->build());   // середній час у мс

[$result, $ms] = Benchmark::value(fn () => $report->build());  // результат і час

Обмеження Benchmark:

  • це мікробенчмарк у поточному процесі: кеш бази, OPcache, прогрів впливають на результат. Перша ітерація часто повільніша - тому iterations;
  • для продакшен-продуктивності потрібні профілювальники й моніторинг (Xdebug, Blackfire, Pulse, APM), а не Benchmark::dd;
  • Benchmark::dd() зупиняє виконання - лише для локального налагодження.

Benchmark::value() корисний і в продакшен-коді: повертає результат разом з тривалістю, яку можна записати в лог чи метрику для повільних операцій.

Докладніше в документації: Хелпери: Sleep

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання