LiteBus
Testing

Integration Tests

This page is the reference for LiteBus integration tests: which projects exist, what infrastructure each one uses, and which behavioral scenarios they prove. It is written for maintainers adding broker or storage coverage and for contributors running the suite locally or in CI.

For handler-level and in-memory processor recipes, see Testing LiteBus. For durable messaging setup snippets, see Testing.

[!NOTE] Project counts, trait names, and container images reflect the repository at the time this page was written. When in doubt, inspect tests/ and .github/workflows/build-and-test.yml.

How Integration Tests Are Organized

LiteBus consolidates integration tests into four executor projects grouped by concern, plus shared helper libraries. Each executor owns many adapter surfaces (brokers, databases, host bridges) organized in subfolders by technology. Tests prove outcomes: store row transitions, wire headers, processor passes, manifest registration, or HTTP responses. Registration smoke and fast InMemory wire cases live in LiteBus.Durable.IntegrationTests. Sample v6 composition smoke lives in LiteBus.Runtime.UnitTests.

flowchart TB
  subgraph fast [No Docker]
    DTFast["Durable.IntegrationTests TransportFast"]
    HC["Extensions.IntegrationTests HealthChecks"]
    OT["Extensions.IntegrationTests OpenTelemetry"]
  end

  subgraph docker [Docker / Testcontainers]
    DTBrokers["Durable.IntegrationTests Kafka, AWS, Azure, AMQP"]
    PG["Storage.IntegrationTests PostgreSql"]
    EF["Storage.IntegrationTests EntityFrameworkCore"]
    AMQPWire["Transport.IntegrationTests Amqp wire"]
    ASP["Extensions.IntegrationTests AspNetCore"]
  end

  subgraph shared [Shared libraries]
    ST["LiteBus.Storage.Testing contract suites"]
    DTT["LiteBus.Transport.IntegrationTesting helpers"]
    LT["LiteBus.Testing.* concern helpers"]
  end

  DTBrokers --> DTT
  PG --> ST
  EF --> ST
  AMQPWire --> DTT

Executor Inventory

ProjectPathLayer testedDockerPrimary fixture
LiteBus.Durable.IntegrationTeststests/LiteBus.Durable.IntegrationTests/Broker ingress and dispatch (all brokers)Per scenarioKafkaBrokerFixture, LocalStackSqsFixture, ServiceBusEmulatorFixture, RabbitMQ/LavinMQ fixtures
LiteBus.Storage.IntegrationTeststests/LiteBus.Storage.IntegrationTests/PostgreSQL inbox/outbox/saga storage, EF Core stores, schema, hostingYesPostgreSqlFixture, SqlServerFixture
LiteBus.Transport.IntegrationTeststests/LiteBus.Transport.IntegrationTests/AMQP publish/consume/ack/nack wire behaviorYesRabbitMqFixture, LavinMqFixture
LiteBus.Extensions.IntegrationTeststests/LiteBus.Extensions.IntegrationTests/Management HTTP endpoints, health checks, OpenTelemetryPartialPostgreSqlFixture for AspNetCore; InMemory inbox for health

Folder Layout

tests/
|-- LiteBus.Durable.IntegrationTests/
|   |-- Ingress/              # broker to IInbox (InMemory, Kafka, AwsSqs, AzureServiceBus, Amqp)
|   |-- Dispatch/
|   |   |-- Inbox/            # inbox processor to broker
|   |   `-- Outbox/           # outbox processor to broker
|   `-- Registration/         # Use*Dispatch / Use*Ingress resolve without live broker
|-- LiteBus.Storage.IntegrationTests/
|   |-- PostgreSql/           # reference PG store, schema, saga, reliable messaging
|   `-- EntityFrameworkCore/
|       |-- Inbox/
|       `-- Outbox/
|-- LiteBus.Transport.IntegrationTests/
|   `-- Amqp/                 # low-level wire protocol (no inbox/outbox)
|-- LiteBus.Extensions.IntegrationTests/
|   |-- AspNetCore/
|   |-- HealthChecks/
|   `-- OpenTelemetry/
|-- LiteBus.Runtime.UnitTests/
|   `-- Runtime/Composition/  # v6 composition smoke (unit test, not integration)
|-- LiteBus.Transport.IntegrationTesting/   # shared fixtures, traits (not an executor)
|-- LiteBus.Transport.Testing/              # published transport contract suite
|-- LiteBus.Storage.Testing/                # abstract store contract suites
`-- LiteBus.Testing*/                       # concern-specific application test helpers

Supporting libraries (not test executors):

LibraryRole
LiteBus.Transport.IntegrationTestingShared broker fixtures, xUnit traits, DockerTestGate, FlakyInbox, polling helpers, Kafka/AWS/Azure fixture hosts
LiteBus.Transport.Testing (tests/, also published as a package)Abstract TransportContractTests suite for payload/header round trips, redelivery, and cancellation (not a vstest executor; IsTestProject=false)
LiteBus.Storage.Testing (tests/, also published as a package)Abstract InboxStoreContractTests, OutboxStoreContractTests, retention contract suites, lease renewal ownership checks (not a vstest executor; IsTestProject=false)
LiteBus.TestingFramework-neutral ManualTimeProvider and LiteBusTestBase
LiteBus.Testing.DurableMessagingAddInboxStoreRoles, AddOutboxStoreRoles, in-memory host, and processor helpers
LiteBus.Testing.HostingGeneric Host lifecycle and manifest helpers

Shared Infrastructure Patterns

Testcontainers and Images

All Docker-backed fixtures use Testcontainers for .NET (central version in tests/Directory.Packages.props).

ContainerImage / moduleUsed by
PostgreSQLpostgres:16-alpine via Testcontainers.PostgreSqlPostgreSQL storage, EF Core, AspNetCore management, AMQP+PG combos
SQL ServerTestcontainers.MsSqlEF Core inbox/outbox on SQL Server
RabbitMQrabbitmq:4-management via Testcontainers.RabbitMqAMQP transport, ingress, dispatch, PG reliable messaging
LavinMQcloudamqp/lavinmq via generic ContainerBuilderSecond AMQP broker for compatibility
Kafka (Redpanda)docker.redpanda.com/redpandadata/redpanda:v24.3.7 via Testcontainers.Redpanda (default); Confluent via Testcontainers.Kafka when LITEBUS_KAFKA_TEST_BROKER=confluentKafka ingress, dispatch, outbox
LocalStacklocalstack/localstack:4.2 via Testcontainers.LocalStackAWS SQS durable transport
Azure Service Bus emulatorTestcontainers.ServiceBus + servicebus-emulator-config.jsonAzure durable transport

Fixture Lifetime

PatternWhen usedExample
ICollectionFixture<T>One expensive container per test collectionKafkaBrokerCollection, ServiceBusEmulatorCollection, LocalStackSqsCollection
IClassFixture<T>One container shared by all tests in a classPostgreSqlFixture in Storage.IntegrationTests and Extensions.IntegrationTests
Per-test fixtureIsolated broker when tests mutate queues or need clean stateAmqpInboxIngressBatchIntegrationTests creates its own RabbitMqBrokerFixture
Inline new Fixture() + try/finallyComposite scenarios (PG + RabbitMQ in one test)PostgreSqlReliableMessagingEndToEndTests

Docker Unavailable Behavior

Projects differ in how they handle a missing Docker daemon:

BehaviorProjectsMechanism
Fail fast with clear messageStorage.IntegrationTests, Transport.IntegrationTests, Durable.IntegrationTests (AMQP)Fixture InitializeAsync throws InvalidOperationException with DockerRequiredMessage
Skip testsDurable transport (Kafka/AWS/Azure emulator)DockerTestGate + [SkippableFact] + Skip.IfNot(_fixture.IsAvailable) (Azure emulator)
No Docker neededTransportFast cases in LiteBus.Durable.IntegrationTests, health checks, OpenTelemetryAlways runs

CI (.github/workflows/build-and-test.yml) runs unit tests without Docker (FullyQualifiedName!~IntegrationTests), then durable transport in three filtered batches (TransportFast, TransportDocker, TransportAzure), then remaining integration tests (FullyQualifiedName~IntegrationTests excluding those categories and the opt-in TransportLiveAzure category).

Environment Variable Overrides (Local Troubleshooting)

Fixtures can bypass Testcontainers when a connection string is already available:

VariableBypasses
LITEBUS_TEST_POSTGRES_CONNECTION_STRINGPostgreSQL Testcontainers in Storage.IntegrationTests, Extensions.IntegrationTests, and AMQP+PG cases in Durable.IntegrationTests
LITEBUS_TEST_AZURE_SERVICEBUS_CONNECTION_STRING + LITEBUS_TEST_AZURE_SERVICEBUS_QUEUEOptional live Azure namespace tests only (AzureServiceBusOptionalIntegrationTests)

Emulator-based Azure tests still require Docker; the env vars do not replace the emulator fixture.

Typical Test Shape (Durable Messaging)

Most inbox/outbox integration tests follow the same pipeline:

  1. Build ServiceCollection through AddLiteBus(builder => ...).
  2. Register contracts, storage (UseInMemoryStorage or PostgreSQL/EF), and dispatch/ingress adapter.
  3. Ingress path: publish to broker to wait for consumer to assert store/handler state.
  4. Dispatch path: IInbox.AcceptAsync or IOutbox.EnqueueAsync to ProcessPendingAsync to assert broker message or handler side effect.
  5. Assert on observable outcomes (row status, headers on wire, handler invocation), not on internal types.

Broker-Backed Transport Integration Tests

Executor: tests/LiteBus.Durable.IntegrationTests/ Shared helpers: tests/LiteBus.Transport.IntegrationTesting/ Subfolders: Ingress/, Dispatch/Inbox/, Dispatch/Outbox/, Registration/ (grouped by broker: InMemory, Kafka, AwsSqs, AzureServiceBus, Amqp)

InMemory scenarios run without Docker. Kafka, AWS SQS (LocalStack), Azure Service Bus, and AMQP use Testcontainers.

xUnit Categories (CI Filters)

TraitConstantDockerScope
TransportFastTransportTestTraits.FastNoInMemory wire tests in Ingress/InMemory/ and Dispatch/**/InMemory/
TransportDockerTransportTestTraits.DockerYesKafka, LocalStack SQS, AMQP
TransportAzureTransportTestTraits.AzureYes (emulator)Azure Service Bus emulator
TransportLiveAzureTransportTestTraits.LiveAzureNo local emulatorOptional live Azure namespace overlay with explicit credentials

Registration smoke (Registration/BrokerDispatchIngressRegistrationTests.cs) has no category trait; it runs in the Integration Tests CI batch.

# Durable matrix only
dotnet test tests/LiteBus.Durable.IntegrationTests --filter "Category=TransportFast"
dotnet test tests/LiteBus.Durable.IntegrationTests --filter "Category=TransportDocker"
dotnet test tests/LiteBus.Durable.IntegrationTests --filter "Category=TransportAzure"
dotnet test tests/LiteBus.Durable.IntegrationTests --filter "Category=TransportDocker&FullyQualifiedName~Kafka"

# Full solution (matches CI)
dotnet test LiteBus.slnx --filter "Category=TransportFast"
dotnet test LiteBus.slnx --filter "Category=TransportDocker"
dotnet test LiteBus.slnx --filter "Category=TransportAzure"
dotnet test LiteBus.slnx --filter "Category=TransportDocker&FullyQualifiedName~Kafka"

Fixtures per Broker

BrokerFixtureCollectionNotes
InMemoryNoneN/AUses UseInMemoryStorage + in-memory transport modules
KafkaKafkaBrokerFixtureKafkaBrokerCollectionDefault Redpanda image; process-wide host via KafkaBrokerSharedLifecycle; per-test consumer group via KafkaIngressTestSupport.CreateConnection; override with LITEBUS_KAFKA_TEST_IMAGE or LITEBUS_KAFKA_TEST_BROKER
AWS SQSLocalStackSqsFixtureLocalStackSqsCollectionCreates per-scenario queues via CreateQueueAsync(prefix)
AzureServiceBusEmulatorFixtureServiceBusEmulatorCollectionPre-declared queues in Azure/servicebus-emulator-config.json; IsAvailable gates skips

Pre-declared Azure emulator queues: litebus-ingress, litebus-dispatch, litebus-outbox, litebus-fail. ResolveQueue(prefix) maps scenario names to those queues.

Shared Test Messages

Defined in TransportTestMessages.cs under LiteBus.Transport.IntegrationTesting:

TypeUsed for
RemoteWorkCommandInbox dispatch (processor publishes to broker)
ShipOrderCommandInbox ingress E2E (broker to accept to handler)
OrderSubmittedIntegrationEventOutbox dispatch

Scenario Classes (by Folder)

InMemory (Ingress/InMemory/, Dispatch/Inbox/InMemory/, Dispatch/Outbox/InMemory/)

Test classScenarios
InMemoryInboxDispatchIntegrationTestsInbox processor publishes leased envelope to in-memory destination with headers
InMemoryOutboxDispatchIntegrationTestsOutbox processor publishes event; full header propagation; contract-name route fallback
InMemoryInboxIngressModuleIntegrationTestsUseInMemoryIngress E2E accept to process to dispatch; a running Generic Host keeps healthy ingress and dispatch active while an unrelated publisher circuit is open
InMemoryIngressFailureIntegrationTestsUnknown contract, invalid JSON, store full (no broker write)
InMemoryIngressHeaderEdgeCaseIntegrationTestsMissing/wrong contract headers, invalid MessageId, wrong CLR shape
InMemoryIngressIdempotencyIntegrationTestsDuplicate MessageId to single inbox row
InMemoryIngressRequeueBehaviorIntegrationTestsRequeueOnFailure on/off with transient failures

Kafka (Ingress/Kafka/, Dispatch/Inbox/Kafka/, Dispatch/Outbox/Kafka/)

Shared infrastructure lives in tests/LiteBus.Transport.IntegrationTesting/Kafka/ (KafkaBrokerHost, KafkaBrokerFixture, KafkaIngressTestSupport, KafkaTransportTestInfrastructure).

Ingress tests run production TransportInboxIngressConsumer and InboxProcessorBackgroundService through ExecuteAsync on background tasks. Short-lived test hosts call DisposeProviderSafelyAsync before tearing down Kafka clients because IHostedService orchestration can block on librdkafka shutdown.

FolderTest classScenarios
Ingress/Kafka/KafkaInboxIngressEndToEndIntegrationTestsPublish to ingress to processor to dispatch
KafkaInboxIngressFailureIntegrationTestsUnknown contract, invalid JSON, store full; transient seek redelivery
Dispatch/Inbox/Kafka/KafkaInboxDispatchIntegrationTestsInbox dispatch to Kafka topic with headers
Dispatch/Outbox/Kafka/KafkaOutboxDispatchIntegrationTestsOutbox dispatch; contract-name route fallback
KafkaDispatchFailureIntegrationTestsUnreachable broker; circuit breaker

Header edge cases, duplicate MessageId idempotency, and full requeue on/off are covered in Ingress/InMemory/ and Ingress/AwsSqs/. The Kafka Docker suite adds end-to-end flow, failure paths, and TransientAcceptFailure_ShouldRedeliverSameOffsetWithoutRestart (partial requeue-enabled redelivery via seek).

AWS SQS (Ingress/AwsSqs/, Dispatch/Inbox/AwsSqs/, Dispatch/Outbox/AwsSqs/)

Test classScenarios
AwsSqsInboxIngressEndToEndIntegrationTestsSQS to ingress to handler
AwsSqsInboxIngressFailureIntegrationTestsUnknown contract, invalid JSON, store full
AwsSqsIngressIdempotencyIntegrationTestsDuplicate MessageId
AwsSqsIngressHeaderEdgeCaseIntegrationTestsHeader edge cases (SQS-specific MessageId behavior)
AwsSqsIngressRequeueBehaviorIntegrationTestsRequeue disabled (drain) vs enabled (transient store failure via FlakyInbox)
AwsSqsInboxDispatchIntegrationTestsInbox dispatch to SQS
AwsSqsOutboxDispatchIntegrationTestsOutbox dispatch; contract-name route fallback
AwsSqsDispatchFailureIntegrationTestsUnreachable broker; circuit breaker

Azure (Ingress/AzureServiceBus/, Dispatch/Inbox/AzureServiceBus/, Dispatch/Outbox/AzureServiceBus/)

Test classScenarios
AzureServiceBusInboxIngressEndToEndIntegrationTestsEmulator ingress E2E
AzureServiceBusInboxIngressFailureIntegrationTestsUnknown contract, invalid JSON, store full
AzureServiceBusIngressRequeueBehaviorIntegrationTestsRequeue enabled (transient store failure via FlakyInbox)
AzureServiceBusInboxDispatchIntegrationTestsInbox dispatch with full LiteBus headers
AzureServiceBusOutboxDispatchIntegrationTestsOutbox dispatch; contract-name route fallback
AzureServiceBusOptionalIntegrationTestsLive namespace only when env vars set; skips otherwise

Registration (Registration/)

Test classScenarios
BrokerDispatchIngressRegistrationTests[Theory] over every broker Use*Dispatch / Use*Ingress extension; asserts TransportInboxDispatcher, IMessageConsumer, etc. resolve without a live broker

Ingress Ack Policy (Cross-Broker)

TransportInboxIngressConsumer discards (no requeue) when acceptance throws:

  • MessageContractNotRegisteredException
  • InboxDispatchException (missing/invalid transport headers)
  • InboxStorageException (capacity / persistence rejection)
  • InvalidOperationException, ArgumentException, FormatException, JsonException

Other failures honor RequeueOnFailure (default true). Unit reference: LiteBus.Inbox.UnitTests/Ingress/TransportInboxIngressConsumerTests.cs.

Coverage Matrix (Ingress)

Legend: yes = broker Docker/emulator integration test; partial = subset of scenarios or covered via another project; - = no broker-specific test (see InMemory for shared ingress behavior).

ScenarioInMemoryKafkaAWSAzureAMQP
Happy-path E2Eyesyesyesyesyes
Unknown contractyesyesyesyesyes
Invalid JSONyesyesyesyesyes
Store fullyesyesyesyesyes
Duplicate MessageIdyes:yes:partial
Header edge casesyes:partial:partial
Requeue on/offyespartialyespartialpartial

Duplicate MessageId: AMQP partial = DuplicateBrokerDelivery_ShouldExecuteHandlerOnce in LiteBus.Storage.IntegrationTests (PostgreSQL + AMQP reliable-messaging chain), not a dedicated ingress-only idempotency test.

Header edge cases: AWS partial = missing contract name, wrong version, invalid MessageId (not missing contract version or wrong CLR shape). AMQP partial = LiteBus.Inbox.UnitTests/Ingress/Amqp/ handler mapping plus failure nack paths in Ingress/Amqp/ (no dedicated header matrix on RabbitMQ).

Requeue on/off: partial = requeue enabled only (RequeueEnabled_WithTransientStoreFailure... or Kafka seek redelivery). Full on/off pairs exist for InMemory and AWS only.

Coverage Matrix (Dispatch)

ScenarioInMemoryKafkaAWSAzureAMQP
Inbox E2E + headersyesyesyesyesyes
Outbox E2E + headersyesyesyesyesyes
Contract-name route fallbackyesyesyesyesyes
Unreachable broker / circuit breaker:yesyes:Transport.IntegrationTests

AMQP ingress and dispatch scenarios live in LiteBus.Durable.IntegrationTests (Ingress/Amqp/, Dispatch/Inbox/Amqp/, Dispatch/Outbox/Amqp/). Low-level AMQP wire behavior is in LiteBus.Transport.IntegrationTests/Amqp/.


PostgreSQL Storage Integration Tests

Project: tests/LiteBus.Storage.IntegrationTests/ Folder: PostgreSql/ Fixture: PostgreSqlFixture (postgres:16-alpine, retry loop, optional LITEBUS_TEST_POSTGRES_CONNECTION_STRING)

What This Project Proves

PostgreSQL is the reference durable store for inbox, outbox, saga, schema management, work signals, and full-stack reliable messaging.

AreaRepresentative testsScenarios
Store contractsPostgreSqlInboxStoreTests, PostgreSqlOutboxStoreTests, retention variantsInherit LiteBus.Storage.Testing contract suites (leasing, idempotency, dead-letter, visibility)
SchemaPostgreSqlInboxSchemaTests, PostgreSqlOutboxSchemaTests, PostgreSqlSchemaDriftTests, PostgreSqlSchemaScriptTestsCreate, validate, idempotent bootstrap, concurrent bootstrap, drift detection
Schema hostingPostgreSqlSchemaHostingTestsIStartupTask initializers: enable/disable, validate-only, second-run idempotency
Processor E2E (inbox)PostgreSqlInboxEndToEndTestsHappy path, handler failure + retry, dead-letter, lease reclaim, deferred visibility, unknown contract
Processor E2E (outbox)PostgreSqlOutboxEndToEndTestsPublish path through PostgreSQL store
Transactional outboxPostgreSqlOutboxTransactionalIntegrationTestsDomain + outbox commit/rollback on shared connection (UseExistingConnection)
Transactional writersPostgreSqlInboxTransactionalIntegrationTests, PostgreSqlTransactionalWritersIntegrationTestsITransactionalInbox / ITransactionalOutbox: manual CreateTransactionalStore, combined inbox+outbox rollback, ambient IPostgreSqlTransactionProvider: see Transactional messaging writes
Hosting / manifestPostgreSqlInboxHostingIntegrationTestsIBackgroundService processor loop, LISTEN/NOTIFY wake, retention cleanup
Work signalsPostgreSqlInboxWorkSignalNotifyTests, PostgreSqlOutboxWorkSignalNotifyTests, *WorkSignalTestsNotify wake vs poll; reconnection after listener break (some quarantined)
Lease stressPostgreSqlInboxProcessorLeaseStressTestsParallel workers to single terminal state per message
Process recoveryPostgreSqlProcessCrashIntegrationTestsChild worker process termination during handler dispatch; lease-expiry recovery by a replacement processor
Persist resultsPostgreSqlInboxStorePersistResultTests, PostgreSqlInboxStoreBatchMarkFailedTestsBatch completion timestamps, lease-lost reporting
SagaPostgreSqlSagaInboxEndToEndTests, PostgreSqlSagaOrchestrationDepthTestsSaga state in PostgreSQL; multi-step workflow; compensation; parallel version safety
Reliable messaging chainPostgreSqlReliableMessagingEndToEndTestsOutbox to RabbitMQ to inbox to in-process handler; duplicate delivery; ingress failures
Cross-store ingressPostgreSqlInboxIngressEndToEndTestsAMQP ingress with PostgreSQL backing store
Module registrationPostgreSqlModuleRegistrationTestsStorage roles, schema flags, processor/ingress manifest entries, invalid combinations
UtilitiesPostgreSqlStorageUtilityTests, PostgreSqlIdentifierTests, PostgreSqlAdvisoryLockScopeTestsConnection factory, SQL identifiers, advisory lock keys

Composite Broker Usage

PostgreSqlReliableMessagingEndToEndTests and PostgreSqlInboxIngressEndToEndTests spin up RabbitMqBrokerFixture inside the test alongside the shared PostgreSQL fixture. That pattern tests storage + broker together without pulling the full durable transport matrix project.

Quarantined Tests

Some work-signal reconnection tests carry [Trait("Category", "Quarantine")] due to timing sensitivity. Exclude them in routine runs if needed:

dotnet test tests/LiteBus.Storage.IntegrationTests --filter "Category!=Quarantine"

Entity Framework Core Storage Integration Tests

Project: tests/LiteBus.Storage.IntegrationTests/ Folders: EntityFrameworkCore/Inbox/, EntityFrameworkCore/Outbox/

Both use the same fixture pattern as PostgreSQL storage (Testcontainers PostgreSQL and SQL Server). Tests use dedicated IntegrationInboxDbContext / IntegrationOutboxDbContext types and EF interceptors where transactional behavior matters.

Inbox EF Core Scenarios

Test classScenarios
EfCoreInboxStorePostgreSqlContractTests, EfCoreInboxStoreSqlServerContractTestsFull inbox store contract on EF Core
EfCoreInboxProcessorEndToEndTestsProcessor happy path through EF store
EfCoreInboxProcessorHandlerFailureEndToEndTestsHandler failure to retry visibility
EfCoreInboxProcessorDeadLetterEndToEndTestsMax attempts to dead-letter
EfCoreInboxProcessorLeaseExpiryEndToEndTestsLease expiry to reclaim
EfCoreInboxProcessorDeferredVisibilityEndToEndTestsVisibleAfter scheduling
EfCoreInboxProcessorUnknownContractEndToEndTestsUnknown contract terminal state
EfCoreInboxDispatchScopeIsolationIntegrationTestsDistinct scoped DbContext per concurrent message and disposal before pass completion
EfCoreInboxSaveChangesInterceptorAbortTestsDuplicate idempotency key aborts transaction

Outbox EF Core Scenarios

Test classScenarios
EfCoreOutboxStorePostgreSqlContractTests, EfCoreOutboxStoreSqlServerContractTestsFull outbox store contract
EfCoreOutboxProcessorEndToEndTestsProcessor publishes through EF store
EfCoreOutboxProcessorDispatcherFailureEndToEndTestsDispatcher failure to retry
EfCoreOutboxProcessorDeadLetterEndToEndTestsMax attempts to dead-letter
EfCoreOutboxProcessorLeaseExpiryEndToEndTestsLease reclaim
EfCoreOutboxProcessorDeferredVisibilityEndToEndTestsDeferred publish
EfCoreOutboxTransactionalIntegrationTestsDbContext transaction rolls back or commits outbox rows with domain changes
EfCoreOutboxSaveChangesInterceptorIntegrationTestsInterceptor persists all envelope fields; rollback behavior

Outbox EF Core PostgreSQL tests can share PostgreSqlCollection for collection-scoped fixture reuse.


AMQP Integration Tests

AMQP coverage spans two projects: low-level wire protocol in LiteBus.Transport.IntegrationTests, and inbox/outbox ingress and dispatch in LiteBus.Durable.IntegrationTests. RabbitMQ and LavinMQ are both exercised where broker differences matter.

LiteBus.Transport.IntegrationTests (Amqp/)

Fixtures: RabbitMqFixture, LavinMqFixture Focus: Wire protocol behavior without inbox/outbox LiteBus.

Test classScenarios
AmqpTransportIntegrationTestsPublish/consume/ack; nack+requeue redelivery; LiteBus header preservation; stop prevents delivery; cancellation; double-start guard; unreachable broker; connection/channel recovery
RabbitMqAmqpTransportIntegrationTests, LavinMqAmqpTransportIntegrationTestsBroker-specific smoke paths
AmqpHeaderValuesTestsHeader parsing helpers (no container)

LiteBus.Durable.IntegrationTests: AMQP Ingress (Ingress/AMQP/)

Fixtures: RabbitMqBrokerFixture, LavinMqBrokerFixture Storage: InMemory inbox (fast ingress focus)

Test classScenarios
AmqpInboxIngressEndToEndTestsRabbitMQ and LavinMQ to accept to process to dispatch
AmqpInboxIngressFailureTestsUnknown contract, invalid JSON, store full to nack without requeue
AmqpInboxIngressBatchIntegrationTestsBatch accept at Safety.BatchSize and Safety.BatchMaxWait
AmqpIngressRequeueBehaviorIntegrationTestsRequeue enabled (transient store failure via FlakyInbox)

LiteBus.Durable.IntegrationTests: AMQP Inbox Dispatch (Dispatch/Inbox/AMQP/)

Test classScenarios
AmqpInboxDispatcherIntegrationTestsInMemory storage to AMQP publish with headers
RabbitMqInboxDispatchIntegrationTests, LavinMqInboxDispatchIntegrationTestsBroker-specific dispatch
PostgreSqlAmqpInboxDispatchIntegrationTestsPostgreSQL store + AMQP dispatch; envelope marked completed in DB

LiteBus.Durable.IntegrationTests: AMQP Outbox Dispatch (Dispatch/Outbox/AMQP/)

Test classScenarios
AmqpOutboxDispatchIntegrationTestsOutbox to AMQP; contract-name routing key fallback; shutdown-token terminal-persist policy after broker publish
PostgreSqlAmqpOutboxDispatchIntegrationTestsPostgreSQL outbox + AMQP; row marked published

Hosting and Composition Integration Tests

These projects validate host adapters without replacing broker or storage matrices. v6 composition smoke is a unit test in LiteBus.Runtime.UnitTests/Runtime/Composition/LiteBusV6CompositionSmokeTests.cs.

LiteBus.Extensions.IntegrationTests: Health Checks (HealthChecks/)

Docker: No Setup: InMemory inbox + registered IDiagnosticCheck probes + AddHealthChecks().AddLiteBus()

ScenarioExpected health
Unhealthy probe registeredUnhealthy
Healthy probe registeredHealthy
No probes registeredDegraded

LiteBus.Extensions.IntegrationTests: OpenTelemetry (OpenTelemetry/)

Docker: No Setup: OpenTelemetry SDK builder with AddLiteBusInboxInstrumentation / metrics extensions

Proves public ActivitySourceName, MeterName, and instrument constants are subscribed correctly (stable consumer contract).

LiteBus.Extensions.IntegrationTests: ASP.NET Core (AspNetCore/)

Docker: Yes (PostgreSQL) Setup: TestServer host with management endpoints mapped; real PostgreSQL inbox/outbox storage

TestScenario
QueryInboxMessages_ReturnsPersistedRowsHTTP query reflects store contents
Purge_WithConfirm_DeletesRowsInStoreOperator purge API
Health_IncludesRegisteredDiagnosticProbeManagement health includes LiteBus probes

Shared Transport Contract Tests

Library: LiteBus.Transport.Testing NuGet package (tests/LiteBus.Transport.Testing/ in this repository)

The abstract TransportContractTests class verifies the common ITransportPublisher and IMessageConsumer contract without depending on a broker SDK. Concrete test classes supply an isolated TransportContractContext containing the adapter instances, consumer endpoint, publish destination and route, and cleanup callback.

ContractRequired behavior
Publish and consumePreserve payload bytes and canonical LiteBus metadata headers
Return to queueDeliver the same payload again before acknowledgement
Pre-cancelled publishThrow OperationCanceledException without accepting the message

LiteBus runs this suite against LiteBus.Transport.InMemory in unit tests and RabbitMQ in Docker integration tests. Custom adapter authors should reference LiteBus.Transport.Testing, derive one concrete xUnit class, and run it against the real broker used by their adapter.


Shared Store Contract Tests

Library: LiteBus.Storage.Testing NuGet package (tests/LiteBus.Storage.Testing/ in this repository)

Abstract test classes define store behavior contracts inherited by InMemory unit tests, PostgreSQL integration tests, and EF Core integration tests. One implementation, many backends.

SuiteCovers (high level)
InboxStoreContractTestsIdempotency, leasing, renewal owner and generation guards, stale terminal-write fencing, attempt counts, dead-letter, retention, diagnostics query, purge
OutboxStoreContractTestsEnqueue, lease, renewal owner and generation guards, stale terminal-write fencing, publish marking, retry visibility, dead-letter

Direct PostgreSQL and EF Core PostgreSQL suites also pass a caller timestamp ten years ahead of database time. The tests verify that future-visible rows remain hidden and that lease expiry uses the database clock. | InboxRetentionStoreContractTests / OutboxRetentionStoreContractTests | Retention-specific roles |

When adding a custom inbox or outbox store, reference LiteBus.Storage.Testing and inherit these suites in your test project before writing provider-specific tests.


Running Integration Tests Locally

Full Solution (Docker Required for Most Integration Projects)

dotnet test LiteBus.slnx

If Docker is not running, PostgreSQL and AMQP integration tests fail during fixture setup. Durable transport Docker and Azure categories skip individual tests where [SkippableFact] is used. CI runs docker info before these suites and treats unavailable Docker as a failed prerequisite, so local skip behavior does not hide a CI environment error.

Unit Tests Only

dotnet test LiteBus.slnx --filter "FullyQualifiedName!~IntegrationTests"

Exclude PostgreSQL Integration Tests

dotnet test LiteBus.slnx --filter "FullyQualifiedName!~PostgreSql"

By Concern

# Broker transport: durable matrix only (CI category batches)
dotnet test tests/LiteBus.Durable.IntegrationTests --filter "Category=TransportFast"
dotnet test tests/LiteBus.Durable.IntegrationTests --filter "Category=TransportDocker"
dotnet test tests/LiteBus.Durable.IntegrationTests --filter "Category=TransportAzure"
dotnet test tests/LiteBus.Durable.IntegrationTests --filter "Category=TransportDocker&FullyQualifiedName~Kafka"

# Broker transport: full solution (matches CI)
dotnet test LiteBus.slnx --filter "Category=TransportFast"
dotnet test LiteBus.slnx --filter "Category=TransportDocker"
dotnet test LiteBus.slnx --filter "Category=TransportAzure"

# PostgreSQL storage only
dotnet test tests/LiteBus.Storage.IntegrationTests --filter "FullyQualifiedName~PostgreSql"

# AMQP ingress only (durable matrix)
dotnet test tests/LiteBus.Durable.IntegrationTests --filter "FullyQualifiedName~Ingress.Amqp"

# AMQP wire protocol only
dotnet test tests/LiteBus.Transport.IntegrationTests

Optional Live Azure Overlay

Set both variables, then run the live Azure category:

export LITEBUS_TEST_AZURE_SERVICEBUS_CONNECTION_STRING="Endpoint=sb://..."
export LITEBUS_TEST_AZURE_SERVICEBUS_QUEUE="your-queue"
dotnet test LiteBus.slnx --filter "Category=TransportLiveAzure"

What This Does Not Cover

  • Unit tests (*UnitTests* projects): handler logic, mappers, module build order, circuit breaker math. Run via the CI unit-test filter.
  • Benchmarks (benchmarks/): performance, not correctness contracts.
  • Production Azure Service Bus as the default CI path: CI uses the emulator; live namespace is opt-in.
  • Every broker on every scenario: see the ingress/dispatch matrices above for intentional gaps (for example Azure duplicate MessageId and header edge cases on emulator, Kafka full requeue on/off, AMQP requeue disabled drain).

Next

  • Testing: InMemory processor recipes, ack policy summary, quick CI filters
  • Testing LiteBus: handler unit tests, mediation pipeline, WebApplicationFactory
  • Hosted services: IStartupTask, IBackgroundService, and manifest registration tested by PostgreSQL hosting integration tests
  • Reliable Messaging: outbox to broker to inbox patterns exercised in PostgreSqlReliableMessagingEndToEndTests

On this page

Integration TestsHow Integration Tests Are OrganizedExecutor InventoryFolder LayoutShared Infrastructure PatternsTestcontainers and ImagesFixture LifetimeDocker Unavailable BehaviorEnvironment Variable Overrides (Local Troubleshooting)Typical Test Shape (Durable Messaging)Broker-Backed Transport Integration TestsxUnit Categories (CI Filters)Fixtures per BrokerShared Test MessagesScenario Classes (by Folder)InMemory (Ingress/InMemory/, Dispatch/Inbox/InMemory/, Dispatch/Outbox/InMemory/)Kafka (Ingress/Kafka/, Dispatch/Inbox/Kafka/, Dispatch/Outbox/Kafka/)AWS SQS (Ingress/AwsSqs/, Dispatch/Inbox/AwsSqs/, Dispatch/Outbox/AwsSqs/)Azure (Ingress/AzureServiceBus/, Dispatch/Inbox/AzureServiceBus/, Dispatch/Outbox/AzureServiceBus/)Registration (Registration/)Ingress Ack Policy (Cross-Broker)Coverage Matrix (Ingress)Coverage Matrix (Dispatch)PostgreSQL Storage Integration TestsWhat This Project ProvesComposite Broker UsageQuarantined TestsEntity Framework Core Storage Integration TestsInbox EF Core ScenariosOutbox EF Core ScenariosAMQP Integration TestsLiteBus.Transport.IntegrationTests (Amqp/)LiteBus.Durable.IntegrationTests: AMQP Ingress (Ingress/AMQP/)LiteBus.Durable.IntegrationTests: AMQP Inbox Dispatch (Dispatch/Inbox/AMQP/)LiteBus.Durable.IntegrationTests: AMQP Outbox Dispatch (Dispatch/Outbox/AMQP/)Hosting and Composition Integration TestsLiteBus.Extensions.IntegrationTests: Health Checks (HealthChecks/)LiteBus.Extensions.IntegrationTests: OpenTelemetry (OpenTelemetry/)LiteBus.Extensions.IntegrationTests: ASP.NET Core (AspNetCore/)Shared Transport Contract TestsShared Store Contract TestsRunning Integration Tests LocallyFull Solution (Docker Required for Most Integration Projects)Unit Tests OnlyExclude PostgreSQL Integration TestsBy ConcernOptional Live Azure OverlayWhat This Does Not CoverNext