Skip to content

Latest commit

 

History

History
384 lines (275 loc) · 12.4 KB

File metadata and controls

384 lines (275 loc) · 12.4 KB

Predictive Property-Based Testing (PPT) + Invariant System

A Production-Ready Framework for High-Visibility Development

Authors: Michael A. Kuykendall
Implementation: Shimmy AI Inference Engine
Status: Production-Ready ✅
License: MIT


📐 Abstract

Traditional Test-Driven Development (TDD) fails under high-change, AI-assisted, and exploratory development scenarios. This paper introduces PPT + Invariant Testing: a lightweight, enforceable framework that maintains semantic integrity while embracing rapid iteration.

The system has been battle-tested in Shimmy, a high-visibility AI inference engine with 95%+ test coverage and zero-regression deployment.


🎯 Core Innovation

The Problem with Traditional Testing

  1. Brittle Implementation-Based Tests - Break with every refactor
  2. Mock-Heavy Test Suites - Test fake behavior, not real systems
  3. Test Maintenance Overhead - More time spent on tests than features
  4. Silent Failure Drift - Critical invariants stop being checked over time

The PPT + Invariant Solution

  1. Focus on Properties - Test behaviors, not implementations
  2. Embed Runtime Invariants - Semantic contracts enforced in production code
  3. Automate Test Lifecycle - Self-maintaining test suites
  4. Track Invariant Coverage - Ensure critical contracts are always validated

🏗️ System Architecture

Three-Layer Test Hierarchy

Layer Purpose Lifecycle Enforcement
E-Test Exploration & Discovery Temporary explore_test()
P-Test Property Validation Stable property_test() + invariants
C-Test Contract Enforcement Permanent contract_test() + tracking

Runtime Invariant Enforcement

// Embed semantic contracts directly in business logic
assert_invariant(
    payment.amount > 0, 
    "Payment must be positive", 
    Some("checkout_flow")
);

Benefits:

  • Immediate Feedback - Violations crash fast with context
  • Semantic Logging - All checks are recorded for contract validation
  • Zero Overhead - Compiles to simple assertions in release builds
  • AI-Resistant - Contracts survive code generation and refactoring

🧪 Implementation Example - Shimmy AI Engine

Invariant Definition

// Model loading must always validate inputs and outputs
pub fn assert_model_loaded(model_name: &str, success: bool) {
    assert_invariant(
        !model_name.is_empty(),
        "Model name must not be empty",
        Some("model_loading")
    );
    
    if success {
        assert_invariant(
            true,
            "Model loaded successfully", 
            Some(&format!("model_loading:{}", model_name))
        );
    }
}

Property Testing

#[test]
fn test_model_loading_property() {
    property_test("model_names_always_valid", || {
        let test_names = vec!["phi3", "llama2-7b", "mistral-v0.1"];
        
        for name in test_names {
            clear_invariant_log();
            assert_model_loaded(name, true);
            
            // Verify the invariant was actually checked
            let checked = get_checked_invariants();
            if !checked.iter().any(|inv| inv.contains("Model name must not be empty")) {
                return false;
            }
        }
        true
    });
}

Contract Validation

#[test] 
fn test_model_loading_contracts() {
    clear_invariant_log();
    
    // Simulate the actual workflow
    assert_model_loaded("test-model", true);
    
    // Verify ALL required invariants were checked
    contract_test("model_loading_integrity", &[
        "Model name must not be empty",
        "Model loaded successfully"
    ]);
}

📊 Production Results - Shimmy Case Study

Testing Metrics

  • 293 Total Tests (up from 228 after PPT implementation)
  • 95%+ Test Coverage across all critical modules
  • 100% Invariant Coverage on core workflows
  • Zero Regressions during high-velocity development

Quality Gates Enforced

  1. 🧪 PPT Contract Tests - All semantic invariants verified
  2. 🔍 Property Tests - Behavioral consistency across input ranges
  3. 🚀 Exploration Tests - Edge case discovery and validation
  4. 📈 Coverage Gates - 95%+ coverage requirement enforced
  5. 🔒 Security Audits - Zero-vulnerability deployment

CI/CD Integration

# Automated PPT validation in GitHub Actions
- name: 🧪 Run PPT Contract Tests
  run: cargo test ppt_contracts --features "huggingface" -- --nocapture

- name: 📋 Run Property Tests  
  run: cargo test property_tests --features "huggingface" -- --nocapture

🎁 Framework Benefits

For High-Visibility Projects

Confidence Under Scrutiny - Every commit validates semantic correctness
Rapid Iteration Safety - Refactor fearlessly with invariant protection
AI-Assisted Development - Properties guide code generation correctly
Zero Silent Failures - Critical contracts can't be accidentally removed

For Development Teams

Reduced Test Maintenance - Properties are stable across refactors
Clear Failure Modes - Invariant violations provide immediate context
Semantic Documentation - Invariants serve as executable specifications
Regression Protection - Contract tests prevent invariant removal

For System Reliability

Production Monitoring - Same invariants run in production (optional)
Behavioral Consistency - Properties ensure stable system behavior
Edge Case Discovery - Exploration tests reveal unexpected scenarios
Quality Metrics - Invariant coverage provides meaningful quality measurement


🚀 Getting Started

1. Add Dependencies

[dependencies]
lazy_static = "1.4"

2. Include PPT System

mod invariant_ppt;
use invariant_ppt::*;

3. Define Your First Invariant

fn process_payment(amount: f64) -> Result<PaymentResult> {
    assert_invariant(amount > 0.0, "Payment amount must be positive", Some("payments"));
    
    // Your business logic here
    Ok(PaymentResult::Success)
}

4. Create Contract Tests

#[test]
fn test_payment_contracts() {
    clear_invariant_log();
    
    // Exercise your system
    process_payment(100.0).unwrap();
    
    // Verify the contracts were checked
    contract_test("payment_processing", &["Payment amount must be positive"]);
}

🌟 Why This Works

Traditional Testing Problems Solved

Problem PPT + Invariant Solution
Brittle mocks Test real behavior with property validation
Implementation coupling Properties focus on behavior, not code structure
Test maintenance burden Self-documenting invariants survive refactors
Silent contract drift Contract tests ensure invariants are never removed
AI code quality Invariants guide and validate AI-generated code

Philosophical Alignment

  • Embrace Change - Properties are stable while implementations evolve
  • Fail Fast - Invariant violations provide immediate, actionable feedback
  • Document Behavior - Executable contracts are always up-to-date
  • Trust but Verify - Contract tests ensure promises are kept

📈 Advanced Patterns

Hierarchical Invariants

// System-level invariant
assert_invariant(system_is_initialized(), "System must be initialized", Some("system"));

// Subsystem-level invariant  
assert_invariant(database_is_connected(), "Database must be connected", Some("system:database"));

// Operation-level invariant
assert_invariant(user_is_authenticated(), "User must be authenticated", Some("system:auth:user"));

Cross-Service Contracts

// Service A
assert_invariant(request_is_valid(), "Request format valid", Some("service_a:input"));

// Service B  
contract_test("service_integration", &[
    "Request format valid",  // Verify Service A's guarantee
    "Response format valid"  // Verify our own guarantee
]);

Property-Based Fuzzing

property_test("input_validation_robustness", || {
    // Generate random inputs
    let test_inputs = generate_random_inputs(100);
    
    for input in test_inputs {
        clear_invariant_log();
        let result = process_input(input);
        
        // Verify invariants held regardless of input
        let checked = get_checked_invariants();
        if !checked.iter().any(|inv| inv.contains("Input validation")) {
            return false;
        }
    }
    true
});

🎯 Best Practices

Do's

Start Small - Begin with 2-3 critical invariants
Focus on Contracts - Test what the system promises, not how it works
Use Descriptive Messages - Invariant failures should be immediately actionable
Test the Tests - Use contract tests to verify invariants are actually checked
Embrace Exploration - Use E-tests to discover edge cases and new properties

Don'ts

Don't Mock Reality - Test real behavior with real data when possible
Don't Test Implementation - Properties should survive complete rewrites
Don't Ignore Failures - Invariant violations indicate real semantic problems
Don't Skip Contracts - Contract tests prevent silent invariant removal
Don't Over-Engineer - Start simple, add complexity only when needed


📚 Related Work & References

Influences

  • Property-Based Testing (QuickCheck, PropTest) - Random input generation
  • Design by Contract (Eiffel, Ada) - Formal pre/post conditions
  • Behavioral Testing (Cucumber, RSpec) - Focus on system behavior
  • Invariant-Based Programming (SPARK, Dafny) - Mathematical correctness proofs

Unique Contributions

  1. Runtime Integration - Invariants execute in production code, not just tests
  2. AI-Assisted Compatibility - Properties guide and validate generated code
  3. Lightweight Implementation - No complex frameworks or mathematical proofs required
  4. High-Change Tolerance - System designed for rapid iteration and refactoring

🌐 Future Directions

Tooling Enhancements

  • IDE Integration - Highlight functions missing critical invariants
  • Coverage Visualization - Show invariant coverage in code review tools
  • Property Generators - AI-assisted property test generation
  • Cross-Language Support - Port framework to TypeScript, Python, Go

Research Applications

  • ML Model Testing - Invariants for model behavior and fairness
  • Distributed System Contracts - Cross-service invariant validation
  • Security Properties - Automated security contract enforcement
  • Performance Contracts - SLA enforcement through property testing

🎉 Conclusion

PPT + Invariant Testing transforms software quality from a testing problem into a design problem. By embedding semantic contracts directly into business logic and validating them through property-based testing, we achieve:

  • 🔒 Semantic Integrity - Systems behave correctly by construction
  • ⚡ Rapid Iteration - Refactor fearlessly with invariant protection
  • 🤖 AI Compatibility - Properties guide and validate generated code
  • 📈 Quality Metrics - Invariant coverage provides meaningful measurement
  • 🚀 Production Confidence - High-visibility deployment without fear

The Shimmy implementation demonstrates that this approach scales to real-world, production systems under high-visibility development pressure.


📖 Learn More


This is How You Do It Right™

High-visibility development with semantic integrity, property-based robustness, and automated quality gates at every stage.