restxst 0.0.1

REST-first end-to-end / black-box API testing for Rust
Documentation

restxst

REST-first end-to-end / black-box API testing for Rust.

restxst is intentionally specialized for REST APIs. It focuses on composable multi-step flows, captured response data, and clear failure diagnostics without trying to be a multi-protocol framework.

Scope

  • REST/HTTP integration testing via reqwest
  • Step-based test orchestration (TestBuilder)
  • Shared state between steps (Store, Resources)
  • Reusable setup recipes (ContextRegistry)
  • Custom async steps for non-HTTP assertions/side effects

Quick start

use reqwest::StatusCode;
use restxst::{ClientConfig, ClientRegistry, HttpStepBuilder, Resources, Store, TestBuilder, TestState, test::Environment};
use std::collections::HashMap;

struct Env {
    base_url: String,
    clients: ClientRegistry,
}

impl Environment for Env {
    async fn setup(&mut self, _configurations: HashMap<String, String>) -> anyhow::Result<()> {
        self.clients.register(
            "default",
            ClientConfig::new(self.base_url.clone(), reqwest::Client::new()),
        );
        Ok(())
    }

    async fn teardown(&self) -> anyhow::Result<()> {
        Ok(())
    }

    fn state(&self) -> TestState {
        TestState {
            clients: self.clients.clone(),
            store: Store::default(),
            resources: Resources::default(),
        }
    }
}

async fn run_flow(base_url: String) -> anyhow::Result<()> {
    let token_key = restxst::StoreKey::global("token");

    TestBuilder::new()
        .setup_step(
            HttpStepBuilder::new()
                .client("default")
                .post("/auth/login")
                .json(serde_json::json!({
                    "email": "user@example.com",
                    "password": "password"
                }))
                .expect_status(StatusCode::OK)
                .capture_json("/token", token_key.clone())
                .build()?,
        )
        .step(
            HttpStepBuilder::new()
                .client("default")
                .bearer_from(token_key)
                .get("/me")
                .expect_status(StatusCode::OK)
                .build()?,
        )
        .environment(Env {
            base_url,
            clients: ClientRegistry::default(),
        })
        .build()?
        .run()
        .await?;

    Ok(())
}

Minimal principles

  • Always set explicit expectations (expect_status, JSON expectations, cookies).
  • Prefer small reusable contexts for setup flows.
  • Keep custom steps focused; use HTTP expectations whenever possible.
  • Avoid speculative features: add only what your REST tests need.

Examples

  • examples/basic_rest_flow.rs
  • examples/context_flow.rs