Распределение
Проверка распределения
Свойство может пройти вакуумно, если его генераторы никогда не достигают интересных входов. Classify записывает метки на каждый прогон; после полностью прошедшего свойства раннер печатает долю прогонов, попавших в каждую метку.
#[Property(runs: 500)]
public function holds(int $n): void
{
Classify::when($n === 0, 'zero');
Classify::label($n % 2 === 0 ? 'even' : 'odd');
// ... assertions ...
}
// Property "holds" distribution: odd 51% (255/500), even 49% (245/500), zero 1% (3/500)Метка, записанная несколько раз в одном прогоне, считается для этого прогона один раз.
Инфорсмент распределения
Classify::cover() превращает печатную подсказку в жёсткое требование: метка должна встречаться минимум в заданном проценте успешных прогонов, иначе свойство падает с CoverageViolationException — даже если каждый прогон прошёл. Используйте это, чтобы сделать вакуумные проходы невозможными в CI.
#[Property(runs: 500)]
public function holds(int $n): void
{
Classify::cover($n % 2 === 0, 'even', 30.0); // fail if < 30% of runs are even
// ... assertions ...
}Отброшенные попытки (Assume::that()) исключаются из знаменателя и замещаются, пока не выполнятся все запрошенные успешные прогоны. Превышение maxDiscards роняет свойство через GaveUpException (см. Assume::that()).