A beerest é uma lib de testes de API que combina simplicidade, robustez e elegância, oferecendo uma experiência fluente de escrita de testes.
Project description
beerest: A Modern API Testing Framework for Python
Overview
beerest is a powerful, fluent Python library designed to simplify API testing while providing robust validation capabilities. It combines a clean, chainable syntax with comprehensive testing features to make API testing more intuitive and maintainable.
Features
- Fluent, chainable API for building requests
- Rich assertion library for response validation
- Built-in authentication support (Basic, Digest, Bearer Token)
- JSON Schema validation
- Response time assertions
- Custom validation functions
- JSONPath support for precise data access
Installation
pip install beerest
Quick Start
Basic Example
from beerest import Test, Expect
class TestAPI(Test):
def setup_method(self):
super().setup_method()
self.request.base_url = "https://api.example.com"
def test_get_user(self):
response = self.request.to("/users/1").get()
Expect(response) \
.status(200) \
.is_json() \
.body("name").equals("John Doe") \
.body("age").greater_than(18)
Core Components
Request Builder
Build HTTP requests with a fluent interface:
response = (request
.to("/api/users") # Set endpoint
.with_headers({"Content-Type": "application/json"}) # Add headers
.with_body({"name": "John"}) # Set request body
.with_query({"active": True}) # Add query parameters
.with_timeout(5.0) # Set timeout
.post() # Send request
)
Authentication Support
Multiple authentication methods available:
# Bearer Token
request.with_bearer_token("your-token")
# Basic Auth
request.with_basic_auth("username", "password")
# Digest Auth
request.with_digest_auth("username", "password")
# Custom Authentication
request.with_custom_auth(MyCustomAuth())
Response Validation
Comprehensive response validation with the Expect class:
Expect(response) \
.status(200) \
.body("data.users").has_type("array") \
.body("data.users").has_length(5) \
.body("metadata.total").greater_than(0) \
.header("Content-Type").contains("application/json") \
.time().less_than(500)
Schema Validation
Validate response structure against JSON schemas:
user_schema = {
"type": "object",
"required": ["id", "name", "email"],
"properties": {
"id": {"type": "integer"},
"name": {"type": "string"},
"email": {"type": "string"},
"age": {"type": "integer"}
}
}
Expect(response) \
.body() \
.matches_schema(user_schema)
Custom Validations
Create custom validation rules:
Expect(response) \
.body("users") \
.satisfies(
lambda users: all(user["age"] >= 18 for user in users),
"All users must be adults"
)
Advanced Features
JSONPath Support
Access nested data using JSONPath expressions:
Expect(response) \
.body("$.data[?(@.type=='user')].name") \
.contains("John")
Response Time Assertions
Monitor API performance:
Expect(response) \
.time() \
.less_than(500) # Response time under 500ms
Format Validation
Built-in format validators:
Expect(response) \
.body("email").matches_schema({"type": "string", "format": "email"}) \
.body("created_at").matches_schema({"type": "string", "format": "date-time-iso"}) \
.body("id").matches_schema({"type": "string", "format": "uuid"})
Best Practices
-
Test Organization
- Group related tests in test classes
- Use descriptive test method names
- Set up common configuration in
setup_method()
-
Request Structure
- Chain request methods for readability
- Set base URL in setup
- Use timeout for all requests
-
Assertions
- Use clear, specific assertions
- Chain validations logically
- Include both positive and negative tests
-
Error Handling
- Test error responses
- Validate error messages
- Check edge cases
Example Test Suite
class TestUserAPI(Test):
def setup_method(self):
super().setup_method()
self.request.base_url = "https://api.example.com"
def test_create_user(self):
"""Test user creation with valid data"""
user_data = {
"name": "John Doe",
"email": "john@example.com",
"age": 25
}
response = self.request \
.to("/users") \
.with_headers({"Content-Type": "application/json"}) \
.with_body(user_data) \
.post()
Expect(response) \
.status(201) \
.body("id").is_not_empty() \
.body("name").equals(user_data["name"]) \
.body("email").equals(user_data["email"])
def test_get_user_not_found(self):
"""Test handling of non-existent user"""
response = self.request.to("/users/999999").get()
Expect(response) \
.status(404) \
.body("error").equals("User not found")
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file beerest-0.3.1.tar.gz.
File metadata
- Download URL: beerest-0.3.1.tar.gz
- Upload date:
- Size: 14.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
032755bde3105d0482a6ed202b3c90a0bbacaea8eca40b78b2be5e31ad63e46a
|
|
| MD5 |
97cb10352ffd26009864361700424a0e
|
|
| BLAKE2b-256 |
48abaa257f1504e6125c1bd2bd31e68fdfa5d32c822ef12ddd641cc1ca9c48e8
|