Testing

Strategies for verifying Resuma apps — HTTP integration, loader logic, and E2E.

Integration tests (recommended)

Test the axum router produced by FlowApp::into_router():

use axum::body::Body;
use axum::http::{Request, StatusCode};
use resuma::prelude::*;
use tower::ServiceExt;

#[tokio::test]
async fn home_returns_200() {
    let app = FlowApp::new()
        .page("/", || view! { <h1>"Hi"</h1> })
        .into_router(FlowServeOptions::default());

    let res = app
        .oneshot(Request::get("/").body(Body::empty()).unwrap())
        .await
        .unwrap();

    assert_eq!(res.status(), StatusCode::OK);
}

Submit + redirect

#[submit]
async fn create(_form: Form, _req: &FlowRequest) -> Result<Redirect, SubmitError> {
    Ok(redirect("/items"))
}

// JSON client: { ok: true, redirect: "/items" }
// No-JS browser: 303 See Other

Unit tests

Test pure Rust helpers, route matching, and redirect validation without HTTP. The resuma crate includes unit tests for match_route, cache merge, CSP nonce injection, and validate_redirect_path.

Render snapshots

use resuma::{render_view, PageOptions};

#[test]
fn counter_markup() {
    let html = render_view(&PageOptions::default(), || {
        view! { <button>"+1"</button> }
    });
    assert!(html.contains("button"));
}

End-to-end

See E2E testing for Playwright against a running resuma dev server. Assert on SSR HTML, then click to verify resumable handlers load.

What we don't ship yet

There is no Leptos-style in-process component mount harness. For UI regressions, prefer HTTP/E2E tests or snapshot render_view output.