#web-api #http

tanu

tanu - High-performance and async-friendly WebAPI testing framework for Rust

14 releases (7 breaking)

new 0.8.2 Jul 16, 2025
0.7.1 Jun 20, 2025
0.3.1 Mar 17, 2025

#249 in Testing

Download history 111/week @ 2025-03-27 382/week @ 2025-04-03 119/week @ 2025-04-10 422/week @ 2025-04-17 229/week @ 2025-04-24 136/week @ 2025-05-01 333/week @ 2025-05-08 134/week @ 2025-05-15 98/week @ 2025-05-22 225/week @ 2025-05-29 127/week @ 2025-06-05 72/week @ 2025-06-12 374/week @ 2025-06-19 122/week @ 2025-06-26 300/week @ 2025-07-03 460/week @ 2025-07-10

1,273 downloads per month

Apache-2.0

240KB
4K SLoC

tanu

Crates.io Documentation License

High-performance, async-friendly and ergonomic WebAPI testing framework for Rust.

Overview

tanu is the main crate for the tanu WebAPI testing framework. It provides a complete solution for testing REST APIs with a focus on performance, ergonomics, and type safety.

Key Features

  • Fast and Lightweight - Leverages Rust's zero-cost abstractions for minimal overhead
  • Type-Safe and Ergonomic - Takes advantage of Rust's strong type system to prevent errors at compile time
  • Async/Await Native - Full support for async operations without boilerplate
  • Concurrent Execution - Built-in support for running tests concurrently
  • Parameterized Testing - Test multiple scenarios with different inputs
  • Interactive TUI - Beautiful terminal UI for test execution and monitoring
  • CLI Interface - Simple command-line interface for CI/CD integration
  • Allure Integration - Generate beautiful HTML test reports

Quick Start

Installation

Add tanu to your Cargo.toml:

[dependencies]
tanu = "0.8.2"
tokio = { version = "1", features = ["full"] }
eyre = "0.6"

Basic Usage

use tanu::{check, check_eq, http::Client};

#[tanu::test]
async fn get_user_profile() -> eyre::Result<()> {
    let client = Client::new();

    let response = client
        .get("https://api.example.com/users/123")
        .header("authorization", "Bearer token123")
        .send()
        .await?;

    check!(response.status().is_success(), "Expected successful response");

    let user: serde_json::Value = response.json().await?;
    check_eq!(123, user["id"].as_i64().unwrap());
    check_eq!("John Doe", user["name"].as_str().unwrap());

    Ok(())
}

#[tanu::test(200)]
#[tanu::test(404)]
#[tanu::test(500)]
async fn test_status_codes(expected_status: u16) -> eyre::Result<()> {
    let client = Client::new();
    let response = client
        .get(&format!("https://httpbin.org/status/{expected_status}"))
        .send()
        .await?;

    check_eq!(expected_status, response.status().as_u16());
    Ok(())
}

#[tanu::main]
#[tokio::main]
async fn main() -> eyre::Result<()> {
    let runner = tanu::run();
    let app = tanu::App::new();
    app.run(runner).await
}

Running Tests

Run your tests with:

cargo run

Or use the TUI mode for interactive testing:

cargo run -- tui

CLI Options

Usage: your-test-binary [OPTIONS]

Options:
  -c, --config <FILE>     Configuration file path [default: tanu.toml]
  -p, --project <NAME>    Project name to run
  -t, --test <PATTERN>    Test name pattern to run
  tui                     Launch interactive TUI mode
      --parallel <N>      Number of parallel test executions
      --timeout <SECS>    Global timeout for test execution
  -h, --help              Print help information
  -V, --version           Print version information

Configuration

Create a tanu.toml file to configure your tests:

[[projects]]
name = "api-tests"
test_ignore = ["slow_test", "flaky_test"]

[projects.retry]
count = 3
factor = 2.0
jitter = true
delays = ["1s", "2s", "5s"]

[projects.tui.payload.color_theme]
keyword = "blue"
string = "green"
number = "yellow"
boolean = "magenta"
null = "red"

HTTP Client Features

The HTTP client supports:

  • JSON Support - Automatic JSON serialization/deserialization
  • Form Data - URL-encoded and multipart form data
  • Headers - Easy header management
  • Cookies - Session management with cookie jars
  • Compression - gzip, deflate, brotli, zstd support
  • Timeouts - Configurable request timeouts
  • Retries - Automatic retry with backoff strategies

Advanced HTTP Examples

use tanu::{check, check_eq, http::Client};

#[tanu::test]
async fn post_json_data() -> eyre::Result<()> {
    let client = Client::new();
    let payload = serde_json::json!({
        "name": "John Doe",
        "email": "john@example.com"
    });

    let response = client
        .post("https://api.example.com/users")
        .header("content-type", "application/json")
        .json(&payload)
        .send()
        .await?;

    check_eq!(201, response.status().as_u16());
    Ok(())
}

#[tanu::test]
async fn upload_file() -> eyre::Result<()> {
    let client = Client::new();
    
    let form = reqwest::multipart::Form::new()
        .text("name", "document.pdf")
        .file("file", "/path/to/document.pdf")
        .await?;

    let response = client
        .post("https://api.example.com/upload")
        .multipart(form)
        .send()
        .await?;

    check!(response.status().is_success());
    Ok(())
}

Assertion Macros

Tanu provides ergonomic assertion macros:

use tanu::{check, check_eq, check_ne, check_str_eq};

// Basic boolean assertion
check!(response.status().is_success(), "Request should succeed");

// Equality assertions
check_eq!(200, response.status().as_u16());
check_ne!(404, response.status().as_u16());

// String equality (with better error messages)
check_str_eq!("application/json", response.headers()["content-type"]);

Features

Enable optional features based on your needs:

[dependencies]
tanu = { version = "0.8.1", features = ["json", "multipart", "cookies"] }
  • json - JSON request/response support
  • multipart - Multipart form data support
  • cookies - Cookie jar support for session management

Architecture

The tanu framework consists of several crates:

  • tanu - Main crate with CLI and application logic
  • tanu-core - Core HTTP client, assertions, and test runner
  • tanu-derive - Procedural macros for test discovery
  • tanu-tui - Interactive terminal UI

Examples

Check out the examples directory for more comprehensive examples including:

  • REST API testing
  • Authentication flows
  • File uploads
  • Performance testing

Contributing

Contributions are welcome! Please see the contributing guide for details.

License

Licensed under the Apache License 2.0 - see the LICENSE file for details.

Dependencies

~36–53MB
~754K SLoC