Skip to main content

Documentation

Testing

Testing guide

Testing

๐Ÿงช Testing Guide

Running Tests

# Run all tests
cargo test

# Run specific test
cargo test test_basic_operation

# Run with output
cargo test -- --nocapture

# Run tests in parallel
cargo test --release --test-threads=4

Test Structure

Stackhouse is backed by Postgres (via sqlx/StackhouseStore), not a bespoke WAL/memtable/SSTable storage engine โ€” there is no stackhouse_core module. Unit tests live inline as #[cfg(test)] mod tests blocks inside individual src/ files (18 files currently do this); integration/contract tests live in stackhouse/tests/:

stackhouse/
โ”œโ”€โ”€ src/
โ”‚   โ””โ”€โ”€ ... (individual modules with inline #[cfg(test)] mod tests blocks)
โ””โ”€โ”€ tests/
    โ”œโ”€โ”€ api_security_regression.rs
    โ”œโ”€โ”€ billing_integration.rs
    โ”œโ”€โ”€ brain_catalog_contract.rs
    โ”œโ”€โ”€ core_api_feature_coverage.rs
    โ”œโ”€โ”€ schema_inference_contract.rs
    โ”œโ”€โ”€ security_hardening.rs
    โ””โ”€โ”€ source_security_scan.rs

Writing Tests

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_basic_operation() {
        // unit-test the function/struct in this module directly
    }
}

Integration Tests

Integration tests in stackhouse/tests/ spin up an in-memory StackhouseStore and drive the real Axum router through tower::ServiceExt::oneshot (see stackhouse/tests/core_api_feature_coverage.rs):

use std::sync::Arc;
use axum::{body::Body, http::Request};
use tower::ServiceExt;
use stackhouse::{api::{create_router, AppState}, db::StackhouseStore};

#[tokio::test]
async fn test_api_endpoint() {
    let store = StackhouseStore::in_memory().await.unwrap();
    let app = create_router(AppState::new(Arc::new(store)));

    let response = app
        .oneshot(Request::builder()
            .method("POST")
            .uri("/v1/push/test")
            .header("content-type", "application/json")
            .body(Body::from(serde_json::json!({"name": "Test"}).to_string()))
            .unwrap())
        .await
        .unwrap();

    assert_eq!(response.status(), 200);
}

Tests that need a real database gracefully skip (print a message and return early) when StackhouseStore::in_memory() can't reach a test database, rather than failing.

Test Coverage

# Install tarpaulin
cargo install cargo-tarpaulin

# Generate coverage report
cargo tarpaulin --out Html

# View report
open tarpaulin-report/index.html

Benchmarks

See Benchmarks for performance testing.


Done! ๐ŸŽ‰