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