Skip to content

QA-6: Property-based тесты движений (jqwik) #106

Description

@ii-reviewer

Цель: проверять инварианты остатков на рандомизированных последовательностях операций, а не на единичных примерах.
Зависимость: #5, #6, #9.

Что сделать

  • Подключи net.jqwik:jqwik. Сформулируй инварианты домена как свойства:
    • остаток никогда не уходит в минус (списание сверх остатка отклоняется, Валидация остатков #9);
    • Σ(приходы) − Σ(успешных расходов) == текущий остаток;
    • порядок применённых операций не нарушает эти равенства.
  • Генерируй случайные последовательности операций и прогоняй через сервис:
@Property
void stockNeverNegative(@ForAll("ops") List<Movement> ops) {
    int stock = apply(ops);
    assertThat(stock).isGreaterThanOrEqualTo(0);
}
@Provide Arbitrary<List<Movement>> ops() { /* RECEIVE/WRITE_OFF, random qty */ }
  • Трудные места: генераторы реалистичных последовательностей (смесь приходов/расходов, граничные количества, нули); jqwik сам сжимает контрпример (shrinking) — зафиксируй найденный сид как регрессионный тест; решить, гонять на чистом сервисе с моками или на Testcontainers.

Acceptance criteria

  • Свойства покрывают оба инварианта (неотрицательность и баланс прихода/расхода)
  • Тесты гоняют рандомизированные последовательности (много примеров на свойство)
  • Найденный контрпример воспроизводится (зафиксирован сид/кейс)
  • Нарушение инварианта роняет сборку

Metadata

Metadata

Assignees

No one assigned

    Labels

    ciCI/CD, автоматизация сборкиenhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions