Native Shell
Native Shell:AI 生成的 UI,在你的應用中原生呈現,涵蓋每個平台。iOS、Android、macOS、Windows 與 Linux 上的應用、GPUI 應用與網頁在執行時載入已簽名、沙箱隔離的 TSX 模組並繪製 th
AI 翻譯
High-performance, async-friendly and ergonomic WebAPI testing framework for Rust
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗tanu is a framework for writing end-to-end tests against HTTP, gRPC, and GraphQL APIs in plain Rust. Tests are ordinary async functions; tanu discovers them at compile time, runs them concurrently, and gives you a CLI and an interactive TUI to run and inspect them.
async fn with #[tanu::test]; no harness boilerplate.#[tanu::test(args...)] attributes to generate one test case per input.serial groups and ordered modules when you need sequencing.check!, check_eq!, check_ne!, check_str_eq! with colored diffs.dev, staging, and production from one tanu.toml.Create a binary crate and add tanu with tokio:
cargo new my-api-tests
cd my-api-tests
cargo add tanu
cargo add tokio --features full
Replace src/main.rs with:
use tanu::{check, check_eq, eyre, http::Client};
#[tanu::test]
async fn get_returns_200() -> eyre::Result<()> {
let http = Client::new();
let res = http.get("https://httpbin.org/get").send().await?;
check!(res.status().is_success(), "unexpected status: {}", res.status());
Ok(())
}
// One test case is generated per attribute.
#[tanu::test(200)]
#[tanu::test(404)]
#[tanu::test(500)]
async fn status_codes(expected: u16) -> eyre::Result<()> {
let http = Client::new();
let res = http
.get(format!("https://httpbin.org/status/{expected}"))
.send()
.await?;
check_eq!(expected, res.status().as_u16());
Ok(())
}
#[tanu::main]
#[tokio::main]
async fn main() -> eyre::Result<()> {
let runner = run();
let app = tanu::App::new();
app.run(runner).await?;
Ok(())
}
Run the tests:
cargo run -- test # run all tests in CLI mode
cargo run -- test --capture-http # also print HTTP requests/responses
cargo run -- tui # interactive terminal UI
cargo run -- ls # list discovered tests
✓ 1 [default] my_api_tests::get_returns_200 (412.08ms)
✓ 2 [default] my_api_tests::status_codes::200 (398.51ms)
✓ 3 [default] my_api_tests::status_codes::404 (401.77ms)
✓ 4 [default] my_api_tests::status_codes::500 (405.12ms)
Tests: 4 passed, 0 failed, 4 total
See the Getting Started guide for a full walkthrough.
Projects in tanu.toml let you run the same tests against several environments. Arbitrary keys are available to tests through tanu::get_config():
[runner]
capture_http = "on-failure"
concurrency = 8
[[projects]]
name = "staging"
base_url = "https://staging.api.example.com"
retry.count = 3
[[projects]]
name = "production"
base_url = "https://api.example.com"
test_ignore = ["my_api_tests::destructive::delete_account"]
#[tanu::test]
async fn health() -> eyre::Result<()> {
let base_url = tanu::get_config().get_str("base_url")?.to_string();
let res = Client::new().get(format!("{base_url}/health")).send().await?;
check!(res.status().is_success());
Ok(())
}
Values can also come from environment variables or a .env file (TANU_API_KEY, TANU_STAGING_API_KEY). See Configuration.
| Feature | Default | Description |
|---|---|---|
native-tls | ✓ | TLS via the platform's native stack |
rustls-tls-webpki-roots | TLS via rustls with bundled Mozilla roots (use with default-features = false) | |
rustls-tls-native-roots | TLS via rustls with the OS certificate store (use with default-features = false) | |
json | RequestBuilder::json for sending JSON bodies (Response::json is always available) | |
cookies | Response::cookies | |
grpc | gRPC call capture for tonic channels | |
graphql | GraphQL request builder (enables json) |
[dependencies]
tanu = { version = "0.22", features = ["json", "cookies"] }
The CLI runs tests and prints results in your terminal.
The TUI lets you run tests and inspect HTTP calls interactively.
Failures come with colored backtraces from color-eyre.
Test reports with tanu-allure.
| Topic | |
|---|---|
| Getting Started | Install tanu and write your first test |
| Test Attributes | #[tanu::test], parameterized tests, serial groups |
| Ordered Execution | Run a module's tests in source order |
| Assertions | check! and friends |
| gRPC / GraphQL | Protocol-specific testing |
| Configuration | tanu.toml, env vars, retries, masking |
| Command Line Options | test, tui, ls |
| Reporters | Custom reporters and Allure |
| FAQ | Common questions and troubleshooting |
As a long-time backend engineer, I wanted API tests that were fast, type-safe, and written in the same language as the services they test. The tools I tried each fell short:
#[test] with tokio, test-case, and reqwest works, but lacks the structure needed at scale: multiple environments, request capture, retries, reporting, and a way to browse results.tanu aims to be a dedicated framework for that job while staying plain Rust.
Issues and pull requests are welcome. To work on tanu itself:
cargo build --workspace
cargo test --workspace
cargo run -p tanu-integration-tests -- test # requires Docker (httpbin container)
mkdocs serve # preview the documentation site
See CLAUDE.md for the full pre-PR checklist (fmt, clippy for both TLS backends, builds, integration tests) and commit conventions.
Thanks to all the amazing people who have contributed to making tanu better! Every contribution, big or small, helps build a more robust and feature-rich testing framework for the Rust community ✨
Made with contrib.rocks.
We're grateful to our sponsors who support the development of tanu:
Your support helps make tanu better for everyone. Thank you! 🙏
Licensed under the Apache License 2.0.