tanu/lib.rs
1//! # Tanu - High-performance WebAPI Testing Framework
2//!
3//! Tanu is a high-performance, async-friendly, and ergonomic WebAPI testing framework for Rust.
4//! It's designed to be fast, type-safe, and easily extensible with full support for concurrency
5//! and async operations.
6//!
7//! ## Quick Start
8//!
9//! You can install `tanu` and `tokio` by running the following commands in your terminal:
10//! ```bash
11//! cargo add tanu
12//! cargo add tokio --features full
13//! ```
14//!
15//! Write your first test:
16//!
17//! ```rust,no_run
18//! use tanu::{check, eyre, http::Client};
19//!
20//! #[tanu::test]
21//! async fn get_users() -> eyre::Result<()> {
22//! let client = Client::new();
23//! let response = client
24//! .get("https://api.example.com/users")
25//! .send()
26//! .await?;
27//!
28//! check!(response.status().is_success());
29//! Ok(())
30//! }
31//!
32//! #[tanu::main]
33//! #[tokio::main]
34//! async fn main() -> eyre::Result<()> {
35//! let runner = run();
36//! let app = tanu::App::new();
37//! app.run(runner).await?;
38//! Ok(())
39//! }
40//! ```
41//!
42//! ## Key Features
43//!
44//! - **Async/Await Native**: Full support for async operations without boilerplate
45//! - **Type-Safe**: Leverage Rust's type system for robust API testing
46//! - **Ergonomic Assertions**: Use `check!`, `check_eq!`, and other assertion macros
47//! - **Parameterized Testing**: Test multiple scenarios with different inputs
48//! - **Built-in HTTP Client**: No need to set up reqwest or other HTTP clients manually
49//! - **Flexible Error Handling**: Supports `eyre::Result`, `anyhow::Result`, and custom error types
50//! - **TUI Support**: Interactive terminal interface for test execution
51//! - **Concurrent Execution**: Run tests in parallel for better performance
52//!
53//! ## Error Types
54//!
55//! Tanu supports various Result types for flexible error handling:
56//!
57//! - `eyre::Result<()>` (recommended) - Provides colored backtraces and seamless integration
58//! - `anyhow::Result<()>` - Compatible with existing anyhow-based code
59//! - `std::result::Result<(), E>` - Standard Rust Result type with custom error types
60//!
61//! ## Examples
62//!
63//! ### Basic HTTP Test
64//!
65//! ```rust,no_run
66//! use tanu::{check_eq, eyre, http::Client};
67//!
68//! #[tanu::test]
69//! async fn test_api_endpoint() -> eyre::Result<()> {
70//! let client = Client::new();
71//! let response = client
72//! .get("https://httpbin.org/json")
73//! .header("accept", "application/json")
74//! .send()
75//! .await?;
76//!
77//! check_eq!(200, response.status().as_u16());
78//!
79//! let data: serde_json::Value = response.json().await?;
80//! check!(data.is_object());
81//!
82//! Ok(())
83//! }
84//! ```
85//!
86//! ### Parameterized Tests
87//!
88//! ```rust,no_run
89//! use tanu::{check_eq, eyre, http::Client};
90//!
91//! #[tanu::test(200)]
92//! #[tanu::test(404)]
93//! #[tanu::test(500)]
94//! async fn test_status_codes(expected_status: u16) -> eyre::Result<()> {
95//! let client = Client::new();
96//! let response = client
97//! .get(&format!("https://httpbin.org/status/{expected_status}"))
98//! .send()
99//! .await?;
100//!
101//! check_eq!(expected_status, response.status().as_u16());
102//! Ok(())
103//! }
104//! ```
105
106mod app;
107
108// Re-export procedural macros for test and main attributes
109pub use tanu_derive::{main, test};
110
111// Re-export error handling crates for user convenience
112pub use anyhow;
113pub use eyre;
114pub use inventory;
115pub use pretty_assertions;
116
117// Re-export main application struct
118pub use app::App;
119
120// Re-export core functionality
121pub use tanu_core::{
122 assertion,
123 config::{get_config, get_tanu_config, Config, ProjectConfig},
124 http,
125 reporter::{ListReporter, NullReporter, Reporter, ReporterType, TableReporter},
126 runner::{self, scope_current, Runner, TestInfo},
127 {check, check_eq, check_ne, check_str_eq},
128};
129
130// Type alias for the async test function
131pub type AsyncTestFn =
132 fn() -> std::pin::Pin<Box<dyn std::future::Future<Output = eyre::Result<()>> + Send + 'static>>;
133
134// Define the test registration structure for inventory
135pub struct TestRegistration {
136 pub module: &'static str,
137 pub name: &'static str,
138 pub test_fn: AsyncTestFn,
139}
140
141// Collect tests using inventory
142inventory::collect!(TestRegistration);