Skip to main content

API Testing Guide

This guide covers the comprehensive test suite available for testing hlquery API endpoints across all supported client libraries.

Overview

The hlquery project includes a complete test suite with native language tests for each API client library. Each API directory contains tests written in that API's native language:

These tests provide:

  • Comprehensive Coverage: Tests for all major API endpoints
  • Native Language: Each API uses its own client library
  • Easy Execution: Individual test scripts and test runners
  • Real-World Scenarios: Tests that create, use, and clean up test data

Test Structure

Directory Layout

Tests are organized in tests/ subdirectories within each API client directory:

api/
├── python/tests/ # Python API tests (.py files)
├── node/tests/ # Node.js API tests (.js files)
├── php/tests/ # PHP API tests (.php files)
├── perl/tests/ # Perl API tests (.pl files)
├── cpp/tests/ # C++ API tests (.cpp files)
└── rust/tests/ # Rust API tests (.rs files)

Each tests/ directory contains 31 comprehensive test scripts written in that API's native language, covering all aspects of the API, including core functionality, advanced features, error handling, and edge cases.

Note: All Perl, PHP, Python, and Node.js tests are fully implemented with detailed developer comments. See the Perl Tests Guide, PHP Tests Guide, Python Tests Guide, and Node.js Tests Guide for complete documentation.

Important: Each API's tests use that API's own client library:

  • PHP tests use the PHP client (Hlquery\Client)
  • Perl tests use the Perl client (Hlquery::Client)
  • Node.js tests use the Node.js client (Client)
  • C++ tests use the C++ client (hlquery::Client)
  • Rust tests use the Rust client (hlquery_rust_client::Client)

Available Test Scripts

1. test_auth (Authentication Test)

Purpose: Tests authentication functionality

What it tests:

  • Health check without authentication
  • Bearer token authentication
  • API key authentication
  • Token validation

Usage:

# PHP
php api/php/tests/test_auth.php

# Perl
perl api/perl/tests/test_auth.pl

# Node.js
node api/node/tests/test_auth.js

# C++ (compile first)
cd api/cpp && make test_auth && ./build/test_auth

# Rust (compile first)
cd api/rust && cargo build --bin test_auth && cargo run --bin test_auth

Example Output:

----------------------------------------------------------------==============================
TEST: Authentication with Bearer Token
----------------------------------------------------------------------
Health check without auth: 200
Set bearer token: test_tok...
Health check with bearer token: 200
Set API key: test_tok...
Health check with API key: 200
✓ Authentication test completed

2. test_search (Search Test)

Purpose: Comprehensive search functionality testing

What it tests:

  • Basic text search
  • Filtered searches
  • Sorted searches
  • Paginated searches
  • Wildcard searches

Features:

  • Creates test collection with sample data
  • Tests multiple search scenarios
  • Provides detailed pass/fail reporting
  • Automatic cleanup

Usage:

# PHP
php api/php/tests/test_search.php

# Perl
perl api/perl/tests/test_search.pl

# Node.js
node api/node/tests/test_search.js

# C++ (compile first)
cd api/cpp && make test_search && ./build/test_search

# Rust (compile first)
cd api/rust && cargo build --bin test_search && cargo run --bin test_search

3. test_docs_insert (Document Insertion Test)

Purpose: Document insertion and collection creation

What it tests:

  • Creating a new collection with schema
  • Inserting documents into collections
  • Document retrieval verification
  • Collection cleanup

Test Flow:

  1. Creates a test collection with fields: title, content, tags
  2. Inserts a test document with sample data
  3. Verifies the document was inserted correctly
  4. Cleans up the test collection

Usage:

# PHP
php api/php/tests/test_docs_insert.php

# Perl
perl api/perl/tests/test_docs_insert.pl

# Node.js
node api/node/tests/test_docs_insert.js

4. test_search_cols.py

Purpose: Search across multiple collections

What it tests:

  • Listing all available collections
  • Searching within each collection
  • Handling collections with different schemas
  • Multi-collection search scenarios

Usage:

python api/python/tests/test_search_cols.py

5. test_list_all_cols.py

Purpose: Collection listing with pagination

What it tests:

  • Listing all collections
  • Pagination support (offset/limit)
  • Collection metadata display
  • Document count per collection

Features:

  • Displays collection names and document counts
  • Supports pagination parameters
  • Formatted output for easy reading

Usage:

python api/python/tests/test_list_all_cols.py

6. test_create_collection.py

Purpose: Collection creation with various schemas

What it tests:

  • Creating collections with different field types
  • Schema validation
  • Collection retrieval after creation
  • Collection deletion (cleanup)

Schema Types Tested:

  • String fields
  • Float fields
  • String array fields
  • Float array fields (for vectors)

Usage:

python api/python/tests/test_create_collection.py

7. test_get_collection.py

Purpose: Retrieving collection details

What it tests:

  • Getting collection information
  • Retrieving collection fields
  • Formatted field display
  • Error handling for non-existent collections

Usage:

python api/python/tests/test_get_collection.py

8. test_update_document.py

Purpose: Document update operations

What it tests:

  • Updating existing documents
  • Partial updates (updating specific fields)
  • Verifying updates were applied
  • Error handling

Test Flow:

  1. Creates or uses existing collection
  2. Inserts a test document
  3. Updates the document with new data
  4. Verifies the update was successful
  5. Cleans up test data

Usage:

python api/python/tests/test_update_document.py

9. test_delete_document.py

Purpose: Document deletion operations

What it tests:

  • Deleting documents by ID
  • Verifying deletion was successful
  • Error handling for non-existent documents
  • Cleanup procedures

Usage:

python api/python/tests/test_delete_document.py

10. test_vector_search.py

Purpose: Vector similarity search

What it tests:

  • Creating collections with vector fields
  • Inserting documents with embeddings
  • Performing vector similarity searches
  • Vector search parameters (threshold, normalize)

Vector Operations:

  • Creates test collection with float[] embedding field
  • Inserts document with sample vector
  • Performs similarity search with query vector
  • Tests vector search parameters

Usage:

python api/python/tests/test_vector_search.py

11. test_multi_search.py

Purpose: Multi-collection search operations

What it tests:

  • Searching across multiple collections simultaneously
  • Handling different collection schemas
  • Aggregating results from multiple searches
  • Error handling for missing collections

Usage:

python api/python/tests/test_multi_search.py

12. test_health.py

Purpose: System health and monitoring endpoints

What it tests:

  • GET /health - Health check endpoint
  • GET /stats - Server statistics
  • GET /status - Detailed server status
  • GET /metrics - JSON metrics (currently minimal)
  • GET / - Root status response

Usage:

python api/python/tests/test_health.py

13. test_bulk_operations.py

Purpose: Bulk document operations

What it tests:

  • Bulk document import
  • Verifying bulk import results
  • Bulk delete by filter
  • Handling large batches of documents

Test Flow:

  1. Creates test collection
  2. Imports multiple documents in a single operation
  3. Verifies all documents were imported
  4. Tests bulk delete functionality
  5. Cleans up test collection

Usage:

python api/perl/tests/test_bulk_operations.py
python api/php/tests/test_bulk_operations.py
python api/node/tests/test_bulk_operations.py

14. test_synonyms.py

Purpose: Synonym management operations

What it tests:

  • Listing synonyms for a collection
  • Creating/updating synonyms
  • Retrieving specific synonyms
  • Deleting synonyms

Synonym Operations:

  • Creates synonym groups (e.g., car, automobile, vehicle, auto)
  • Tests CRUD operations on synonyms
  • Verifies synonym persistence

Usage:

python api/perl/tests/test_synonyms.py
python api/php/tests/test_synonyms.py
python api/node/tests/test_synonyms.py

15. test_stopwords.py

Purpose: Stopword management operations

What it tests:

  • Listing stopwords for a collection
  • Adding stopwords
  • Deleting stopwords
  • Stopword filtering behavior

Usage:

python api/perl/tests/test_stopwords.py
python api/php/tests/test_stopwords.py
python api/node/tests/test_stopwords.py

16. test_overrides.py

Purpose: Search override management

What it tests:

  • Listing search overrides
  • Creating search overrides with rules
  • Retrieving override details
  • Deleting overrides

Override Features:

  • Tests query matching rules
  • Tests result inclusion/exclusion
  • Verifies override application

Usage:

python api/perl/tests/test_overrides.py
python api/php/tests/test_overrides.py
python api/node/tests/test_overrides.py

17. test_aliases.py

Purpose: Collection alias management

What it tests:

  • Listing all aliases
  • Creating aliases for collections
  • Retrieving alias details
  • Deleting aliases

Alias Operations:

  • Maps aliases to collection names
  • Tests alias resolution
  • Verifies alias persistence

Usage:

python api/perl/tests/test_aliases.py
python api/php/tests/test_aliases.py
python api/node/tests/test_aliases.py

18. test_facets.py

Purpose: Facet counts and aggregation

What it tests:

  • Getting facet counts for fields
  • Facet aggregation across documents
  • Facet filtering
  • Multiple facet fields

Usage:

python api/perl/tests/test_facets.py
python api/php/tests/test_facets.py
python api/node/tests/test_facets.py

19. test_export.py

Purpose: Document export operations

What it tests:

  • Exporting documents from collections
  • Export with filters
  • Export with limits
  • Export data format

Usage:

python api/perl/tests/test_export.py
python api/php/tests/test_export.py
python api/node/tests/test_export.py

20. test_delete_collection.py

Purpose: Collection deletion operations

What it tests:

  • Deleting collections
  • Verifying deletion was successful
  • Error handling for non-existent collections
  • Cleanup verification

Test Flow:

  1. Creates test collection
  2. Verifies collection exists
  3. Deletes the collection
  4. Verifies collection no longer exists

Usage:

python api/perl/tests/test_delete_collection.py
python api/php/tests/test_delete_collection.py
python api/node/tests/test_delete_collection.py

21. test_update_collection.py

Purpose: Collection schema updates

What it tests:

  • Updating collection schemas
  • Adding new fields to collections
  • Modifying existing fields
  • Verifying schema changes

Schema Update Operations:

  • Adds new fields to existing collections
  • Tests field type changes
  • Verifies schema persistence

Usage:

python api/perl/tests/test_update_collection.py
python api/php/tests/test_update_collection.py
python api/node/tests/test_update_collection.py

22. test_error_handling.py

Purpose: Error handling and validation

What it tests:

  • Getting non-existent collections (404 errors)
  • Getting non-existent documents (404 errors)
  • Deleting non-existent resources
  • Invalid schema validation
  • Invalid search parameters

Error Scenarios:

  • Tests proper error codes (400, 404, 422)
  • Validates error message formats
  • Ensures graceful error handling

Usage:

python api/perl/tests/test_error_handling.py
python api/php/tests/test_error_handling.py
python api/node/tests/test_error_handling.py

23. test_edge_cases.py

Purpose: Edge cases and boundary conditions

What it tests:

  • Documents with special characters
  • Empty string values
  • Large limit values
  • Zero limit values
  • Wildcard-only searches

Edge Case Scenarios:

  • Special characters: &, <, >, ", '
  • Empty fields
  • Boundary values
  • Unusual but valid inputs

Usage:

python api/perl/tests/test_edge_cases.py
python api/php/tests/test_edge_cases.py
python api/node/tests/test_edge_cases.py

24. test_data_types.py

Purpose: Data type validation

What it tests:

  • String fields
  • Float fields
  • Integer fields
  • String array fields
  • Float array fields (vectors)

Data Type Coverage:

  • Tests all supported field types
  • Validates type constraints
  • Tests array operations
  • Vector field handling

Usage:

python api/perl/tests/test_data_types.py
python api/php/tests/test_data_types.py
python api/node/tests/test_data_types.py

25. test_pagination.py

Purpose: Pagination with various scenarios

What it tests:

  • First page retrieval
  • Subsequent pages
  • Large offsets
  • Limits larger than total
  • Search pagination

Pagination Scenarios:

  • Tests offset/limit combinations
  • Validates pagination consistency
  • Tests boundary conditions
  • Search result pagination

Usage:

python api/perl/tests/test_pagination.py
python api/php/tests/test_pagination.py
python api/node/tests/test_pagination.py

26. test_list_documents.py

Purpose: Document listing operations

What it tests:

  • Listing all documents
  • Listing with limits
  • Listing with offsets
  • Empty result handling
  • Large offset handling

Listing Operations:

  • Tests various listing parameters
  • Validates result consistency
  • Tests edge cases for listing

Usage:

python api/perl/tests/test_list_documents.py
python api/php/tests/test_list_documents.py
python api/node/tests/test_list_documents.py
python api/cpp/tests/test_list_documents.py
python api/rust/tests/test_list_documents.py

27. test_get_document.py

Purpose: Retrieve individual documents by ID

What it tests:

  • Getting documents by ID
  • Verifying document retrieval
  • Error handling for non-existent documents
  • Document field validation

Usage:

python api/perl/tests/test_get_document.py
python api/php/tests/test_get_document.py
python api/node/tests/test_get_document.py
python api/cpp/tests/test_get_document.py
python api/rust/tests/test_get_document.py

28. test_stats.py

Purpose: Server statistics and metrics

What it tests:

  • GET /stats - Server statistics
  • GET /connections - Active connections
  • GET /rocksdb - RocksDB engine stats
  • GET /doctotal - Document counts

Usage:

python api/perl/tests/test_stats.py
python api/php/tests/test_stats.py
python api/node/tests/test_stats.py
python api/cpp/tests/test_stats.py
python api/rust/tests/test_stats.py

29. test_import_documents.py

Purpose: Document import operations

What it tests:

  • Importing single documents
  • Importing multiple documents
  • Verifying import results
  • Import validation

Usage:

python api/perl/tests/test_import_documents.py
python api/php/tests/test_import_documents.py
python api/node/tests/test_import_documents.py
python api/cpp/tests/test_import_documents.py
python api/rust/tests/test_import_documents.py

30. test_filter_search.py

Purpose: Search with filter operations

What it tests:

  • Filtering by category
  • Filtering by price range
  • Multiple filter combinations
  • Complex filter expressions

Filter Operations:

  • Category filters
  • Numeric range filters
  • Boolean filters
  • Combined filters with && and ||

Usage:

python api/perl/tests/test_filter_search.py
python api/php/tests/test_filter_search.py
python api/node/tests/test_filter_search.py
python api/cpp/tests/test_filter_search.py
python api/rust/tests/test_filter_search.py

31. test_sort_search.py

Purpose: Search with sorting options

What it tests:

  • Sorting by price (ascending/descending)
  • Sorting by rating
  • Sorting by multiple fields
  • Sort order validation

Sort Operations:

  • Ascending sort (:asc)
  • Descending sort (:desc)
  • Multiple field sorting
  • Sort with filters

Usage:

python api/perl/tests/test_sort_search.py
python api/php/tests/test_sort_search.py
python api/node/tests/test_sort_search.py
python api/cpp/tests/test_sort_search.py
python api/rust/tests/test_sort_search.py

How Tests Work

Test Structure

Each test script follows a consistent structure:

#!/usr/bin/env python3
"""
Test Description
"""

import sys
import os

# Change to script directory (working directory)
script_dir = os.path.dirname(os.path.abspath(__file__))
os.chdir(script_dir)

# Path setup to import client library
python_api_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(script_dir))), 'python')
sys.path.insert(0, python_api_path)

from lib import Client

BASE_URL = 'http://localhost:9200'

def test_feature():
"""Test function"""
print("=" * 70)
print("TEST: Feature Name")
print("-" * 70)

client = Client(BASE_URL)
tests_passed = 0
tests_failed = 0

# Test scenarios here
# ...

# Summary
print(f"Test Summary: {tests_passed} passed, {tests_failed} failed")

if __name__ == '__main__':
test_feature()

Key Feature: All test scripts automatically change to their own directory when executed using os.chdir(script_dir). This ensures:

  • Tests can be run from any directory
  • Relative paths work correctly
  • Working directory is always the test directory

For detailed explanations of how tests work, see How Tests Work.

Test Execution Flow

  1. Setup: Test imports client library and sets base URL
  2. Execution: Runs test scenarios with pass/fail tracking
  3. Verification: Checks responses and validates results
  4. Cleanup: Removes test data (collections, documents)
  5. Reporting: Prints summary with pass/fail counts

Example: How test_search.py Works

Let's walk through how the enhanced search test works:

def test_search():
"""Test search functionality with multiple scenarios"""
# 1. Initialize client
client = Client('http://localhost:9200')
tests_passed = 0
tests_failed = 0

# 2. Get or create test collection
collections = client.list_collections(0, 1)
collection_name = None

if collections.is_success():
body = collections.get_body()
if body.get('collections'):
collection_name = body['collections'][0]['name']

# 3. Create test collection if needed
if not collection_name:
collection_name = 'test_search_' + str(int(time.time()))
schema = {
'fields': [
{'name': 'title', 'type': 'string'},
{'name': 'content', 'type': 'string'},
{'name': 'category', 'type': 'string'},
{'name': 'price', 'type': 'float'}
]
}
client.collections_api().create(collection_name, schema)

# Add test documents
test_docs = [
{'id': 'doc1', 'title': 'Test Document One', ...},
{'id': 'doc2', 'title': 'Test Document Two', ...},
{'id': 'doc3', 'title': 'Sample Document', ...}
]
for doc in test_docs:
client.documents_api().add(collection_name, doc)

# 4. Run test scenarios
# Test 1: Basic search
search_params = {'q': 'test', 'query_by': 'title,content', 'limit': 10}
results = client.search(collection_name, search_params)
if results.is_success():
tests_passed += 1
else:
tests_failed += 1

# Test 2: Filtered search
search_params = {'q': '*', 'query_by': 'title', 'filter_by': 'category:test', 'limit': 5}
results = client.search(collection_name, search_params)
# ... validation ...

# Test 3-5: More scenarios...

# 5. Cleanup
if created_collection:
client.collections_api().delete(collection_name)

# 6. Summary
print(f"Search Test Summary: {tests_passed} passed, {tests_failed} failed")

Example: How test_bulk_operations.py Works

def test_bulk_operations():
"""Test bulk document operations"""
client = Client(BASE_URL)

# 1. Create test collection
collection_name = 'test_bulk_' + str(int(time.time()))
schema = {'fields': [{'name': 'title', 'type': 'string'}]}
client.collections_api().create(collection_name, schema)

# 2. Prepare bulk documents
bulk_docs = [
{'id': 'bulk1', 'title': 'Bulk Document 1'},
{'id': 'bulk2', 'title': 'Bulk Document 2'},
{'id': 'bulk3', 'title': 'Bulk Document 3'},
# ... more documents
]

# 3. Bulk import
import_result = client.documents_api().import_documents(collection_name, bulk_docs)
if import_result.is_success():
print(f"✓ Bulk imported {len(bulk_docs)} documents")

# 4. Verify import
documents = client.list_documents(collection_name, {'offset': 0, 'limit': 10})
# Check document count matches

# 5. Bulk delete by filter
delete_result = client.documents_api().delete_by_filter(collection_name, 'category:bulk')

# 6. Cleanup
client.collections_api().delete(collection_name)

Example: How test_error_handling.py Works

def test_error_handling():
"""Test error handling scenarios"""
client = Client(BASE_URL)

# Test 1: Get non-existent collection (should return 404)
result = client.get_collection('__nonexistent_collection__')
if not result.is_success() and result.get_status_code() == 404:
print("✓ Correctly returned 404 error")
tests_passed += 1

# Test 2: Get non-existent document (should return 404)
result = client.get_document(collection_name, '__nonexistent_doc__')
if not result.is_success() and result.get_status_code() == 404:
print("✓ Correctly returned 404 error")
tests_passed += 1

# Test 3: Create collection with invalid schema (should return 400/422)
invalid_schema = {'invalid': 'data'}
result = client.collections_api().create('test_invalid', invalid_schema)
if not result.is_success() and result.get_status_code() in [400, 422]:
print("✓ Correctly rejected invalid schema")
tests_passed += 1

Example: How test_edge_cases.py Works

def test_edge_cases():
"""Test edge cases"""
client = Client(BASE_URL)

# Test 1: Document with special characters
special_doc = {
'id': 'special_123',
'title': 'Test & Special <Characters> "Quotes"',
'content': "Content with 'apostrophes' and \"quotes\""
}
result = client.documents_api().add(collection_name, special_doc)
if result.is_success():
print("✓ Document with special characters created")

# Test 2: Empty string values
empty_doc = {'id': 'empty_123', 'title': '', 'content': ''}
result = client.documents_api().add(collection_name, empty_doc)

# Test 3: Large limit value
result = client.list_documents(collection_name, {'offset': 0, 'limit': 10000})

# Test 4: Zero limit
result = client.list_documents(collection_name, {'offset': 0, 'limit': 0})

Running Tests

Individual Test Execution

Run any test script directly:

# From the API directory
cd api/python/tests
python test_auth.py

# Or from project root
python api/python/tests/test_auth.py

Example Test Output

When you run a test, you'll see output like this:

----------------------------------------------------------------==============================
TEST: Search Functionality
----------------------------------------------------------------------
✓ Created test collection: test_search_1234567890
✓ Added 3 test documents

Using collection: test_search_1234567890

Test 1: Basic search
✓ Found 2 results

Test 2: Search with filters
✓ Filtered search found 2 results

Test 3: Search with sorting
✓ Sorted search successful

Test 4: Search with pagination
✓ Paginated search returned 2 results

Test 5: Wildcard search
✓ Wildcard search successful

✓ Cleaned up test collection: test_search_1234567890

----------------------------------------------------------------==============================
Search Test Summary: 5 passed, 0 failed
----------------------------------------------------------------==============================

Running All Tests

Use the test runner script to execute all tests:

# From the tests directory
python run_all_tests.py

# Or from project root
python api/python/tests/run_all_tests.py

The test runner provides:

  • Sequential execution of all tests
  • Pass/fail reporting for each test
  • Summary statistics
  • Total execution time
  • Error details for failed tests

Example Test Runner Output

When you run run_all_tests.py, you'll see output like this:

----------------------------------------------------------------==============================
hlquery API Test Suite
----------------------------------------------------------------==============================

Found 26 test files

Running tests...

Running test_auth.py...
✓ PASSED (0.45s)

Running test_search.py...
✓ PASSED (1.23s)

Running test_bulk_operations.py...
✓ PASSED (0.89s)

Running test_synonyms.py...
✓ PASSED (0.67s)

Running test_stopwords.py...
✓ PASSED (0.52s)

Running test_overrides.py...
✓ PASSED (0.61s)

Running test_aliases.py...
✓ PASSED (0.48s)

Running test_facets.py...
✓ PASSED (0.55s)

Running test_export.py...
✓ PASSED (0.43s)

Running test_delete_collection.py...
✓ PASSED (0.38s)

Running test_update_collection.py...
✓ PASSED (0.42s)

Running test_error_handling.py...
✓ PASSED (0.51s)

Running test_edge_cases.py...
✓ PASSED (0.47s)

Running test_data_types.py...
✓ PASSED (0.58s)

Running test_pagination.py...
✓ PASSED (0.64s)

Running test_list_documents.py...
✓ PASSED (0.49s)

... (more tests)

----------------------------------------------------------------==============================
TEST SUMMARY
----------------------------------------------------------------==============================

Total Tests: 26
Passed: 26
Failed: 0
Total Time: 15.23s

----------------------------------------------------------------==============================

Detailed Test Examples

Example 1: Running test_auth.py

$ python api/perl/tests/test_auth.py

Output:

----------------------------------------------------------------==============================
TEST: Authentication with Bearer Token (Perl API)
----------------------------------------------------------------------
Health check without auth: 200
Set bearer token: test_tok...
Health check with bearer token: 200
Set API key: test_tok...
Health check with API key: 200
✓ Authentication test completed

What happened:

  1. Test created a client without authentication
  2. Made a health check request (succeeded)
  3. Set a bearer token and tested again (succeeded)
  4. Changed to API key authentication and tested (succeeded)

Example 2: Running test_bulk_operations.py

$ python api/php/tests/test_bulk_operations.py

Output:

----------------------------------------------------------------==============================
TEST: Bulk Operations (PHP API)
----------------------------------------------------------------------
✓ Created test collection: test_bulk_php_1234567890

Test 1: Bulk import documents
✓ Bulk imported 5 documents

Test 2: Verify bulk import
✓ Found 5 documents in collection

Test 3: Bulk delete by filter
✓ Bulk delete by filter successful

✓ Cleaned up collection: test_bulk_php_1234567890

----------------------------------------------------------------==============================
Bulk Operations Test Summary: 3 passed, 0 failed
----------------------------------------------------------------==============================

What happened:

  1. Created a test collection
  2. Imported 5 documents in one operation
  3. Verified all 5 documents were imported
  4. Deleted all documents matching a filter
  5. Cleaned up the test collection

Example 3: Running test_error_handling.py

$ python api/node/tests/test_error_handling.py

Output:

----------------------------------------------------------------==============================
TEST: Error Handling (Node.js API)
----------------------------------------------------------------------
Test 1: Get non-existent collection
✓ Correctly returned error: 404

Test 2: Get non-existent document
✓ Correctly returned error: 404

Test 3: Delete non-existent collection
✓ Correctly returned error: 404

Test 4: Create collection with invalid schema
✓ Correctly rejected invalid schema: 400

Test 5: Search with invalid parameters
✓ Search with invalid params handled: 400

----------------------------------------------------------------==============================
Error Handling Test Summary: 5 passed, 0 failed
----------------------------------------------------------------==============================

What happened:

  1. Tried to get a collection that doesn't exist → Got 404 (correct)
  2. Tried to get a document that doesn't exist → Got 404 (correct)
  3. Tried to delete a non-existent collection → Got 404 (correct)
  4. Tried to create collection with invalid schema → Got 400 (correct)
  5. Tried search with invalid parameters → Got 400 (correct)

Example 4: Running test_data_types.py

$ python api/perl/tests/test_data_types.py

Output:

----------------------------------------------------------------==============================
TEST: Data Types (Perl API)
----------------------------------------------------------------------
✓ Created test collection: test_datatypes_perl_1234567890

Test 1: String field
✓ String field handled

Test 2: Float field
✓ Float field handled

Test 3: String array field
✓ String array field handled

Test 4: Float array field (vector)
✓ Float array field handled

Test 5: Integer field
✓ Integer field handled

✓ Cleaned up collection: test_datatypes_perl_1234567890

----------------------------------------------------------------==============================
Data Types Test Summary: 5 passed, 0 failed
----------------------------------------------------------------==============================

What happened:

  1. Created collection with multiple field types (string, float, int, arrays)
  2. Tested each data type by inserting documents
  3. Verified all data types are handled correctly
  4. Cleaned up test collection

Test Interaction Examples

Example: How Tests Create and Clean Up Data

Most tests follow this pattern:

# 1. CREATE test data
collection_name = 'test_feature_' + str(int(time.time()))
client.collections_api().create(collection_name, schema)

# 2. USE test data
# ... perform operations ...

# 3. CLEANUP test data
client.collections_api().delete(collection_name)

Why this matters:

  • Each test is independent
  • No leftover data after tests
  • Tests can run in any order
  • Safe to run multiple times

Example: How Tests Track Pass/Fail

tests_passed = 0
tests_failed = 0

# Test scenario
result = client.some_operation()
if result.is_success():
print(" ✓ Operation successful")
tests_passed += 1
else:
print(f" ✗ Operation failed: {result.get_status_code()}")
tests_failed += 1

# At the end
print(f"Test Summary: {tests_passed} passed, {tests_failed} failed")

Benefits:

  • Clear pass/fail indicators (✓ and ✗)
  • Detailed error information
  • Summary statistics
  • Easy to see what failed

Real-World Test Scenarios

Scenario 1: Testing Search with Real Data

# Create collection with realistic schema
schema = {
'fields': [
{'name': 'title', 'type': 'string'},
{'name': 'description', 'type': 'string'},
{'name': 'price', 'type': 'float'},
{'name': 'category', 'type': 'string'},
{'name': 'tags', 'type': 'string[]'}
]
}

# Add realistic documents
products = [
{
'id': 'prod1',
'title': 'Wireless Headphones',
'description': 'High-quality wireless headphones with noise cancellation',
'price': 99.99,
'category': 'electronics',
'tags': ['audio', 'wireless', 'headphones']
},
# ... more products
]

# Test various search scenarios
# 1. Search by text
results = client.search(collection_name, {
'q': 'headphones',
'query_by': 'title,description',
'limit': 10
})

# 2. Filter by category
results = client.search(collection_name, {
'q': '*',
'query_by': 'title',
'filter_by': 'category:electronics',
'limit': 10
})

# 3. Sort by price
results = client.search(collection_name, {
'q': '*',
'query_by': 'title',
'sort_by': 'price:asc',
'limit': 10
})

Scenario 2: Testing Bulk Operations

# Prepare large batch of documents
bulk_docs = []
for i in range(100):
bulk_docs.append({
'id': f'doc_{i}',
'title': f'Document {i}',
'content': f'Content for document {i}',
'category': 'test'
})

# Import all at once
result = client.documents_api().import_documents(collection_name, bulk_docs)

# Verify all imported
documents = client.list_documents(collection_name, {'offset': 0, 'limit': 1000})
assert len(documents.get_body()['documents']) == 100

# Bulk delete by category
delete_result = client.documents_api().delete_by_filter(collection_name, 'category:test')

Scenario 3: Testing Error Handling

# Test 1: Invalid collection name
result = client.get_collection('')
assert not result.is_success()
assert result.get_status_code() in [400, 404]

# Test 2: Invalid document ID
result = client.get_document(collection_name, '')
assert not result.is_success()
assert result.get_status_code() in [400, 404]

# Test 3: Invalid schema
invalid_schema = {'not': 'valid'}
result = client.collections_api().create('test', invalid_schema)
assert not result.is_success()
assert result.get_status_code() in [400, 422]

# Test 4: Missing required fields
incomplete_doc = {'id': 'doc1'} # Missing required fields
result = client.documents_api().add(collection_name, incomplete_doc)
# May succeed or fail depending on schema requirements

Test Configuration

Base URL

All tests use a default base URL: http://localhost:9200

To test against a different server, modify the BASE_URL constant in each test file:

BASE_URL = 'http://your-server:9200'

Authentication

Tests can be configured to use authentication by modifying the test scripts or passing tokens via environment variables.

For tests that require authentication:

  1. Set the token in the test script
  2. Or modify the client initialization to include auth

Example:

client = Client(BASE_URL)
client.set_auth_token('your_token_here', 'bearer')

Test Best Practices

1. Test Isolation

Each test script is designed to be independent:

  • Creates its own test data when needed
  • Cleans up after itself
  • Doesn't depend on other tests

2. Error Handling

Tests include comprehensive error handling:

  • Graceful failure for missing collections
  • Clear error messages
  • Proper cleanup even on failure

3. Data Cleanup

Tests that create data automatically clean up:

  • Test collections are deleted after testing
  • Test documents are removed
  • No leftover test data

4. Real-World Scenarios

Tests simulate real usage:

  • Create collections with realistic schemas
  • Insert documents with meaningful data
  • Perform actual searches and operations

Integration with CI/CD

Running Tests in CI

Example GitHub Actions workflow:

name: API Tests

on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Start hlquery server
run: |
# Start your hlquery server
./hlquery --daemon
- name: Run tests
run: |
python api/python/tests/run_all_tests.py
- name: Stop server
run: |
# Stop hlquery server
pkill hlquery

Exit Codes

  • 0: All tests passed
  • 1: One or more tests failed

This makes the test suite suitable for CI/CD pipelines.

Extending the Test Suite

Adding New Tests

To add a new test:

  1. Create a new file: test_new_feature.py

  2. Follow the existing test structure:

    #!/usr/bin/env python3
    """Test Description"""

    import sys
    import os
    sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

    from lib import Client

    BASE_URL = 'http://localhost:9200'

    def test_new_feature():
    """Test description"""
    print("=" * 70)
    print("TEST: New Feature")
    print("-" * 70)

    client = Client(BASE_URL)
    # Your test code here

    print("✓ Test completed\n")

    if __name__ == '__main__':
    test_new_feature()
  3. Make it executable: chmod +x test_new_feature.py

  4. The test runner will automatically include it

Test Naming Convention

  • All test files start with test_
  • Use descriptive names: test_feature_name.py
  • Use underscores, not hyphens

Troubleshooting

Common Issues

1. Import Errors

Problem: ModuleNotFoundError: No module named 'lib'

Solution: Ensure you're running from the correct directory or the test script has the correct path setup.

2. Connection Refused

Problem: Connection refused errors

Solution:

  • Ensure hlquery server is running
  • Check the BASE_URL matches your server address
  • Verify firewall settings

3. Authentication Failures

Problem: 401 Unauthorized errors

Solution:

  • Check if your server requires authentication
  • Set the correct token in the test script
  • Verify token format (bearer vs api-key)

4. Collection Not Found

Problem: Tests fail because collections don't exist

Solution:

  • Some tests create their own collections
  • Others require existing collections
  • Check test documentation for requirements

Test Coverage

The comprehensive test suite covers:

Core Functionality (Tests 1-12)

  • Authentication (bearer tokens, API keys)
  • Collection management (create, read, update, delete, list)
  • Document operations (insert, update, delete, retrieve, list)
  • Search operations (basic, filtered, sorted, paginated, wildcard)
  • Vector search (similarity search with embeddings)
  • Multi-collection search
  • Health and monitoring endpoints

Advanced Features (Tests 13-21)

  • Bulk document operations (import, delete by filter)
  • Synonyms management (create, read, update, delete)
  • Stopwords management (add, list, delete)
  • Search overrides (create, read, delete)
  • Collection aliases (create, read, delete)
  • Facet counts and aggregation
  • Document export
  • Collection deletion with verification
  • Collection schema updates

Error Handling & Edge Cases (Tests 22-26)

  • Error handling (404, 400, 422 responses)
  • Edge cases (special characters, empty values, boundaries)
  • Data type validation (strings, floats, integers, arrays, vectors)
  • Pagination scenarios (various offset/limit combinations)
  • Document listing operations (all variations)

Additional Operations (Tests 27-31)

  • Get individual documents by ID
  • Server statistics and metrics (cache, connections, RocksDB, doctotal)
  • Document import operations (single and bulk)
  • Filter search operations (category, price range, multiple filters)
  • Sort search operations (ascending, descending, multiple fields)

Test Statistics

Per API Directory:

  • Python API: 31 test files (30 tests + 1 runner)
  • Node.js API: 31 test files (30 tests + 1 runner)
  • Perl API: 31 test files (30 tests + 1 runner)
  • PHP API: 31 test files (30 tests + 1 runner)
  • Node API: 31 test files (30 tests + 1 runner)
  • C++ API: 31 test files (30 tests + 1 runner)
  • Rust API: 31 test files (30 tests + 1 runner)

Total Test Coverage:

  • 60+ API endpoints tested
  • 180+ individual test scenarios
  • Comprehensive error handling
  • Edge case validation
  • Data type verification
  • Filter and sort operations
  • Statistics and metrics

Test Suite by API

Python API Tests

The Python API includes 31 test files covering comprehensive functionality:

  • All core functionality tests
  • Advanced feature tests (bulk ops, synonyms, stopwords, etc.)
  • Error handling and edge case tests
  • Data type validation tests
  • Pagination and listing tests
  • Document retrieval tests
  • Statistics and metrics tests
  • Filter and sort search tests

Node.js API Tests

The Node.js API includes 31 test files covering comprehensive functionality:

  • All core functionality tests
  • Advanced feature tests (bulk ops, synonyms, stopwords, etc.)
  • Error handling and edge case tests
  • Data type validation tests
  • Pagination and listing tests
  • Document retrieval tests
  • Statistics and metrics tests
  • Filter and sort search tests

Perl, PHP, Node, C++, and Rust API Tests

These APIs include the most comprehensive test suite with 31 test files each:

  • All core functionality tests
  • Advanced feature tests (bulk ops, synonyms, stopwords, etc.)
  • Error handling and edge case tests
  • Data type validation tests
  • Pagination and listing tests
  • Document retrieval tests
  • Statistics and metrics tests
  • Filter and sort search tests

Running Tests for Different APIs

# Python API
python api/python/tests/run_all_tests.py

# Perl API
python api/perl/tests/run_all_tests.py

# PHP API
python api/php/tests/run_all_tests.py

# Node API
python api/node/tests/run_all_tests.py

# C++ API
python api/cpp/tests/run_all_tests.py

# Rust API
python api/rust/tests/run_all_tests.py

All test suites use the Python client library and can be run from any API directory.

Language-Specific Test Guides

Contributing

When adding new API features, please:

  1. Add corresponding test scripts
  2. Update this documentation
  3. Ensure tests pass before submitting PRs
  4. Follow existing test patterns and conventions

Support

For issues with the test suite:

  • Check the troubleshooting section above
  • Review test script comments
  • Check server logs for detailed error messages
  • Open an issue on the project repository