Examples
Real-world examples and use cases demonstrating NOIV's capabilities across different scenarios and industries.
Getting Started Examples
Simple API Health Check
bash
# Quick health check
noiv quick https://api.github.com/
yaml
# health_check.yaml
name: API Health Check
base_url: https://api.example.com
tests:
- name: Health Endpoint
request:
method: GET
path: /health
expect:
status: 200
body:
status: "healthy"
bash
# Run the health check
noiv test health_check.yaml
Your First API Test
yaml
# first_test.yaml
name: My First API Test
base_url: https://jsonplaceholder.typicode.com
tests:
- name: Get User
request:
method: GET
path: /users/1
expect:
status: 200
body:
id: 1
name: "Leanne Graham"
email: "Sincere@april.biz"
E-commerce API Examples
Product Catalog Testing
yaml
# ecommerce_catalog.yaml
name: E-commerce Product Catalog Tests
base_url: https://shop-api.example.com
version: "1.0"
environments:
staging:
base_url: https://staging-shop.example.com
variables:
api_key: "staging-key-123"
production:
base_url: https://shop-api.example.com
variables:
api_key: "{{PROD_API_KEY}}"
variables:
product_id: ""
category_id: "electronics"
auth_token: ""
setup:
- name: Authenticate API Client
request:
method: POST
path: /auth/token
body:
client_id: "api-client"
client_secret: "{{api_key}}"
expect:
status: 200
extract:
auth_token: "$.access_token"
tests:
- name: Search Products by Category
request:
method: GET
path: /products/search
headers:
Authorization: "Bearer {{auth_token}}"
query:
category: "{{category_id}}"
limit: 20
sort: "popularity"
expect:
status: 200
body:
products: {"type": "array"}
total: {"type": "number"}
pagination:
page: 1
limit: 20
assert:
- jsonpath: "$.products.length"
condition: "lte"
value: 20
- jsonpath: "$.products[*].category"
condition: "equals"
value: "electronics"
- name: Get Product Details
request:
method: GET
path: /products/12345
headers:
Authorization: "Bearer {{auth_token}}"
expect:
status: 200
body:
id: "{{product_id}}"
name: {"type": "string"}
price: {"type": "number"}
inventory:
stock: {"type": "number"}
available: true
extract:
product_id: "$.id"
assert:
- jsonpath: "$.price"
condition: "gte"
value: 0
- jsonpath: "$.inventory.stock"
condition: "gte"
value: 0
- name: Add Product to Cart
request:
method: POST
path: /cart/items
headers:
Authorization: "Bearer {{auth_token}}"
Content-Type: application/json
body:
product_id: "{{product_id}}"
quantity: 2
expect:
status: 201
body:
cart_item_id: {"type": "string"}
total_items: {"type": "number"}
total_price: {"type": "number"}
- name: Calculate Shipping Options
request:
method: POST
path: /shipping/calculate
headers:
Authorization: "Bearer {{auth_token}}"
Content-Type: application/json
body:
items:
- product_id: "{{product_id}}"
quantity: 2
destination:
country: "US"
postal_code: "10001"
expect:
status: 200
body:
options: {"type": "array"}
assert:
- jsonpath: "$.options.length"
condition: "gte"
value: 1
- jsonpath: "$.options[*].price"
condition: "gte"
value: 0
teardown:
- name: Clear Cart
request:
method: DELETE
path: /cart
headers:
Authorization: "Bearer {{auth_token}}"
expect:
status: 204
Complete Checkout Flow
yaml
# checkout_flow.yaml
name: Complete E-commerce Checkout Flow
base_url: https://shop-api.example.com
variables:
user_email: "test@example.com"
product_id: "laptop-001"
cart_id: ""
order_id: ""
payment_token: ""
tests:
- name: User Registration
request:
method: POST
path: /auth/register
body:
email: "{{user_email}}"
password: "SecurePass123"
name: "Test User"
expect:
status: 201
body:
user_id: {"type": "string"}
email: "{{user_email}}"
- name: User Login
depends_on: "User Registration"
request:
method: POST
path: /auth/login
body:
email: "{{user_email}}"
password: "SecurePass123"
expect:
status: 200
body:
access_token: {"type": "string"}
expires_in: 3600
extract:
auth_token: "$.access_token"
- name: Browse Product Catalog
depends_on: "User Login"
request:
method: GET
path: /products
headers:
Authorization: "Bearer {{auth_token}}"
query:
category: "laptops"
in_stock: true
expect:
status: 200
body:
products: {"type": "array"}
- name: Add Item to Cart
depends_on: "Browse Product Catalog"
request:
method: POST
path: /cart
headers:
Authorization: "Bearer {{auth_token}}"
body:
product_id: "{{product_id}}"
quantity: 1
expect:
status: 201
body:
cart_id: {"type": "string"}
extract:
cart_id: "$.cart_id"
- name: Apply Discount Code
depends_on: "Add Item to Cart"
request:
method: POST
path: /cart/{{cart_id}}/discount
headers:
Authorization: "Bearer {{auth_token}}"
body:
code: "SAVE10"
expect:
status: 200
body:
discount_applied: true
discount_amount: {"type": "number"}
- name: Calculate Tax and Shipping
depends_on: "Apply Discount Code"
request:
method: POST
path: /cart/{{cart_id}}/calculate
headers:
Authorization: "Bearer {{auth_token}}"
body:
shipping_address:
street: "123 Main St"
city: "New York"
state: "NY"
zip: "10001"
country: "US"
expect:
status: 200
body:
subtotal: {"type": "number"}
tax: {"type": "number"}
shipping: {"type": "number"}
total: {"type": "number"}
- name: Process Payment
depends_on: "Calculate Tax and Shipping"
request:
method: POST
path: /payments/process
headers:
Authorization: "Bearer {{auth_token}}"
body:
cart_id: "{{cart_id}}"
payment_method:
type: "credit_card"
token: "test_card_token_123"
billing_address:
street: "123 Main St"
city: "New York"
state: "NY"
zip: "10001"
country: "US"
expect:
status: 200
body:
payment_id: {"type": "string"}
status: "completed"
extract:
payment_token: "$.payment_id"
- name: Create Order
depends_on: "Process Payment"
request:
method: POST
path: /orders
headers:
Authorization: "Bearer {{auth_token}}"
body:
cart_id: "{{cart_id}}"
payment_id: "{{payment_token}}"
expect:
status: 201
body:
order_id: {"type": "string"}
status: "confirmed"
estimated_delivery: {"type": "string"}
extract:
order_id: "$.order_id"
- name: Send Order Confirmation Email
depends_on: "Create Order"
request:
method: POST
path: /notifications/order-confirmation
headers:
Authorization: "Bearer {{auth_token}}"
body:
order_id: "{{order_id}}"
email: "{{user_email}}"
expect:
status: 202
body:
notification_id: {"type": "string"}
status: "queued"
- name: Track Order Status
depends_on: "Send Order Confirmation Email"
request:
method: GET
path: /orders/{{order_id}}/status
headers:
Authorization: "Bearer {{auth_token}}"
expect:
status: 200
body:
order_id: "{{order_id}}"
status: "confirmed"
tracking_number: {"type": "string"}
REST API CRUD Examples
User Management API
yaml
# user_management.yaml
name: User Management CRUD Operations
base_url: https://api.example.com
version: "2.0"
environments:
development:
base_url: http://localhost:3000
variables:
admin_token: "dev-admin-token"
staging:
base_url: https://staging-api.example.com
variables:
admin_token: "{{STAGING_ADMIN_TOKEN}}"
variables:
user_id: ""
auth_token: ""
test_email: "testuser@example.com"
setup:
- name: Admin Authentication
request:
method: POST
path: /auth/admin/login
body:
username: "admin"
password: "{{admin_token}}"
expect:
status: 200
extract:
auth_token: "$.access_token"
tests:
# CREATE Operations
- name: Create User with Valid Data
request:
method: POST
path: /users
headers:
Authorization: "Bearer {{auth_token}}"
Content-Type: application/json
body:
name: "John Doe"
email: "{{test_email}}"
age: 30
role: "user"
preferences:
newsletter: true
notifications: false
expect:
status: 201
headers:
Content-Type: application/json
Location: "regex:/users/\\d+"
body:
id: "{{user_id}}"
name: "John Doe"
email: "{{test_email}}"
age: 30
role: "user"
created_at: "regex:^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}"
updated_at: "regex:^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}"
response_time_ms: 1000
extract:
user_id: "$.id"
assert:
- jsonpath: "$.preferences.newsletter"
condition: "equals"
value: true
- name: Create User with Duplicate Email
request:
method: POST
path: /users
headers:
Authorization: "Bearer {{auth_token}}"
Content-Type: application/json
body:
name: "Jane Doe"
email: "{{test_email}}" # Same email as previous test
age: 25
expect:
status: 409
body:
error: "Duplicate email address"
code: "EMAIL_EXISTS"
- name: Create User with Invalid Data
request:
method: POST
path: /users
headers:
Authorization: "Bearer {{auth_token}}"
Content-Type: application/json
body:
name: "" # Invalid: empty name
email: "invalid-email" # Invalid: bad email format
age: -5 # Invalid: negative age
expect:
status: 400
body:
errors: {"type": "array"}
assert:
- jsonpath: "$.errors.length"
condition: "gte"
value: 3
# READ Operations
- name: Get User by Valid ID
depends_on: "Create User with Valid Data"
request:
method: GET
path: /users/{{user_id}}
headers:
Authorization: "Bearer {{auth_token}}"
expect:
status: 200
body:
id: "{{user_id}}"
name: "John Doe"
email: "{{test_email}}"
age: 30
role: "user"
assert:
- jsonpath: "$.email"
condition: "matches"
value: "^[\\w.-]+@[\\w.-]+\\.[A-Za-z]{2,}$"
- name: Get User by Invalid ID
request:
method: GET
path: /users/99999
headers:
Authorization: "Bearer {{auth_token}}"
expect:
status: 404
body:
error: "User not found"
code: "USER_NOT_FOUND"
- name: List Users with Pagination
request:
method: GET
path: /users
headers:
Authorization: "Bearer {{auth_token}}"
query:
page: 1
limit: 10
sort: "created_at:desc"
expect:
status: 200
body:
users: {"type": "array"}
pagination:
page: 1
limit: 10
total: {"type": "number"}
pages: {"type": "number"}
assert:
- jsonpath: "$.users.length"
condition: "lte"
value: 10
- jsonpath: "$.pagination.total"
condition: "gte"
value: 1
- name: Search Users by Email
request:
method: GET
path: /users/search
headers:
Authorization: "Bearer {{auth_token}}"
query:
q: "{{test_email}}"
fields: "email"
expect:
status: 200
body:
users: {"type": "array"}
count: {"type": "number"}
assert:
- jsonpath: "$.users[*].email"
condition: "contains"
value: "{{test_email}}"
# UPDATE Operations
- name: Update User with Valid Data
depends_on: "Get User by Valid ID"
request:
method: PUT
path: /users/{{user_id}}
headers:
Authorization: "Bearer {{auth_token}}"
Content-Type: application/json
body:
name: "John Smith"
email: "{{test_email}}"
age: 31
role: "user"
preferences:
newsletter: false
notifications: true
expect:
status: 200
body:
id: "{{user_id}}"
name: "John Smith"
email: "{{test_email}}"
age: 31
updated_at: "regex:^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}"
assert:
- jsonpath: "$.preferences.newsletter"
condition: "equals"
value: false
- name: Partial Update User (PATCH)
depends_on: "Update User with Valid Data"
request:
method: PATCH
path: /users/{{user_id}}
headers:
Authorization: "Bearer {{auth_token}}"
Content-Type: application/json
body:
age: 32
preferences:
notifications: false
expect:
status: 200
body:
id: "{{user_id}}"
name: "John Smith" # Should remain unchanged
age: 32 # Should be updated
assert:
- jsonpath: "$.preferences.notifications"
condition: "equals"
value: false
- name: Update User with Invalid ID
request:
method: PUT
path: /users/99999
headers:
Authorization: "Bearer {{auth_token}}"
Content-Type: application/json
body:
name: "Non-existent User"
email: "test@example.com"
expect:
status: 404
body:
error: "User not found"
# DELETE Operations
- name: Delete User with Valid ID
depends_on: "Partial Update User (PATCH)"
request:
method: DELETE
path: /users/{{user_id}}
headers:
Authorization: "Bearer {{auth_token}}"
expect:
status: 204
# No body expected for 204 No Content
- name: Verify User Deletion
depends_on: "Delete User with Valid ID"
request:
method: GET
path: /users/{{user_id}}
headers:
Authorization: "Bearer {{auth_token}}"
expect:
status: 404
body:
error: "User not found"
- name: Delete User with Invalid ID
request:
method: DELETE
path: /users/99999
headers:
Authorization: "Bearer {{auth_token}}"
expect:
status: 404
body:
error: "User not found"
teardown:
- name: Cleanup Test Data
request:
method: DELETE
path: /admin/cleanup/test-data
headers:
Authorization: "Bearer {{auth_token}}"
body:
email_pattern: "testuser@example.com"
expect:
status: 200
Authentication & Security Examples
JWT Authentication Flow
yaml
# jwt_authentication.yaml
name: JWT Authentication Flow Tests
base_url: https://auth-api.example.com
version: "1.0"
variables:
user_email: "test@example.com"
user_password: "SecurePass123"
access_token: ""
refresh_token: ""
user_id: ""
tests:
- name: User Registration
request:
method: POST
path: /auth/register
headers:
Content-Type: application/json
body:
email: "{{user_email}}"
password: "{{user_password}}"
confirm_password: "{{user_password}}"
name: "Test User"
terms_accepted: true
expect:
status: 201
body:
user_id: "{{user_id}}"
email: "{{user_email}}"
email_verified: false
created_at: {"type": "string"}
extract:
user_id: "$.user_id"
- name: Email Verification
depends_on: "User Registration"
request:
method: POST
path: /auth/verify-email
headers:
Content-Type: application/json
body:
user_id: "{{user_id}}"
verification_token: "test_verification_token"
expect:
status: 200
body:
email_verified: true
message: "Email verified successfully"
- name: User Login with Valid Credentials
depends_on: "Email Verification"
request:
method: POST
path: /auth/login
headers:
Content-Type: application/json
body:
email: "{{user_email}}"
password: "{{user_password}}"
expect:
status: 200
body:
access_token: "{{access_token}}"
refresh_token: "{{refresh_token}}"
token_type: "Bearer"
expires_in: 3600
user:
id: "{{user_id}}"
email: "{{user_email}}"
email_verified: true
extract:
access_token: "$.access_token"
refresh_token: "$.refresh_token"
assert:
- jsonpath: "$.access_token"
condition: "matches"
value: "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+$" # JWT format
- name: User Login with Invalid Password
request:
method: POST
path: /auth/login
headers:
Content-Type: application/json
body:
email: "{{user_email}}"
password: "WrongPassword123"
expect:
status: 401
body:
error: "Invalid credentials"
code: "INVALID_CREDENTIALS"
- name: Access Protected Resource
depends_on: "User Login with Valid Credentials"
request:
method: GET
path: /auth/me
headers:
Authorization: "Bearer {{access_token}}"
expect:
status: 200
body:
id: "{{user_id}}"
email: "{{user_email}}"
name: "Test User"
email_verified: true
- name: Access Protected Resource with Invalid Token
request:
method: GET
path: /auth/me
headers:
Authorization: "Bearer invalid_token_123"
expect:
status: 401
body:
error: "Invalid or expired token"
code: "INVALID_TOKEN"
- name: Refresh Access Token
depends_on: "User Login with Valid Credentials"
request:
method: POST
path: /auth/refresh
headers:
Content-Type: application/json
body:
refresh_token: "{{refresh_token}}"
expect:
status: 200
body:
access_token: {"type": "string"}
token_type: "Bearer"
expires_in: 3600
extract:
access_token: "$.access_token"
- name: Password Reset Request
request:
method: POST
path: /auth/password-reset
headers:
Content-Type: application/json
body:
email: "{{user_email}}"
expect:
status: 200
body:
message: "Password reset email sent"
reset_token_sent: true
- name: Password Reset Confirmation
depends_on: "Password Reset Request"
request:
method: POST
path: /auth/password-reset/confirm
headers:
Content-Type: application/json
body:
reset_token: "test_reset_token"
new_password: "NewSecurePass456"
confirm_password: "NewSecurePass456"
expect:
status: 200
body:
password_reset: true
message: "Password updated successfully"
- name: Login with New Password
depends_on: "Password Reset Confirmation"
request:
method: POST
path: /auth/login
headers:
Content-Type: application/json
body:
email: "{{user_email}}"
password: "NewSecurePass456"
expect:
status: 200
body:
access_token: {"type": "string"}
user:
email: "{{user_email}}"
- name: Logout User
depends_on: "Refresh Access Token"
request:
method: POST
path: /auth/logout
headers:
Authorization: "Bearer {{access_token}}"
Content-Type: application/json
body:
refresh_token: "{{refresh_token}}"
expect:
status: 200
body:
message: "Logged out successfully"
tokens_revoked: true
- name: Verify Logout - Access Revoked
depends_on: "Logout User"
request:
method: GET
path: /auth/me
headers:
Authorization: "Bearer {{access_token}}"
expect:
status: 401
body:
error: "Token has been revoked"
OAuth 2.0 Flow
yaml
# oauth2_flow.yaml
name: OAuth 2.0 Authorization Flow
base_url: https://oauth-provider.example.com
variables:
client_id: "test-client-123"
client_secret: "test-secret-456"
redirect_uri: "https://myapp.example.com/callback"
authorization_code: ""
access_token: ""
refresh_token: ""
tests:
- name: Client Credentials Grant
request:
method: POST
path: /oauth/token
headers:
Content-Type: application/x-www-form-urlencoded
Authorization: "Basic {{base64(client_id:client_secret)}}"
body: "grant_type=client_credentials&scope=read:users"
expect:
status: 200
body:
access_token: {"type": "string"}
token_type: "Bearer"
expires_in: {"type": "number"}
scope: "read:users"
extract:
access_token: "$.access_token"
- name: Authorization Code Exchange
request:
method: POST
path: /oauth/token
headers:
Content-Type: application/x-www-form-urlencoded
body: |
grant_type=authorization_code&
code=test_auth_code_123&
redirect_uri={{redirect_uri}}&
client_id={{client_id}}&
client_secret={{client_secret}}
expect:
status: 200
body:
access_token: {"type": "string"}
refresh_token: {"type": "string"}
token_type: "Bearer"
expires_in: {"type": "number"}
extract:
access_token: "$.access_token"
refresh_token: "$.refresh_token"
- name: Use Access Token
depends_on: "Authorization Code Exchange"
request:
method: GET
path: /api/user/profile
headers:
Authorization: "Bearer {{access_token}}"
expect:
status: 200
body:
user_id: {"type": "string"}
email: {"type": "string"}
- name: Refresh Token Grant
depends_on: "Authorization Code Exchange"
request:
method: POST
path: /oauth/token
headers:
Content-Type: application/x-www-form-urlencoded
body: |
grant_type=refresh_token&
refresh_token={{refresh_token}}&
client_id={{client_id}}&
client_secret={{client_secret}}
expect:
status: 200
body:
access_token: {"type": "string"}
token_type: "Bearer"
expires_in: {"type": "number"}
Performance Testing Examples
Load Testing Scenario
yaml
# load_testing.yaml
name: API Load Testing Scenarios
base_url: https://api.example.com
version: "1.0"
benchmark:
users: 100
duration: 300 # 5 minutes
ramp_up: 60 # 1 minute ramp-up
performance_thresholds:
response_time:
p95_ms: 500
p99_ms: 1000
error_rate:
max_percent: 1
throughput:
min_rps: 50
scenarios:
- name: User Browsing Pattern
weight: 60 # 60% of traffic
tests:
- name: Home Page
request:
method: GET
path: /
expect:
status: 200
response_time_ms: 300
- name: Product Search
request:
method: GET
path: /products/search
query:
q: "laptop"
category: "electronics"
expect:
status: 200
response_time_ms: 500
- name: Product Details
request:
method: GET
path: /products/{{random_product_id}}
expect:
status: 200
response_time_ms: 200
- name: User Account Operations
weight: 30 # 30% of traffic
tests:
- name: Login
request:
method: POST
path: /auth/login
body:
email: "{{random_email}}"
password: "password123"
expect:
status: 200
response_time_ms: 400
- name: View Profile
request:
method: GET
path: /user/profile
headers:
Authorization: "Bearer {{auth_token}}"
expect:
status: 200
response_time_ms: 250
- name: Order Processing
weight: 10 # 10% of traffic
tests:
- name: Add to Cart
request:
method: POST
path: /cart/items
headers:
Authorization: "Bearer {{auth_token}}"
body:
product_id: "{{random_product_id}}"
quantity: 1
expect:
status: 201
response_time_ms: 600
- name: Checkout Process
request:
method: POST
path: /orders
headers:
Authorization: "Bearer {{auth_token}}"
body:
payment_method: "credit_card"
expect:
status: 201
response_time_ms: 1500
Stress Testing
yaml
# stress_test.yaml
name: API Stress Testing
base_url: https://api.example.com
benchmark:
profile: stress
users_start: 50
users_max: 500
increment_step: 25
step_duration: 60
tests:
- name: Critical Endpoint Stress Test
request:
method: GET
path: /api/critical-endpoint
expect:
status: 200
response_time_ms: 2000 # Higher threshold for stress test
- name: Database Heavy Operation
request:
method: POST
path: /api/heavy-query
body:
filters:
date_range: "last_year"
include_analytics: true
expect:
status: 200
response_time_ms: 5000
API Integration Examples
Third-Party Service Integration
yaml
# third_party_integration.yaml
name: Third-Party Service Integration Tests
base_url: https://api.myservice.com
variables:
stripe_token: ""
sendgrid_message_id: ""
aws_s3_url: ""
tests:
- name: Stripe Payment Processing
request:
method: POST
path: /payments/stripe/charge
headers:
Content-Type: application/json
Authorization: "Bearer {{api_key}}"
body:
amount: 2999 # $29.99
currency: "usd"
source: "tok_visa"
description: "Test payment"
expect:
status: 200
body:
id: {"type": "string"}
status: "succeeded"
amount: 2999
currency: "usd"
extract:
stripe_token: "$.id"
- name: SendGrid Email Delivery
request:
method: POST
path: /notifications/email/send
headers:
Content-Type: application/json
Authorization: "Bearer {{api_key}}"
body:
to: "test@example.com"
from: "noreply@myservice.com"
subject: "Test Email"
content: "This is a test email"
template_id: "welcome_template"
expect:
status: 202
body:
message_id: {"type": "string"}
status: "queued"
extract:
sendgrid_message_id: "$.message_id"
- name: AWS S3 File Upload
request:
method: POST
path: /files/upload
headers:
Content-Type: multipart/form-data
Authorization: "Bearer {{api_key}}"
body:
file: "@test_file.jpg"
bucket: "user-uploads"
path: "profile-images/"
expect:
status: 201
body:
url: {"type": "string"}
key: {"type": "string"}
size: {"type": "number"}
extract:
aws_s3_url: "$.url"
assert:
- jsonpath: "$.url"
condition: "matches"
value: "^https://.*\\.s3\\.amazonaws\\.com/.*"
- name: Verify File Upload
depends_on: "AWS S3 File Upload"
request:
method: GET
path: "{{aws_s3_url}}"
expect:
status: 200
headers:
Content-Type: "image/jpeg"
CI/CD Integration Examples
GitHub Actions Integration
yaml
# .github/workflows/api-tests.yml
name: API Tests
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 6 * * *' # Daily at 6 AM
jobs:
api-tests:
runs-on: ubuntu-latest
strategy:
matrix:
environment: [staging, production]
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: Install NOIV
run: pip install noiv
- name: Run Functional Tests
run: |
noiv test tests/functional_tests.yaml \
--environment ${{ matrix.environment }} \
--format junit \
--output functional-results.xml \
--variable api_key=${{ secrets.API_KEY }}
- name: Run Performance Tests
run: |
noiv benchmark tests/performance_tests.yaml \
--users 50 \
--duration 120 \
--environment ${{ matrix.environment }} \
--format json \
--output performance-results.json
- name: Generate HTML Report
if: always()
run: |
noiv report functional-results.xml performance-results.json \
--merge \
--template detailed \
--title "API Test Report - ${{ matrix.environment }}" \
--output api-report-${{ matrix.environment }}.html
- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v3
with:
name: test-results-${{ matrix.environment }}
path: |
functional-results.xml
performance-results.json
api-report-${{ matrix.environment }}.html
- name: Publish Test Results
if: always()
uses: dorny/test-reporter@v1
with:
name: API Tests (${{ matrix.environment }})
path: functional-results.xml
reporter: java-junit
- name: Comment PR with Report
if: github.event_name == 'pull_request'
uses: actions/github-script@v6
with:
script: |
const fs = require('fs');
const reportPath = `api-report-${{ matrix.environment }}.html`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## API Test Report (${{ matrix.environment }})
📊 Test execution completed. View the [detailed report](${reportPath}) for full results.
Environment: ${{ matrix.environment }}
Commit: ${context.sha.substring(0, 7)}
`
});
performance-baseline:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install NOIV
run: pip install noiv
- name: Run Baseline Performance Test
run: |
noiv benchmark tests/baseline_performance.yaml \
--users 100 \
--duration 300 \
--environment production \
--output baseline-$(date +%Y%m%d).json
- name: Store Baseline
run: |
mkdir -p baselines
cp baseline-$(date +%Y%m%d).json baselines/
- name: Commit Baseline
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add baselines/
git commit -m "Update performance baseline [skip ci]" || exit 0
git push
Jenkins Pipeline
groovy
// Jenkinsfile
pipeline {
agent any
parameters {
choice(
name: 'ENVIRONMENT',
choices: ['staging', 'production'],
description: 'Environment to test'
)
choice(
name: 'TEST_SUITE',
choices: ['smoke', 'regression', 'full'],
description: 'Test suite to run'
)
}
environment {
API_KEY = credentials('api-key')
NOIV_VERSION = '0.2.1'
}
stages {
stage('Setup') {
steps {
sh 'pip install noiv==${NOIV_VERSION}'
}
}
stage('Smoke Tests') {
when {
anyOf {
params.TEST_SUITE == 'smoke'
params.TEST_SUITE == 'full'
}
}
steps {
sh '''
noiv test tests/smoke_tests.yaml \
--environment ${ENVIRONMENT} \
--format junit \
--output smoke-results.xml \
--variable api_key=${API_KEY}
'''
}
}
stage('Regression Tests') {
when {
anyOf {
params.TEST_SUITE == 'regression'
params.TEST_SUITE == 'full'
}
}
parallel {
stage('Functional Tests') {
steps {
sh '''
noiv test tests/functional_tests.yaml \
--environment ${ENVIRONMENT} \
--parallel 4 \
--format junit \
--output functional-results.xml \
--variable api_key=${API_KEY}
'''
}
}
stage('Performance Tests') {
steps {
sh '''
noiv benchmark tests/performance_tests.yaml \
--users 50 \
--duration 180 \
--environment ${ENVIRONMENT} \
--format json \
--output performance-results.json
'''
}
}
}
}
stage('Generate Report') {
steps {
sh '''
noiv report *-results.* \
--merge \
--template detailed \
--title "API Test Report - ${ENVIRONMENT}" \
--description "Build ${BUILD_NUMBER} - ${TEST_SUITE} test suite" \
--output api-report.html
'''
}
}
}
post {
always {
// Publish test results
junit testResults: '*-results.xml', allowEmptyResults: true
// Archive artifacts
archiveArtifacts artifacts: '*.html,*.json,*.xml', fingerprint: true
// Publish HTML report
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: '.',
reportFiles: 'api-report.html',
reportName: 'API Test Report'
])
}
failure {
emailext (
subject: "API Tests Failed - ${env.JOB_NAME} #${env.BUILD_NUMBER}",
body: """
API tests have failed for environment: ${params.ENVIRONMENT}
Build: ${env.BUILD_URL}
Test Report: ${env.BUILD_URL}API_Test_Report/
Please check the logs and fix any issues.
""",
to: "${env.CHANGE_AUTHOR_EMAIL ?: 'team@example.com'}"
)
}
success {
script {
if (params.ENVIRONMENT == 'production' && params.TEST_SUITE == 'full') {
// Update performance baseline on successful production tests
sh '''
cp performance-results.json baselines/baseline-$(date +%Y%m%d).json
echo "Updated performance baseline"
'''
}
}
}
}
}
Monitoring & Alerting Examples
Health Check Monitoring
yaml
# health_monitoring.yaml
name: API Health Monitoring
base_url: https://api.example.com
tests:
- name: API Health Check
request:
method: GET
path: /health
expect:
status: 200
response_time_ms: 1000
body:
status: "healthy"
services:
database: "healthy"
cache: "healthy"
external_api: "healthy"
- name: Database Connectivity
request:
method: GET
path: /health/database
expect:
status: 200
response_time_ms: 2000
body:
status: "connected"
response_time_ms: {"type": "number"}
assert:
- jsonpath: "$.response_time_ms"
condition: "lt"
value: 100
- name: External Service Dependencies
request:
method: GET
path: /health/dependencies
expect:
status: 200
body:
payment_gateway: "operational"
email_service: "operational"
analytics: "operational"
bash
#!/bin/bash
# health_check_monitor.sh
# Run health checks every 5 minutes
while true; do
echo "Running health checks at $(date)"
# Run health check tests
noiv test health_monitoring.yaml \
--format json \
--output health_results.json
# Check for failures
FAILED_TESTS=$(jq '.summary.failed' health_results.json)
if [ "$FAILED_TESTS" -gt 0 ]; then
echo "⚠️ Health check failures detected: $FAILED_TESTS"
# Send alert
curl -X POST https://alerts.example.com/api/alert \
-H "Content-Type: application/json" \
-d '{
"level": "warning",
"message": "API health check failures detected",
"details": "'"$(cat health_results.json)"'"
}'
else
echo "✅ All health checks passed"
fi
# Wait 5 minutes
sleep 300
done
These examples demonstrate the versatility and power of NOIV across different scenarios, from simple API testing to complex enterprise workflows. Each example can be customized and extended based on your specific requirements.