Test Basé sur les Propriétés

VérifiéSûr

Tests basés sur les propriétés avec fast-check pour valider les invariants de la logique métier en générant des entrées aléatoires. Cela permet de garantir la correction pour des cas limites que les tests manuels pourraient manquer, notamment pour les calculs mathématiques, les invariants d'inventaire et les transitions d'état.

Spar Skills Guide Bot
TestingIntermédiaire
10002/06/2026
Claude Code
#property-testing#fast-check#business-logic#invariants

Recommandé pour

Notre avis

Cette compétence enseigne les tests basés sur les propriétés avec fast-check pour valider les invariants de la logique métier.

Points forts

  • Couverture exhaustive des entrées possibles
  • Détection d'effets de bord et de cas limites
  • Vérification d'invariants métier critiques
  • Intégration facile avec Vitest

Limites

  • Courbe d'apprentissage pour définir des propriétés pertinentes
  • Ne remplace pas les tests unitaires classiques pour la logique déterministe simple
  • Peut être plus lent que les tests par exemples
Quand l'utiliser

Lorsque vous devez vérifier qu'un invariant métier se maintient pour toutes les entrées valides.

Quand l'éviter

Pour des transformations simples sans invariant à garantir, préférez des tests unitaires classiques.

Analyse de sécurité

Sûr
Score qualité88/100

This skill is a purely instructional guide to property-based testing with fast-check. It contains no executable commands, destructive operations, exfiltration, or obfuscation.

Aucun point d'attention détecté

Exemples

Test FCR calculation
Write a property-based test for the FCR calculation function that takes feed and weight gain as inputs. The property should ensure that for any positive feed and weight gain, the FCR is positive and finite.
Test inventory invariant
Write a property-based test to verify the inventory invariant: current quantity equals initial quantity minus sum of mortalities minus sum of sales. Use fast-check to generate random initial quantities, mortalities, and sales, and ensure the calculated current quantity is non-negative and does not exceed the initial quantity.

name: Property Testing description: Property-based testing with fast-check for business logic validation

Property Testing

LivestockAI uses property-based testing (PBT) with fast-check to validate business logic invariants.

What is Property Testing?

Instead of testing specific examples, property tests verify that properties hold for ALL possible inputs:

// Example-based test
it('calculates FCR correctly', () => {
  expect(calculateFCR(150, 100)).toBe(1.5)
})

// Property-based test
it('FCR is always positive when inputs are positive', () => {
  fc.assert(
    fc.property(
      fc.float({ min: 0.1, max: 10000 }),
      fc.float({ min: 0.1, max: 10000 }),
      (feed, weight) => {
        const fcr = calculateFCR(feed, weight)
        return fcr === null || fcr > 0
      },
    ),
  )
})

fast-check Basics

import { describe, it, expect } from 'vitest'
import * as fc from 'fast-check'

describe('Property Tests', () => {
  it('property holds for all inputs', () => {
    fc.assert(
      fc.property(fc.integer({ min: 1, max: 100000 }), (quantity) => {
        // Property must return true or throw
        return quantity > 0
      }),
      { numRuns: 100 },
    )
  })
})

Common Arbitraries

// Integers
fc.integer({ min: 1, max: 100000 })
fc.nat() // Non-negative integer

// Floats
fc.float({ min: 0, max: 10000 })

// Strings
fc.string()
fc.uuid()

// Arrays
fc.array(fc.integer(), { minLength: 0, maxLength: 20 })

// Objects
fc.record({
  quantity: fc.integer({ min: 1, max: 1000 }),
  price: fc.float({ min: 0, max: 10000 }),
})

Inventory Invariant Example

From tests/features/batches/batches.property.test.ts:

/**
 * Property 4: Inventory Invariant
 * For any batch, current_quantity SHALL always equal:
 * initial_quantity - sum(mortality) - sum(sales)
 */
describe('Property 4: Inventory Invariant', () => {
  it('current_quantity equals initial - mortalities - sales', () => {
    fc.assert(
      fc.property(
        fc.integer({ min: 1, max: 100000 }),
        fc.array(fc.integer({ min: 1, max: 1000 })),
        fc.array(fc.integer({ min: 1, max: 1000 })),
        (initial, mortalities, sales) => {
          const { constrained } = constrainQuantities(
            initial,
            mortalities,
            sales,
          )
          const current = calculateCurrentQuantity(initial, constrained)

          expect(current).toBeGreaterThanOrEqual(0)
          expect(current).toBeLessThanOrEqual(initial)
        },
      ),
      { numRuns: 100 },
    )
  })
})

Linking to Requirements

Annotate tests with requirement links:

/**
 * **Validates: Requirements 3.2, 4.2, 8.2**
 */
it('inventory invariant holds', () => {
  // ...
})

When to Use Property Testing

  • Mathematical calculations (FCR, mortality rate, profit)
  • Invariants (quantity never negative, totals match)
  • State transitions (batch status changes)
  • Data transformations (currency conversion)

Related Skills

  • vitest-patterns - Unit testing basics
  • three-layer-architecture - Service layer testing
Skills similaires