Testing Guide
This guide covers running and writing tests for Surgewave.
Running Tests
Unit Tests
# Run all unit tests
dotnet test
# Run specific test project
dotnet test tests/Kuestenlogik.Surgewave.Core.Tests
# Run with verbose output
dotnet test --logger "console;verbosity=detailed"
# Run tests matching a pattern
dotnet test --filter "FullyQualifiedName~Producer"
Integration Tests
Integration tests require Docker:
# Run integration tests
dotnet test tests/Kuestenlogik.Surgewave.IntegrationTests
# Run specific integration test
dotnet test tests/Kuestenlogik.Surgewave.IntegrationTests --filter "KRaft"
Benchmarks
cd benchmarks/Kuestenlogik.Surgewave.Benchmarks
# Run all benchmarks
dotnet run -c Release
# Run specific benchmark
dotnet run -c Release -- --filter "*Producer*"
# Generate comparison report
dotnet run -c Release -- --filter "*" --exporters json
Test Categories
| Category | Location | Purpose |
|---|---|---|
| Unit Tests | tests/Kuestenlogik.Surgewave.*.Tests/ |
Test individual components |
| Integration Tests | tests/Kuestenlogik.Surgewave.IntegrationTests/ |
Test component interactions |
| Kafka Compatibility | tests/Kuestenlogik.Surgewave.KafkaCompat.Tests/ |
Verify Kafka client compatibility |
| Benchmarks | benchmarks/Kuestenlogik.Surgewave.Benchmarks/ |
Performance measurements |
Writing Tests
Unit Test Example
public class TopicManagerTests
{
[Fact]
public async Task CreateTopic_WithValidConfig_Succeeds()
{
// Arrange
var storage = new MemoryStorageEngine();
var manager = new TopicManager(storage);
// Act
var result = await manager.CreateTopicAsync("test-topic", partitions: 3);
// Assert
Assert.True(result.Success);
Assert.Equal(3, result.Topic.PartitionCount);
}
}
Integration Test with Embedded Broker
public class ProducerIntegrationTests : IAsyncLifetime
{
private EmbeddedSurgewave _broker;
public async Task InitializeAsync()
{
_broker = new EmbeddedSurgewave(options =>
{
options.Port = 19092;
options.Storage = StorageBackend.Memory;
});
await _broker.StartAsync();
}
public async Task DisposeAsync()
{
await _broker.DisposeAsync();
}
[Fact]
public async Task Produce_AndConsume_RoundTrip()
{
// Test code here
}
}
Kafka Compatibility Test
public class KafkaClientCompatibilityTests
{
[Fact]
public async Task ConfluentKafka_CanProduceAndConsume()
{
var config = new ProducerConfig
{
BootstrapServers = "localhost:9092"
};
using var producer = new ProducerBuilder<string, string>(config).Build();
var result = await producer.ProduceAsync("test",
new Message<string, string> { Key = "k", Value = "v" });
Assert.NotNull(result);
}
}
Test Utilities
TestFixtures
// Use shared broker across tests
public class SharedBrokerFixture : IAsyncLifetime
{
public EmbeddedSurgewave Broker { get; private set; }
public async Task InitializeAsync()
{
Broker = new EmbeddedSurgewave();
await Broker.StartAsync();
}
public async Task DisposeAsync() => await Broker.DisposeAsync();
}
// Use in test class
public class MyTests : IClassFixture<SharedBrokerFixture>
{
private readonly SharedBrokerFixture _fixture;
public MyTests(SharedBrokerFixture fixture) => _fixture = fixture;
}
Continuous Integration
Tests run automatically on:
- Pull requests
- Pushes to main branch
GitHub Actions
- name: Test
run: dotnet test --configuration Release --no-build --verbosity normal
Coverage Reports
# Generate coverage report
dotnet test --collect:"XPlat Code Coverage"
# View report (requires reportgenerator)
reportgenerator -reports:**/coverage.cobertura.xml -targetdir:coverage-report