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

```rust
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`