Skip to content
GitHub

Run with: pytest tests/ --verbose

Alpha (0.1.x) — MIT licensed. Public API may change before 1.0.

Compliance suites are base test classes that verify a protocol implementation against its contract. They ensure your custom backend (cache, event bus, database, etc.) behaves correctly across all edge cases — not just the happy path.

Each suite is a standard pytest class. Subclass it, implement the abstract factory method, and pytest discovers the tests automatically.

SuiteProtocol verifiedFactory method
CacheBackendComplianceCacheBackendProtocolcreate_backend()
EventBusComplianceEventBusProtocolcreate_bus()
QueueBackendComplianceQueueBackendProtocolcreate_backend()
TaskQueueComplianceTaskQueueProtocolcreate_queue()
DatabaseProviderComplianceDatabaseProviderProtocolcreate_provider()
RepositoryComplianceRepositoryProtocolcreate_repository()
VectorStoreComplianceVectorStoreProtocolcreate_store()
SearchEngineComplianceSearchEngineProtocolcreate_engine()
BlobStoreComplianceBlobStoreProtocolcreate_store()
DistributedLockComplianceDistributedLockProtocolcreate_lock()
AuditLoggerComplianceAuditLoggerProtocolcreate_logger()
AuditStoreComplianceAuditStoreProtocolcreate_store()
WebhookDeliveryStoreComplianceWebhookDeliveryStoreProtocolcreate_store()
WebhookSubscriptionStoreComplianceWebhookSubscriptionStoreProtocolcreate_store()
MiddlewareComplianceMiddlewareProtocolcreate_middleware()
FlagProviderComplianceFlagProviderProtocolcreate_provider()
NotificationChannelComplianceNotificationChannelProtocolcreate_channel()

Import from lexigram.testing.compliance:

from lexigram.testing import CacheBackendCompliance
from lexigram.testing import EventBusCompliance

Using compliance suites with custom backends

Section titled “Using compliance suites with custom backends”

Subclass the suite and implement the factory method. Pytest runs all inherited tests:

from lexigram.testing import CacheBackendCompliance
from my_project import RedisCacheBackend
class TestRedisCacheCompliance(CacheBackendCompliance):
async def create_backend(self):
return RedisCacheBackend("redis://localhost:6379/15")

The suite verifies:

  • get/set round-trip
  • Missing key returns None
  • TTL expiration
  • delete removes keys
  • clear empties the cache
  • Concurrent access safety

Create a base test class that exercises your protocol:

import pytest
from lexigram.result import Ok
from lexigram.contracts.infra.cache import CacheBackendProtocol
class MyProtocolCompliance:
@pytest.fixture
async def backend(self) -> CacheBackendProtocol:
return await self.create_backend()
async def create_backend(self) -> CacheBackendProtocol:
raise NotImplementedError # Subclasses implement this
@pytest.mark.asyncio
async def test_set_and_get(self, backend: CacheBackendProtocol) -> None:
result = await backend.set("key", b"value")
assert result.is_ok()
got = await backend.get("key")
assert got.is_ok() and got.unwrap() == b"value"
@pytest.mark.asyncio
async def test_missing_key(self, backend: CacheBackendProtocol) -> None:
result = await backend.get("nonexistent")
assert result.is_ok() and result.unwrap() is None

Add it to your test suite’s __all__ and import it alongside the built-in suites.

from lexigram.testing import CacheBackendCompliance
from my_app.backends import MyCustomCache
class TestMyCacheCompliance(CacheBackendCompliance):
async def create_backend(self):
return MyCustomCache(max_size=1000)
# Run with: pytest tests/ --verbose

The compliance suite will run approximately 15-20 tests depending on the protocol. All tests use Result-based assertions:

result = await backend.set("key", b"val")
assert result.is_ok() # Never unwrap() without checking
  • lexigram.testing.compliance — full module listing
  • lexigram.contracts.cache.CacheBackendProtocol — protocol definition
  • FakeCache, InMemoryCacheBackend — reference implementations for comparison
  • CacheBackendCompliance — source to understand the test matrix