Testovanie
Health::fake() nahradí manažér — pre fasádu aj pre všetko, čo si HealthManager injektuje — zaznamenávajúcim HealthFake a vráti ho. Fake si ponechá registrované kontroly, spúšťa ich bez odosielania jobov, notifikácií či zápisu riadkov, na report(), status() a stlmenia odpovedá z pamäte a zaznamená každé volanie, aj cez trait UsesHealthChecks a príkazy Artisan:
use RoundlyConsulting\Alerts\CheckResult;
use RoundlyConsulting\Alerts\Facades\Health;
$fake = Health::fake();
Health::define('disk-full', fn () => CheckResult::failed('Disk full'));
Health::for($team)->run(DiskUsageCheck::class); // healthy: checked, nothing to recover
Health::for($team)->run('disk-full'); // failing: alerted
$team->monitorCheck(DiskUsageCheck::class)->hourly()->save();
Health::silences()->mute('db', for: $team);
$this->artisan('alerts:prune-runs', ['--days' => 7]);
$fake->assertChecked('disk_usage_check');
$fake->assertNothingRecovered(); // a first healthy run recovers nothing
$fake->assertAlerted('disk-full'); // not recorded while a fake silence matches
$fake->assertMonitored(DiskUsageCheck::class, $team);
$fake->assertMuted('db', $team);
$fake->assertPruned(7);
$fake->assertNothingRanDue();Všetky aserácie
| Aserácia | Negácia | Prejde, keď |
|---|---|---|
assertChecked(string $key) | assertNothingChecked() | Kontrola s týmto kľúčom bežala pre niektorého vlastníka. |
assertAlerted(string $key) | assertNothingAlerted() | Pre kľúč sa spustil alert: dosiahol sa failAfter po sebe idúcich zlyhaní (warning alebo failed) a jeho kľúču, tagom ani * nezodpovedalo žiadne stlmenie vo fake. |
assertRecovered(string $key) | assertNothingRecovered() | Otvorený alert kľúča sa zatvoril po recoverAfter po sebe idúcich úspechoch a nezodpovedalo mu žiadne stlmenie vo fake. Úspešný beh bez otvoreného alertu nezaznamená nič. |
assertMonitored(string $checkOrKey, ?Model $owner = null) | assertNothingMonitored() | Kontrola (názov triedy alebo kľúč) bola naplánovaná — cez monitor()->save(), schedule() alebo trait — pre zadaného vlastníka, ak ho uvediete. |
assertUnmonitored(string $checkOrKey, ?Model $owner = null) | assertNothingUnmonitored() | Pre kontrolu sa zavolal unmonitor(), pri zadanom vlastníkovi pre neho. |
assertMuted(string $key, ?Model $owner = null) | assertNothingMuted() | Pre kľúč sa zavolal silences()->mute(), pri zadanom vlastníkovi s obmedzením naňho. |
assertUnmuted(string $key, ?Model $owner = null) | assertNothingUnmuted() | Pre kľúč sa zavolal silences()->unmute(), pri zadanom vlastníkovi s obmedzením naňho. |
assertRanDue(?int $times = null) | assertNothingRanDue() | Zavolal sa runDue() — aspoň raz, alebo presne $times-krát. |
assertPruned(?int $days = null) | assertNothingPruned() | Zavolal sa prune() — pri zadanom počte dní práve s ním. |
$fake = Health::fake();
$healthy = false;
Health::define('payments-api', function () use (&$healthy): bool {
return $healthy;
})->failAfter(2)->recoverAfter(2);
Health::for($team)->run('payments-api'); // 1st failure — below failAfter
$fake->assertNothingAlerted();
Health::for($team)->run('payments-api'); // 2nd failure — the alert opens
$fake->assertAlerted('payments-api');
$healthy = true;
Health::for($team)->run('payments-api'); // 1st OK — still open
$fake->assertNothingRecovered();
Health::for($team)->status(); // Status::Failed until recovery is confirmed
Health::for($team)->run('payments-api'); // 2nd OK — the alert closes
$fake->assertRecovered('payments-api');
Health::for($team)->unmonitor(DiskUsageCheck::class);
Health::silences()->unmute('db', for: $team);
Health::runDue();
$fake->assertUnmonitored(DiskUsageCheck::class, $team);
$fake->assertUnmuted('db', $team);
$fake->assertRanDue(1);
$fake->assertNothingMonitored();
$fake->assertNothingMuted();
$fake->assertNothingPruned();Ako sa fake správa
- Beh prejde rovnakými bránami ako skutočný, s pamäťou pre každého vlastníka a kontrolu: vyhodená výnimka alebo prekročený časový limit sa stane výsledkom failed, alert sa zaznamená až po dosiahnutí failAfter po sebe idúcich zlyhaní a obnova len vtedy, keď sa otvorený alert zatvorí po recoverAfter po sebe idúcich úspechoch. Žiadne riadky, behy, udalosti ani notifikácie.
- Voľby pochádzajú zo spúšťaného riadka, z monitoringu zaznamenaného pre daného vlastníka alebo z define() inline kontroly. Riadok iného vlastníka aj tak odmietne s InvalidHealthCheck.
- report() a status() sa zostavia z monitoringov fake v pamäti — otvorený alert pre každého vlastníka a kontrolu, rovnako ako v skutočnom reporte — nikdy nie z databázy.
- Stlmenia žijú v pamäti: zodpovedajúce stlmenie vo fake (kľúč, tag alebo *) potlačí zaznamenanie alertu a isMuted() aj active() ich vracajú.
- schedule(), monitor()->save() a mute() vracajú neuložené modely; neplatný cron odmietnu s InvalidCronExpression, rovnako ako skutočná akcia. runDue(), prune() a unmonitor() vracajú 0; monitors() vráti prázdnu kolekciu.
- Výsledky skipped nemenia počítadlá a nezaznamenajú alert ani obnovu.
Test celej cesty
Pre end-to-end správanie spustite skutočnú cestu nad vašou databázou s fakes Notification a Event z Laravelu:
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Notification;
use RoundlyConsulting\Alerts\CheckResult;
use RoundlyConsulting\Alerts\Events\HealthCheckFailed;
use RoundlyConsulting\Alerts\Facades\Health;
it('opens an alert and notifies the team when a check fails', function () {
Notification::fake();
Event::fake([HealthCheckFailed::class]);
Health::define('always-down', fn () => CheckResult::failed('Down'));
$team = Team::factory()->create();
$result = Health::for($team)->run('always-down');
expect($result->status->isAlertable())->toBeTrue()
->and($team->alerts()->open()->count())->toBe(1);
Event::assertDispatched(HealthCheckFailed::class);
});Factories
HealthCheck, Alert, HealthCheckRun a AlertSilence majú pribalené factories. Alert má stavy warning(), failed(), skipped() a recovered(). Stĺpce vlastníka nasmerujte na skutočného vlastníka:
use RoundlyConsulting\Alerts\Alert;
use RoundlyConsulting\Alerts\HealthCheck;
use RoundlyConsulting\Alerts\HealthCheckRun;
$row = HealthCheck::factory()->create([
'notifiable_type' => $team->getMorphClass(),
'notifiable_id' => $team->getKey(),
'health_check' => 'disk_usage_check',
]);
HealthCheckRun::factory()->count(20)->create(['health_check_id' => $row->id]);
Alert::factory()->warning()->create([ // also failed(), skipped(), recovered()
'notifiable_type' => $team->getMorphClass(),
'notifiable_id' => $team->getKey(),
'health_check_id' => $row->id,
]);Vlastné testy balíka
composer testPrejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.