Simple Inventory API Testing

Basic inventory API testing for stock management, updates, and availability checks

LoadForge can record your browser, graphically build tests, scan your site with a wizard and more. Sign up now to run your first test.

Sign up now


This guide shows how to test inventory management APIs with common operations like checking stock, updating inventory, and managing product availability.

Use Cases

  • Test inventory stock level checking
  • Validate inventory updates and adjustments
  • Test low stock alerts and notifications
  • Check inventory synchronization across systems

Simple Implementation

from locust import task, HttpUser
import random
import json

class InventoryTestUser(HttpUser):
    def on_start(self):
        # Sample product data for testing
        self.products = [
            {"id": "PROD001", "sku": "LAPTOP-HP-001", "name": "HP Laptop"},
            {"id": "PROD002", "sku": "PHONE-IPH-001", "name": "iPhone 13"},
            {"id": "PROD003", "sku": "HEADP-SON-001", "name": "Sony Headphones"},
            {"id": "PROD004", "sku": "TABLET-IPD-001", "name": "iPad Pro"},
            {"id": "PROD005", "sku": "WATCH-APL-001", "name": "Apple Watch"}
        ]
        
        # Inventory operations
        self.operations = ["restock", "adjustment", "sale", "return"]
        
        # API endpoints
        self.inventory_endpoints = {
            "check": "/api/inventory/check",
            "update": "/api/inventory/update",
            "bulk": "/api/inventory/bulk-update",
            "alerts": "/api/inventory/alerts"
        }

    @task(4)
    def test_check_inventory(self):
        """Test checking inventory levels"""
        product = random.choice(self.products)
        
        params = {
            "sku": product["sku"],
            "location": random.choice(["warehouse_1", "store_001", "online"])
        }
        
        with self.client.get(
            self.inventory_endpoints["check"],
            params=params,
            name="Check Inventory"
        ) as response:
            if response.status_code == 200:
                try:
                    inventory = response.json()
                    
                    available = inventory.get("available", 0)
                    reserved = inventory.get("reserved", 0)
                    total = inventory.get("total", 0)
                    
                    print(f"Inventory check {product['sku']}: {available}/{total} available")
                    
                    # Validate inventory data
                    if available < 0:
                        response.failure("Negative available inventory")
                    
                except json.JSONDecodeError:
                    response.failure("Invalid JSON response")
            elif response.status_code == 404:
                print(f"Product not found: {product['sku']}")
            else:
                response.failure(f"Inventory check failed: {response.status_code}")

    @task(3)
    def test_update_inventory(self):
        """Test updating inventory levels"""
        product = random.choice(self.products)
        operation = random.choice(self.operations)
        
        # Generate appropriate quantity based on operation
        if operation == "restock":
            quantity = random.randint(10, 100)
        elif operation == "sale":
            quantity = -random.randint(1, 5)
        elif operation == "return":
            quantity = random.randint(1, 3)
        else:  # adjustment
            quantity = random.randint(-10, 10)
        
        update_data = {
            "sku": product["sku"],
            "quantity": quantity,
            "operation": operation,
            "location": "warehouse_1",
            "reason": f"Test {operation} operation"
        }
        
        with self.client.post(
            self.inventory_endpoints["update"],
            json=update_data,
            name="Update Inventory"
        ) as response:
            if response.status_code == 200:
                try:
                    result = response.json()
                    new_quantity = result.get("new_quantity", 0)
                    
                    print(f"Inventory updated {product['sku']}: {operation} {quantity}, new total: {new_quantity}")
                    
                    # Validate update
                    if new_quantity < 0 and operation != "adjustment":
                        print(f"Warning: Negative inventory after {operation}")
                    
                except json.JSONDecodeError:
                    response.failure("Invalid JSON response")
            elif response.status_code == 400:
                print(f"Invalid inventory update: {operation} {quantity}")
            elif response.status_code == 409:
                print(f"Inventory conflict: insufficient stock for {operation}")
            else:
                response.failure(f"Inventory update failed: {response.status_code}")

    @task(2)
    def test_bulk_inventory_update(self):
        """Test bulk inventory updates"""
        # Select 2-3 products for bulk update
        selected_products = random.sample(self.products, random.randint(2, 3))
        
        bulk_updates = []
        for product in selected_products:
            bulk_updates.append({
                "sku": product["sku"],
                "quantity": random.randint(5, 50),
                "operation": "restock",
                "location": "warehouse_1"
            })
        
        bulk_data = {
            "updates": bulk_updates,
            "batch_id": f"BATCH_{random.randint(1000, 9999)}"
        }
        
        with self.client.post(
            self.inventory_endpoints["bulk"],
            json=bulk_data,
            name="Bulk Inventory Update"
        ) as response:
            if response.status_code == 200:
                try:
                    result = response.json()
                    
                    processed = result.get("processed", 0)
                    failed = result.get("failed", 0)
                    batch_id = result.get("batch_id")
                    
                    print(f"Bulk update: {processed} processed, {failed} failed (batch: {batch_id})")
                    
                    if failed > 0:
                        print(f"Some bulk updates failed: {failed}/{len(bulk_updates)}")
                    
                except json.JSONDecodeError:
                    response.failure("Invalid JSON response")
            else:
                response.failure(f"Bulk inventory update failed: {response.status_code}")

    @task(2)
    def test_inventory_availability(self):
        """Test inventory availability checking"""
        product = random.choice(self.products)
        requested_quantity = random.randint(1, 10)
        
        availability_params = {
            "sku": product["sku"],
            "quantity": requested_quantity,
            "location": random.choice(["warehouse_1", "store_001", "all"])
        }
        
        with self.client.get(
            f"{self.inventory_endpoints['check']}/availability",
            params=availability_params,
            name="Check Availability"
        ) as response:
            if response.status_code == 200:
                try:
                    availability = response.json()
                    
                    available = availability.get("available", False)
                    can_fulfill = availability.get("can_fulfill", 0)
                    locations = availability.get("locations", [])
                    
                    print(f"Availability {product['sku']}: {can_fulfill}/{requested_quantity} available")
                    
                    if not available and can_fulfill > 0:
                        print(f"Inconsistent availability data")
                    
                except json.JSONDecodeError:
                    response.failure("Invalid JSON response")
            else:
                response.failure(f"Availability check failed: {response.status_code}")

    @task(1)
    def test_low_stock_alerts(self):
        """Test low stock alert system"""
        with self.client.get(
            self.inventory_endpoints["alerts"],
            params={"threshold": random.choice([5, 10, 20])},
            name="Low Stock Alerts"
        ) as response:
            if response.status_code == 200:
                try:
                    alerts = response.json()
                    
                    if isinstance(alerts, dict):
                        items = alerts.get("alerts", alerts.get("items", []))
                    else:
                        items = alerts if isinstance(alerts, list) else []
                    
                    print(f"Low stock alerts: {len(items)} products below threshold")
                    
                    # Validate alert data
                    for alert in items[:3]:  # Check first 3 alerts
                        if isinstance(alert, dict):
                            sku = alert.get("sku")
                            current_stock = alert.get("current_stock", 0)
                            threshold = alert.get("threshold", 0)
                            
                            if current_stock > threshold:
                                print(f"Invalid alert: {sku} stock {current_stock} > threshold {threshold}")
                    
                except json.JSONDecodeError:
                    response.failure("Invalid JSON response")
            else:
                response.failure(f"Low stock alerts failed: {response.status_code}")

    @task(1)
    def test_inventory_reservation(self):
        """Test inventory reservation for orders"""
        product = random.choice(self.products)
        reserve_quantity = random.randint(1, 5)
        
        reservation_data = {
            "sku": product["sku"],
            "quantity": reserve_quantity,
            "order_id": f"ORDER_{random.randint(10000, 99999)}",
            "expires_in": 900  # 15 minutes
        }
        
        with self.client.post(
            f"{self.inventory_endpoints['update']}/reserve",
            json=reservation_data,
            name="Reserve Inventory"
        ) as response:
            if response.status_code == 200:
                try:
                    result = response.json()
                    
                    reservation_id = result.get("reservation_id")
                    reserved_quantity = result.get("reserved_quantity", 0)
                    expires_at = result.get("expires_at")
                    
                    print(f"Reserved {reserved_quantity} units of {product['sku']} (ID: {reservation_id})")
                    
                    # Test releasing the reservation
                    if reservation_id:
                        self._release_reservation(reservation_id)
                    
                except json.JSONDecodeError:
                    response.failure("Invalid JSON response")
            elif response.status_code == 409:
                print(f"Insufficient inventory to reserve {reserve_quantity} units")
            else:
                response.failure(f"Inventory reservation failed: {response.status_code}")

    def _release_reservation(self, reservation_id):
        """Helper method to release inventory reservation"""
        with self.client.delete(
            f"{self.inventory_endpoints['update']}/reserve/{reservation_id}",
            name="Release Reservation"
        ) as response:
            if response.status_code == 200:
                print(f"Released reservation: {reservation_id}")
            else:
                print(f"Failed to release reservation: {reservation_id}")

Setup Instructions

  1. Replace inventory endpoints with your actual inventory API URLs
  2. Update product data with real SKUs and product information
  3. Adjust location names to match your warehouse/store setup
  4. Configure authentication headers if required by your inventory API

What This Tests

  • Inventory Checking: Tests stock level retrieval and availability
  • Inventory Updates: Tests stock adjustments and operations
  • Bulk Operations: Tests batch inventory updates
  • Availability Checks: Tests product availability validation
  • Low Stock Alerts: Tests inventory monitoring and alerts
  • Reservations: Tests inventory reservation and release

Best Practices

  • Use realistic product SKUs and inventory operations
  • Test both positive and negative inventory adjustments
  • Validate inventory consistency across operations
  • Monitor performance with bulk operations
  • Test edge cases like negative inventory and conflicts

Common Issues

  • Concurrency: Multiple updates to same SKU may cause conflicts
  • Negative Inventory: Some systems allow, others don't
  • Location Sync: Multi-location inventory may have sync delays
  • Reservation Expiry: Test reservation timeout handling

This guide provides comprehensive inventory management testing patterns for e-commerce and retail applications with proper stock tracking and warehouse operations. 

Ready to run your test?
Start your first test within minutes.