Reo.Core.TUnitIntegrationTesting
10.0.281
See the version list below for details.
dotnet add package Reo.Core.TUnitIntegrationTesting --version 10.0.281
NuGet\Install-Package Reo.Core.TUnitIntegrationTesting -Version 10.0.281
<PackageReference Include="Reo.Core.TUnitIntegrationTesting" Version="10.0.281" />
<PackageVersion Include="Reo.Core.TUnitIntegrationTesting" Version="10.0.281" />
<PackageReference Include="Reo.Core.TUnitIntegrationTesting" />
paket add Reo.Core.TUnitIntegrationTesting --version 10.0.281
#r "nuget: Reo.Core.TUnitIntegrationTesting, 10.0.281"
#:package Reo.Core.TUnitIntegrationTesting@10.0.281
#addin nuget:?package=Reo.Core.TUnitIntegrationTesting&version=10.0.281
#tool nuget:?package=Reo.Core.TUnitIntegrationTesting&version=10.0.281
Reo.Core.TUnitIntegrationTesting
Инфраструктура интеграционного тестирования на базе TUnit с общими Docker-контейнерами
(Testcontainers) для всех тестов сборки. TUnit-аналог связки Reo.Core.Xunit.IntegrationTesting +
Reo.Core.IntegrationTesting.
Пакет содержит TUnit-связанную часть: фикстуры хранилищ и привязку их жизненного цикла к TUnit
(TUnitContainerFixture реализует IAsyncInitializer/IAsyncDisposable). Фреймворк-нейтральная база
(абстракции и конкретные контейнеры хранилищ, сидирование, BaseContainerFixture,
TestingPostgresDbContextFactory, RespawnerFacade, построитель тестового хоста) живёт в
Reo.Core.Testing.Common и не зависит от тестового фреймворка.
Парадигма та же, что и в xUnit-версии: один контейнер на все тесты сборки. Контейнер поднимается один раз перед первым тестом, использующим фикстуру, и останавливается после завершения всех тестов сборки.
Как это работает
В xUnit-версии шаринг контейнера обеспечивали сборочные атрибуты и кастомные раннеры. В TUnit тот же результат
достигается штатным механизмом фреймворка — [ClassDataSource<TFixture>(Shared = SharedType.PerAssembly)]:
- TUnit создает ровно один экземпляр фикстуры на сборку;
- при создании фикстуры вызывается
IAsyncInitializer.InitializeAsync()— здесь поднимается контейнер, создается контекст и выполняется сидирование; - после всех тестов сборки вызывается
IAsyncDisposable.DisposeAsync()— контейнер останавливается.
Использование
Подключите пакет в тестовый проект и запросите фикстуру в тестовом классе через свойство:
public class OrderRepositoryTests
{
[ClassDataSource<PostgresFixture<TestingContext>>(Shared = SharedType.PerAssembly)]
public required PostgresFixture<TestingContext> Postgres { get; init; }
[Test]
public async Task Save_order_should_persist_order(CancellationToken cancellationToken)
{
var context = Postgres.DatabaseContextFactory.CreateDbContext();
// ...
}
}
либо через конструктор:
[ClassDataSource<PostgresFixture<TestingContext>>(Shared = SharedType.PerAssembly)]
public class OrderRepositoryTests(PostgresFixture<TestingContext> postgres)
{
[Test]
public async Task Save_order_should_persist_order(CancellationToken cancellationToken)
{
// ...
}
}
Доступные пары «контейнер — фикстура»
| Хранилище | Контейнер | Фикстура |
|---|---|---|
| Postgres 12 | PostgresTestContainer<TDbContext> |
PostgresFixture<TDbContext> |
| Postgres 11.17 (Identity Server, EventsApi) | PostgresIbTestContainer<TDbContext> |
PostgresIbFixture<TDbContext> |
| Mongo 7.0.12 | MongoTestContainer |
MongoFixture |
| Mongo 4.4.6 (GarbageTruckLastPositionTracker, Contracts) | MongoIotTestContainer |
MongoIotFixture |
| Redis | RedisTestContainer |
RedisFixture |
| Elasticsearch | ElasticTestContainer |
ElasticFixture |
| RabbitMq | RabbitMqTestContainer |
RabbitMqFixture |
В отличие от xUnit-версии, объявлять контейнеры сборочным атрибутом не нужно: фикстура сама создает и поднимает
свой контейнер (BaseContainerFixture.CreateContainer()).
Сидирование контейнера
Создайте в тестовом проекте наследника ContainerSeeder<TFixture> (конструктор — без параметров, количество
сидов не ограничено, находятся рефлексией автоматически):
public sealed class AdminUserSeeder : ContainerSeeder<PostgresFixture<TestingContext>>
{
protected override async Task SeedAsync(PostgresFixture<TestingContext> fixture)
{
var context = fixture.DatabaseContextFactory.CreateDbContext();
// наполнение базы тестовыми данными
}
}
Сиды выполняются один раз при старте контейнера и повторно после каждой очистки.
Очистка контейнера
Между тестами состояние контейнера откатывается вызовом CleanupAsync() — например, из хука [After(Test)]
или [After(Class)]:
[After(Test)]
public async Task Cleanup() => await Postgres.CleanupAsync();
Для Postgres очистка откатывает базу к чекпоинту (Respawn), для Mongo — удаляет все несистемные коллекции.
AutoMocker
Расширения для Moq.AutoMock повторяют xUnit-версию:
_mocker
.SetupPostgres(postgresFixture)
.SetupMongo(mongoFixture)
.SetupElastic(elasticFixture)
.SetupRedis(redisFixture);
Для Postgres доступны перехватчики EF Core: fixture.WithInterceptors([...]).
Миграция с Reo.Core.Xunit.IntegrationTesting
| xUnit | TUnit |
|---|---|
[assembly: EnableIntegrationTestingFramework] |
не нужен |
[assembly: RaiseContainer<TContainer>] |
не нужен — фикстура создает контейнер сама |
ICollectionFixture<T> / IClassFixture<T> |
[ClassDataSource<T>(Shared = SharedType.PerAssembly)] |
IAsyncLifetime у фикстуры |
IAsyncInitializer + IAsyncDisposable (подключаются через базовый класс TUnitContainerFixture) |
BaseContainerFixture(FixtureContext) + конструктор фикстуры |
фикстура без параметров; контекст доступен в хуках InitializeCoreAsync / AfterSeedCoreAsync и после инициализации |
fixture.CleanupAsync() |
без изменений |
ContainerSeeder<TFixture> |
без изменений |
Замечания
- Тесты, использующие общий контейнер, стоит помечать
[NotInParallel](или ограничивать параллелизм на уровне сборки): контейнер — общий ресурс, параллельная очистка/запись приведет к конфликтам. В xUnit-версии параллелизация отключалась принудительно кастомным раннером. - Для работы тестов требуется запущенный Docker.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- AspNetCore.HealthChecks.Elasticsearch (>= 9.0.0)
- AspNetCore.HealthChecks.MongoDb (>= 9.0.0)
- AspNetCore.HealthChecks.NpgSql (>= 9.0.0)
- AspNetCore.HealthChecks.Redis (>= 9.0.0)
- AspNetCore.HealthChecks.UI.Client (>= 9.0.0)
- AwesomeAssertions (>= 9.5.0)
- AwesomeAssertions.Analyzers (>= 9.0.8)
- Bogus (>= 35.6.5)
- Duende.IdentityModel (>= 8.1.0)
- ertelecom.Serilog.Sinks.Graylog (>= 1.1.0)
- FluentValidation (>= 12.1.1)
- FluentValidation.AspNetCore (>= 11.3.1)
- Flurl (>= 4.0.0)
- Flurl.Http (>= 4.0.2)
- Flurl.Http.Newtonsoft (>= 0.9.1)
- Humanizer (>= 3.0.10)
- Humanizer.Core (>= 3.0.10)
- Humanizer.Core.ru (>= 3.0.10)
- JetBrains.Annotations (>= 2026.2.0)
- LinqKit.Core (>= 1.2.11)
- MassTransit (>= 8.5.10 && < 9.0.0)
- MassTransit.Abstractions (>= 8.5.10 && < 9.0.0)
- MassTransit.RabbitMQ (>= 8.5.10 && < 9.0.0)
- Meziantou.FluentAssertionsAnalyzers (>= 1.0.22)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 10.0.10)
- Microsoft.AspNetCore.Authentication.OpenIdConnect (>= 10.0.10)
- Microsoft.AspNetCore.Mvc.NewtonsoftJson (>= 10.0.10)
- Microsoft.AspNetCore.TestHost (>= 10.0.10)
- Microsoft.Bcl.AsyncInterfaces (>= 10.0.10)
- Microsoft.CodeAnalysis.Analyzers (>= 3.11.0)
- Microsoft.CodeAnalysis.Common (>= 5.0.0)
- Microsoft.CodeAnalysis.CSharp (>= 5.0.0)
- Microsoft.CodeAnalysis.CSharp.Workspaces (>= 5.0.0)
- Microsoft.CodeAnalysis.Workspaces.Common (>= 5.0.0)
- Microsoft.CodeAnalysis.Workspaces.MSBuild (>= 5.0.0)
- Microsoft.EntityFrameworkCore (>= 10.0.10)
- Microsoft.EntityFrameworkCore.Design (>= 10.0.10)
- Microsoft.EntityFrameworkCore.InMemory (>= 10.0.10)
- Microsoft.EntityFrameworkCore.Relational (>= 10.0.10)
- Microsoft.Extensions.Caching.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Caching.Memory (>= 10.0.10)
- Microsoft.Extensions.Caching.StackExchangeRedis (>= 10.0.10)
- Microsoft.Extensions.Configuration (>= 10.0.10)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.10)
- Microsoft.Extensions.DependencyInjection (>= 10.0.10)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore (>= 10.0.10)
- Microsoft.Extensions.Diagnostics.Testing (>= 10.8.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Http.Polly (>= 10.0.10)
- Microsoft.Extensions.Logging (>= 10.0.10)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Options (>= 10.0.10)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.10)
- Microsoft.Extensions.TimeProvider.Testing (>= 10.8.0)
- MongoDB.Analyzer (>= 2.0.0)
- MongoDB.Driver (>= 3.10.0)
- Moq.Analyzers (>= 0.4.2)
- Moq.AutoMock (>= 4.0.2)
- NEST (>= 7.17.5)
- NEST.JsonNetSerializer (>= 7.17.5)
- Newtonsoft.Json (>= 13.0.4)
- Npgsql.EntityFrameworkCore.PostgreSQL (>= 10.0.3)
- Polly (>= 8.5.0)
- RabbitMQ.Client (>= 7.2.1)
- RedLock.net (>= 2.3.2)
- Reo.Core.Database (>= 10.0.281)
- Reo.Core.Elastic (>= 10.0.281)
- Reo.Core.Logging (>= 10.0.281)
- Reo.Core.MongoDB (>= 10.0.281)
- Reo.Core.Testing.Common (>= 10.0.281)
- Reo.Models.StronglyTyped (>= 1.0.39)
- Reo.Models.StronglyTyped.MongoDb (>= 1.0.39)
- Respawn (>= 7.0.0)
- Serilog (>= 4.4.0)
- Serilog.AspNetCore (>= 10.0.0)
- SharpCompress (>= 0.48.1)
- stbychkov.AutoLoggerMessage (>= 1.0.17)
- Swashbuckle.AspNetCore (>= 10.2.3)
- System.ComponentModel.Annotations (>= 5.0.0)
- System.IO.Abstractions (>= 22.2.0)
- System.Linq.Async (>= 7.0.1)
- TestableIO.System.IO.Abstractions (>= 22.2.0)
- TestableIO.System.IO.Abstractions.TestingHelpers (>= 22.2.0)
- Testcontainers (>= 4.13.0)
- Testcontainers.Elasticsearch (>= 4.13.0)
- Testcontainers.MongoDb (>= 4.13.0)
- Testcontainers.PostgreSql (>= 4.13.0)
- Testcontainers.RabbitMq (>= 4.13.0)
- Testcontainers.Redis (>= 4.13.0)
- TUnit.Core (>= 1.61.38)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.