diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e29e26..8c0efad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,20 @@ # Changelog ## v5.0.0 +### ✨ Features + +- Dependency injection is now at the Environment level + - Create a `IDependencyInjectionConfigurator` + ```csharp + public class DependencyInjectionConfigurator : IDependencyInjectionConfigurator + { + public IServiceCollection ConfigureServices(IServiceCollection services) => services; + } + ``` + - Add a `[InjectionConfigurator(typeof(DependencyInjectionConfigurator))]` to the test class. + - You could add multiple `InjectionConfiguratorAttribute` to the same test class (or parents), they will all be used. + - Add dependencies to the environment/infrastructure constructor ! + ### 💥 Breaking Changes - Deleted support for Extensions, use dependency injection instead. diff --git a/NotoriousTest.Core/DI/DependencyInjectionConfigurator.cs b/NotoriousTest.Core/DI/DependencyInjectionConfigurator.cs new file mode 100644 index 0000000..1a55ada --- /dev/null +++ b/NotoriousTest.Core/DI/DependencyInjectionConfigurator.cs @@ -0,0 +1,8 @@ +using Microsoft.Extensions.DependencyInjection; + +namespace NotoriousTest.Core.DI; + +public class DependencyInjectionConfigurator : IDependencyInjectionConfigurator +{ + public IServiceCollection ConfigureServices(IServiceCollection services) => services; +} diff --git a/NotoriousTest.Core/DI/IDependencyInjectionConfigurator.cs b/NotoriousTest.Core/DI/IDependencyInjectionConfigurator.cs new file mode 100644 index 0000000..d525761 --- /dev/null +++ b/NotoriousTest.Core/DI/IDependencyInjectionConfigurator.cs @@ -0,0 +1,8 @@ +using Microsoft.Extensions.DependencyInjection; + +namespace NotoriousTest.Core.DI; + +public interface IDependencyInjectionConfigurator +{ + IServiceCollection ConfigureServices(IServiceCollection services); +} diff --git a/NotoriousTest.Core/DI/InjectionConfiguratorAttribute.cs b/NotoriousTest.Core/DI/InjectionConfiguratorAttribute.cs new file mode 100644 index 0000000..635ecc0 --- /dev/null +++ b/NotoriousTest.Core/DI/InjectionConfiguratorAttribute.cs @@ -0,0 +1,7 @@ +namespace NotoriousTest.Core.DI; + +[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] +public class InjectionConfiguratorAttribute(Type diConfiguratorType) : Attribute +{ + public Type DIConfiguratorType { get; } = diConfiguratorType; +} diff --git a/NotoriousTest.Core/EnvironmentId.cs b/NotoriousTest.Core/EnvironmentId.cs index af6e1cc..7f3832b 100644 --- a/NotoriousTest.Core/EnvironmentId.cs +++ b/NotoriousTest.Core/EnvironmentId.cs @@ -4,5 +4,8 @@ public record EnvironmentId(Guid Value) { public static implicit operator Guid(EnvironmentId wrapper) => wrapper.Value; public static implicit operator EnvironmentId(Guid guid) => new(guid); + + + public static EnvironmentId Create() => new(Guid.NewGuid()); } } diff --git a/NotoriousTest.Core/Environments/EnvironmentBase.cs b/NotoriousTest.Core/Environments/EnvironmentBase.cs index e1f4d14..0cf261a 100644 --- a/NotoriousTest.Core/Environments/EnvironmentBase.cs +++ b/NotoriousTest.Core/Environments/EnvironmentBase.cs @@ -23,37 +23,31 @@ public abstract class EnvironmentBase /// /// Gets the unique identifier for the environment instance. /// - public EnvironmentId EnvironmentId { get; private set; } = Guid.NewGuid(); + public EnvironmentId EnvironmentId { get; } = EnvironmentId.Create(); public abstract Assembly CurrentAssembly { get; } + protected IWatchDog WatchDog { get; } + protected IRegistry Registry { get; } + protected IRuntime Runtime { get; } + protected ITestLogger Logger { get; } + protected IServiceProvider ServiceProvider { get; } - protected IServiceProvider ServiceProvider { get; private set; } - private IServiceCollection _serviceCollection; - protected IWatchDog WatchDog => field ??= ServiceProvider.GetRequiredService(); - protected IRegistry Registry => field ??= ServiceProvider.GetRequiredService(); - protected IRuntime Runtime => field ??= ServiceProvider.GetRequiredService(); - protected ITestLogger Logger => field ??= ServiceProvider.GetRequiredService(); - - protected EnvironmentConfiguration Settings => field ??= - ServiceProvider.GetRequiredService() - ?.Get(EnvironmentConfiguration.SECTION_NAME) ?? new EnvironmentConfiguration(); - - - /// - /// Define current test assembly. - /// + protected EnvironmentSettings Settings { get; } + public EnvironmentBase(EnvironmentSettings settings, IWatchDog watchDog, IRegistry registry, IRuntime runtime, ITestLogger logger, IServiceProvider serviceProvider) + { + Settings = settings; + WatchDog = watchDog; + Registry = registry; + Runtime = runtime; + Logger = logger; + ServiceProvider = serviceProvider; + } /// /// Gets the collection of infrastructure components associated with this instance. /// private List _infrastructures = []; - /// - /// Configuration infrastructure dependency injection. - /// - /// - protected virtual void ConfigureInfrastructureServices(IServiceCollection collection) => _serviceCollection.AddSingleton(EnvironmentId); - /// /// Configure environment with infrastructures. Called before environment initialization. /// @@ -79,7 +73,7 @@ public T GetInfrastructure() where T : Infrastructure /// Add an infrastructure within environment. /// public EnvironmentBase AddInfrastructure() where T : Infrastructure - => AddInfrastructure(ActivatorUtilities.CreateInstance(ServiceProvider)); + => AddInfrastructure(ActivatorUtilities.CreateInstance(ServiceProvider, EnvironmentId)); /// /// Add an infrastructure within environment. @@ -101,10 +95,7 @@ public EnvironmentBase AddInfrastructure(Infrastructure infrastructure) /// A task that represents the asynchronous initialization operation. public virtual async Task Initialize() { - _serviceCollection = new ServiceCollection(); // Setup registry - ConfigureInfrastructureServices(_serviceCollection); - ServiceProvider = _serviceCollection.BuildServiceProvider(); if (!Settings.DisableWatchdog) { await SetupRegistry(); @@ -117,7 +108,7 @@ public virtual async Task Initialize() private async Task InitializeInfrastructureInParralelAndInOrder() { - var infrastructureGroupedByOrder = _infrastructures.OrderBy(i => i.Order).GroupBy(i => i.Order); + IEnumerable> infrastructureGroupedByOrder = _infrastructures.OrderBy(i => i.Order).GroupBy(i => i.Order); var action = new Func(async (i) => { @@ -128,10 +119,10 @@ private async Task InitializeInfrastructureInParralelAndInOrder() await i.InitializeAsync(); }); - foreach (var infrastructureGroup in infrastructureGroupedByOrder) + foreach (IGrouping infrastructureGroup in infrastructureGroupedByOrder) { - var nonConsumers = infrastructureGroup.Where(i => i is not IConfigurationConsumer); - var consumers = infrastructureGroup.Where(i => i is IConfigurationConsumer); + IEnumerable nonConsumers = infrastructureGroup.Where(i => i is not IConfigurationConsumer); + IEnumerable consumers = infrastructureGroup.Where(i => i is IConfigurationConsumer); await Task.WhenAll(nonConsumers.Select(i => action(i))); await Task.WhenAll(consumers.Select(i => action(i))); } @@ -141,17 +132,13 @@ private async Task StartDoggyDog() { RuntimeConfiguration? runtimeConfiguration = Runtime.GetSupportedRuntimes(CurrentAssembly); if (runtimeConfiguration == null) - Logger.Log($"Runtime for {CurrentAssembly.FullName} cannot be found. Cleaner resolution may not work properly."); + Logger.Log($"Runtime for {CurrentAssembly.FullName} cannot be found. Cleaner resolution may not work properly.", EnvironmentId); IEnumerable? runtimesPath = runtimeConfiguration?.SupportedFrameworks?.Select(sf => sf.FilePath); WatchDog.Start(CurrentAssembly, Process.GetCurrentProcess().Id, EnvironmentId, runtimesPath); } - public virtual async Task Reset() - { - await ExecuteActionOnInfrastructureInParralelAndInOrder((i) => i.AutoReset ? i.ResetAsync() : Task.CompletedTask); - - } + public virtual async Task Reset() => await ExecuteActionOnInfrastructureInParralelAndInOrder((i) => i.AutoReset ? i.ResetAsync() : Task.CompletedTask); public virtual async Task Destroy() { @@ -164,22 +151,18 @@ public virtual async Task Destroy() private async Task ExecuteActionOnInfrastructureInParralelAndInOrder(Func action) { - var infrastructureGroupedByOrder = _infrastructures.OrderBy(i => i.Order).GroupBy(i => i.Order); - foreach (var infrastructure in infrastructureGroupedByOrder) + IEnumerable> infrastructureGroupedByOrder = _infrastructures.OrderBy(i => i.Order).GroupBy(i => i.Order); + foreach (IGrouping infrastructure in infrastructureGroupedByOrder) { await Task.WhenAll(infrastructure.Select(action)); } } - - - private List> AggregateInfrastructureConfiguration() - { - return _infrastructures - .Where(i => i is IConfigurationProducer) - .SelectMany(i => (i as IConfigurationProducer).OutputConfiguration) - .ToList(); - } + private List> AggregateInfrastructureConfiguration() => + _infrastructures + .Where(i => i is IConfigurationProducer) + .SelectMany(i => (i as IConfigurationProducer)!.OutputConfiguration) + .ToList(); private Task SetupRegistry() => Registry.Ensure(); } diff --git a/NotoriousTest.Core/Environments/EnvironmentConfiguration.cs b/NotoriousTest.Core/Environments/EnvironmentSettings.cs similarity index 54% rename from NotoriousTest.Core/Environments/EnvironmentConfiguration.cs rename to NotoriousTest.Core/Environments/EnvironmentSettings.cs index 270da78..ba29658 100644 --- a/NotoriousTest.Core/Environments/EnvironmentConfiguration.cs +++ b/NotoriousTest.Core/Environments/EnvironmentSettings.cs @@ -1,8 +1,8 @@ namespace NotoriousTest.Core.Environments { - public class EnvironmentConfiguration + public class EnvironmentSettings { public static string SECTION_NAME = "Environment"; - public bool DisableWatchdog { get; set; } = false; + public bool DisableWatchdog { get; init; } } } diff --git a/NotoriousTest.Core/Fixture.cs b/NotoriousTest.Core/Fixture.cs new file mode 100644 index 0000000..dec620e --- /dev/null +++ b/NotoriousTest.Core/Fixture.cs @@ -0,0 +1,42 @@ +using System.Reflection; +using Microsoft.Extensions.DependencyInjection; +using NotoriousTest.Core.Environments; +using NotoriousTest.Core.DI; + +namespace NotoriousTest.Core; + +public class Fixture where TEnvironment : EnvironmentBase +{ + public TEnvironment Environment { get; private set; } + protected Type? TestClass { get; } + protected IDependencyInjectionConfigurator[] InjectionConfigurators => field ??= GetInjectionConfigurators(); + private readonly IServiceProvider _services; + + public Fixture(Type? testClass) + { + TestClass = testClass; + _services = ConfigureServiceCollection(); + Environment = InstantiateEnvironment(_services); + } + + private TEnvironment InstantiateEnvironment(IServiceProvider provider) => ActivatorUtilities.CreateInstance(provider); + + private IServiceProvider ConfigureServiceCollection() + { + IServiceCollection services = new ServiceCollection(); + + foreach (IDependencyInjectionConfigurator dependencyInjectionConfigurator in InjectionConfigurators) + { + dependencyInjectionConfigurator.ConfigureServices(services); + } + + return services.BuildServiceProvider(); + } + + private IDependencyInjectionConfigurator[] GetInjectionConfigurators() + { + IEnumerable diConfiguratorTypes = TestClass!.GetCustomAttributes() + .Select(ic => ic.DIConfiguratorType).ToArray(); + return diConfiguratorTypes.Select((dic) => Activator.CreateInstance(dic) as IDependencyInjectionConfigurator).Where(dic => dic is not null).ToArray()!; + } +} diff --git a/NotoriousTest.Core/Infrastructures/Infrastructure.cs b/NotoriousTest.Core/Infrastructures/Infrastructure.cs index 0e212bc..2f2765f 100644 --- a/NotoriousTest.Core/Infrastructures/Infrastructure.cs +++ b/NotoriousTest.Core/Infrastructures/Infrastructure.cs @@ -46,8 +46,8 @@ public abstract class Infrastructure : IAsyncDisposable, IInfrastructure /// public bool AutoReset { get; set; } = true; - public virtual bool DisableRegistry { get; } = false; - internal bool WatchdogDisabled { get; set; } = false; + public virtual bool DisableRegistry => false; + internal bool WatchdogDisabled { get; set; } /// public EnvironmentId EnvironmentId { get; set; } public Guid Id = Guid.NewGuid(); @@ -59,13 +59,13 @@ public abstract class Infrastructure : IAsyncDisposable, IInfrastructure /// /// Gets the logger instance used to record test execution details and diagnostic information. /// - protected ITestLogger Logger { get; private set; } + protected ITestLogger Logger { get; } /// /// Gets the registry provider used to track infrastructure and clean them after test crash. /// - protected IRegistry Registry { get; private set; } - protected bool Registered { get; private set; } = false; + protected IRegistry Registry { get; } + protected bool Registered { get; private set; } public Infrastructure(EnvironmentId contextId, ITestLogger logger, IRegistry provider) { @@ -75,10 +75,7 @@ public Infrastructure(EnvironmentId contextId, ITestLogger logger, IRegistry pro } public abstract Task Initialize(); - public virtual Task Reset() - { - return Task.CompletedTask; - } + public virtual Task Reset() => Task.CompletedTask; public abstract Task Destroy(); public async ValueTask DisposeAsync() @@ -90,18 +87,18 @@ internal async Task InitializeAsync() { try { - Logger.Log($"[{GetType().Name}] Initialization ..."); + Logger.Log($"[{GetType().Name}] Initialization ...", EnvironmentId); var sw = Stopwatch.StartNew(); await Initialize(); if (!WatchdogDisabled && !DisableRegistry && !Registered) await Register(); - Logger.Log($"[{GetType().Name}] Initialization completed in {sw.ElapsedMilliseconds} ms"); + Logger.Log($"[{GetType().Name}] Initialization completed in {sw.ElapsedMilliseconds} ms", EnvironmentId); } catch (Exception ec) { - Logger.Log("Initialization failed with exception: " + ec.ToString()); + Logger.Log("Initialization failed with exception: " + ec, EnvironmentId); await Destroy(); throw; } @@ -123,23 +120,23 @@ await Registry.Register(new InfrastuctureRegistryEntry() internal async Task ResetAsync() { - Logger.Log($"[{GetType().Name}] Reset ..."); + Logger.Log($"[{GetType().Name}] Reset ...", EnvironmentId); var sw = Stopwatch.StartNew(); await Reset(); if (!WatchdogDisabled && !DisableRegistry) await Registry.NotifyReset(Id); - Logger.Log($"[{GetType().Name} ] Reset completed in {sw.ElapsedMilliseconds} ms"); + Logger.Log($"[{GetType().Name} ] Reset completed in {sw.ElapsedMilliseconds} ms", EnvironmentId); } internal async Task DestroyAsync() { - Logger.Log($"[{GetType().Name}] Destroy ..."); + Logger.Log($"[{GetType().Name}] Destroy ...", EnvironmentId); var sw = Stopwatch.StartNew(); await Destroy(); if (!WatchdogDisabled && !DisableRegistry) await Registry.Remove(Id); - Logger.Log($"[{GetType().Name} ] Destroy completed in {sw.ElapsedMilliseconds} ms"); + Logger.Log($"[{GetType().Name} ] Destroy completed in {sw.ElapsedMilliseconds} ms", EnvironmentId); } } diff --git a/NotoriousTest.Core/IntegrationTestBase.cs b/NotoriousTest.Core/IntegrationTestBase.cs new file mode 100644 index 0000000..27a0c46 --- /dev/null +++ b/NotoriousTest.Core/IntegrationTestBase.cs @@ -0,0 +1,14 @@ +using NotoriousTest.Core.DI; +using NotoriousTest.Core.Environments; + +namespace NotoriousTest.Core; + +[InjectionConfigurator(typeof(DependencyInjectionConfigurator))] +public abstract class IntegrationTestBase where T : EnvironmentBase +{ + protected T Environment => Fixture.Environment; + [Obsolete("Use Environment instead")] + protected T CurrentEnvironment => Fixture.Environment; + protected Fixture Fixture { get; set; } + +} diff --git a/NotoriousTest.Core/Logger/ITestLogger.cs b/NotoriousTest.Core/Logger/ITestLogger.cs index f846a7d..1bbb1c1 100644 --- a/NotoriousTest.Core/Logger/ITestLogger.cs +++ b/NotoriousTest.Core/Logger/ITestLogger.cs @@ -2,6 +2,6 @@ { public interface ITestLogger { - void Log(string message); + void Log(string message, EnvironmentId environmentId); } } diff --git a/NotoriousTest.Core/NotoriousTest.Core.csproj b/NotoriousTest.Core/NotoriousTest.Core.csproj index a963728..c9294e2 100644 --- a/NotoriousTest.Core/NotoriousTest.Core.csproj +++ b/NotoriousTest.Core/NotoriousTest.Core.csproj @@ -15,6 +15,10 @@ - + + + + + diff --git a/NotoriousTest.Core/Runtime/IRuntime.cs b/NotoriousTest.Core/Runtime/IRuntime.cs index 6016c48..b5d9556 100644 --- a/NotoriousTest.Core/Runtime/IRuntime.cs +++ b/NotoriousTest.Core/Runtime/IRuntime.cs @@ -4,6 +4,6 @@ namespace NotoriousTest.Core.Runtime { public interface IRuntime { - public RuntimeConfiguration GetSupportedRuntimes(Assembly assembly); + RuntimeConfiguration? GetSupportedRuntimes(Assembly assembly); } } diff --git a/NotoriousTest.Database/DatabaseInfrastructureBase.cs b/NotoriousTest.Database/DatabaseInfrastructureBase.cs index 6bd8c7b..65de608 100644 --- a/NotoriousTest.Database/DatabaseInfrastructureBase.cs +++ b/NotoriousTest.Database/DatabaseInfrastructureBase.cs @@ -74,7 +74,7 @@ public override async Task Reset() catch (InvalidOperationException ex) { // This can occur if the database has no tables. In that case, we can ignore the exception and continue with the test setup. - Logger.Log(ex.Message); + Logger.Log(ex.Message, EnvironmentId); } diff --git a/NotoriousTest.IntegrationTests/DoggyDog/DoggyDogTests.cs b/NotoriousTest.IntegrationTests/DoggyDog/DoggyDogTestsBase.cs similarity index 87% rename from NotoriousTest.IntegrationTests/DoggyDog/DoggyDogTests.cs rename to NotoriousTest.IntegrationTests/DoggyDog/DoggyDogTestsBase.cs index 6849ab5..93666af 100644 --- a/NotoriousTest.IntegrationTests/DoggyDog/DoggyDogTests.cs +++ b/NotoriousTest.IntegrationTests/DoggyDog/DoggyDogTestsBase.cs @@ -6,13 +6,12 @@ using System.Diagnostics; using System.Text; using NotoriousTest.Core.Registry; -using NotoriousTest.IntegrationTests.Infrastructure; using NotoriousTest.IntegrationTests.SystemUnderTest; namespace NotoriousTest.IntegrationTests.DoggyDog { - public class DoggyDogTests(NotoriousTestEnvironment environment) + public class DoggyDogTestsBase(XUnitFixture environment) : IntegrationTest(environment) { private const int FAKE_PROCESS_WAIT_TIME = 1; @@ -23,9 +22,9 @@ public async Task DoggyDog_Should_Do_Nothing_When_Process_Exit_Normally() Guid environmentId = Guid.NewGuid(); Process? process = DoggyDogTestFramework.Arrange.StartFakeProcess(environmentId, timeToExit: FAKE_PROCESS_WAIT_TIME); - SqliteInfrastructure registry = CurrentEnvironment.GetInfrastructure(); + SqliteInfrastructure registry = Environment.GetInfrastructure(); - (Process doggyDogProcess, StringBuilder stdoutBuilder) = DoggyDogTestFramework.Act.StartDoggyDog(process.Id, typeof(DoggyDogTests).Assembly.Location, registry.GetDatabaseConnectionString(), environmentId); + (Process doggyDogProcess, StringBuilder stdoutBuilder) = DoggyDogTestFramework.Act.StartDoggyDog(process.Id, typeof(DoggyDogTestsBase).Assembly.Location, registry.GetDatabaseConnectionString(), environmentId); await doggyDogProcess.WaitForExitAsync(TestContext.Current.CancellationToken); string stdout = stdoutBuilder.ToString(); @@ -39,13 +38,13 @@ public async Task DoggyDog_Should_Do_Nothing_When_Process_Exit_Normally() public async Task DoggyDog_Should_Cleanup_Orphan_Infrastructures_When_Process_Exit_Abnormally() { var environmentId = Guid.NewGuid(); - SqliteInfrastructure registry = CurrentEnvironment.GetInfrastructure(); + SqliteInfrastructure registry = Environment.GetInfrastructure(); Process process = DoggyDogTestFramework.Arrange.StartFakeProcess(environmentId, exitCode: 1, timeToExit: FAKE_PROCESS_WAIT_TIME); InfrastuctureRegistryEntry fakeEntry = await DoggyDogTestFramework.Arrange.CreateInfrastructureInRegistry(registry, process, typeof(DoggyDogTestFramework.Arrange.FakeInfrastructureWithCleaner), environmentId); - (Process doggyDogProcess, StringBuilder stdoutBuilder) = DoggyDogTestFramework.Act.StartDoggyDog(process.Id, typeof(DoggyDogTests).Assembly.Location, registry.GetDatabaseConnectionString(), environmentId); + (Process doggyDogProcess, StringBuilder stdoutBuilder) = DoggyDogTestFramework.Act.StartDoggyDog(process.Id, typeof(DoggyDogTestsBase).Assembly.Location, registry.GetDatabaseConnectionString(), environmentId); await doggyDogProcess.WaitForExitAsync(TestContext.Current.CancellationToken); @@ -62,10 +61,10 @@ public async Task DoggyDog_Should_Cleanup_Orphan_Infrastructures_When_Process_Ex public async Task DoggyDog_Should_Exit_When_Monitored_Process_Not_Found() { var environmentId = Guid.NewGuid(); - SqliteInfrastructure registry = CurrentEnvironment.GetInfrastructure(); + SqliteInfrastructure registry = Environment.GetInfrastructure(); const int PROCESS_ID = 999999; - (Process doggyDogProcess, StringBuilder stdoutBuilder) = DoggyDogTestFramework.Act.StartDoggyDog(PROCESS_ID, typeof(DoggyDogTests).Assembly.Location, registry.GetDatabaseConnectionString(), environmentId); + (Process doggyDogProcess, StringBuilder stdoutBuilder) = DoggyDogTestFramework.Act.StartDoggyDog(PROCESS_ID, typeof(DoggyDogTestsBase).Assembly.Location, registry.GetDatabaseConnectionString(), environmentId); await doggyDogProcess.WaitForExitAsync(TestContext.Current.CancellationToken); @@ -83,7 +82,7 @@ public async Task DoggyDog_Should_Exit_When_Registry_File_Not_Found() const string FAKE_REGISTRY_PATH = "C:\\fake\\path\\registry.db"; const string FAKE_CONNECTION_STRING = $"DataSource={FAKE_REGISTRY_PATH}"; - (Process doggyDogProcess, StringBuilder stdoutBuilder) = DoggyDogTestFramework.Act.StartDoggyDog(process.Id, typeof(DoggyDogTests).Assembly.Location, FAKE_CONNECTION_STRING, environmentId); + (Process doggyDogProcess, StringBuilder stdoutBuilder) = DoggyDogTestFramework.Act.StartDoggyDog(process.Id, typeof(DoggyDogTestsBase).Assembly.Location, FAKE_CONNECTION_STRING, environmentId); await doggyDogProcess.WaitForExitAsync(TestContext.Current.CancellationToken); string stdout = stdoutBuilder.ToString(); @@ -97,11 +96,11 @@ public async Task DoggyDog_Should_Do_Nothing_When_Process_Crashes_With_No_Regist { var environmentId = Guid.NewGuid(); - SqliteInfrastructure registry = CurrentEnvironment.GetInfrastructure(); + SqliteInfrastructure registry = Environment.GetInfrastructure(); Process process = DoggyDogTestFramework.Arrange.StartFakeProcess(environmentId, exitCode: 1, timeToExit: FAKE_PROCESS_WAIT_TIME); - (Process doggyDogProcess, StringBuilder stdoutBuilder) = DoggyDogTestFramework.Act.StartDoggyDog(process.Id, typeof(DoggyDogTests).Assembly.Location, registry.GetDatabaseConnectionString(), environmentId); + (Process doggyDogProcess, StringBuilder stdoutBuilder) = DoggyDogTestFramework.Act.StartDoggyDog(process.Id, typeof(DoggyDogTestsBase).Assembly.Location, registry.GetDatabaseConnectionString(), environmentId); await doggyDogProcess.WaitForExitAsync(TestContext.Current.CancellationToken); @@ -117,13 +116,13 @@ public async Task DoggyDog_Should_Do_Nothing_When_Process_Crashes_With_No_Regist public async Task DoggyDog_Should_Skip_Infrastructure_Without_Cleaner_Attribute_When_Process_Crashes() { var environmentId = Guid.NewGuid(); - SqliteInfrastructure registry = CurrentEnvironment.GetInfrastructure(); + SqliteInfrastructure registry = Environment.GetInfrastructure(); Process? process = DoggyDogTestFramework.Arrange.StartFakeProcess(environmentId, exitCode: 1, timeToExit: FAKE_PROCESS_WAIT_TIME); InfrastuctureRegistryEntry fakeEntry = await DoggyDogTestFramework.Arrange.CreateInfrastructureInRegistry(registry, process, typeof(DoggyDogTestFramework.Arrange.FakeInfrastructureWithoutCleanerAttribute), environmentId); - (Process doggyDogProcess, StringBuilder stdoutBuilder) = DoggyDogTestFramework.Act.StartDoggyDog(process.Id, typeof(DoggyDogTests).Assembly.Location, registry.GetDatabaseConnectionString(), environmentId); + (Process doggyDogProcess, StringBuilder stdoutBuilder) = DoggyDogTestFramework.Act.StartDoggyDog(process.Id, typeof(DoggyDogTestsBase).Assembly.Location, registry.GetDatabaseConnectionString(), environmentId); await doggyDogProcess.WaitForExitAsync(TestContext.Current.CancellationToken); @@ -140,14 +139,14 @@ public async Task DoggyDog_Should_Skip_Infrastructure_Without_Cleaner_Attribute_ public async Task DoggyDog_Should_Cleanup_Multiple_Orphan_Infrastructures_When_Process_Crashes() { var environmentId = Guid.NewGuid(); - SqliteInfrastructure registry = CurrentEnvironment.GetInfrastructure(); + SqliteInfrastructure registry = Environment.GetInfrastructure(); Process fakeProcess = DoggyDogTestFramework.Arrange.StartFakeProcess(environmentId, exitCode: 1, timeToExit: FAKE_PROCESS_WAIT_TIME); InfrastuctureRegistryEntry fakeEntry1 = await DoggyDogTestFramework.Arrange.CreateInfrastructureInRegistry(registry, fakeProcess, typeof(DoggyDogTestFramework.Arrange.FakeInfrastructureWithCleaner), environmentId); InfrastuctureRegistryEntry fakeEntry2 = await DoggyDogTestFramework.Arrange.CreateInfrastructureInRegistry(registry, fakeProcess, typeof(DoggyDogTestFramework.Arrange.FakeInfrastructure2WithCleaner), environmentId); - (Process doggyDogProcess, StringBuilder stdoutBuilder) = DoggyDogTestFramework.Act.StartDoggyDog(fakeProcess.Id, typeof(DoggyDogTests).Assembly.Location, registry.GetDatabaseConnectionString(), environmentId); + (Process doggyDogProcess, StringBuilder stdoutBuilder) = DoggyDogTestFramework.Act.StartDoggyDog(fakeProcess.Id, typeof(DoggyDogTestsBase).Assembly.Location, registry.GetDatabaseConnectionString(), environmentId); await doggyDogProcess.WaitForExitAsync(TestContext.Current.CancellationToken); string stdout = stdoutBuilder.ToString(); @@ -164,10 +163,10 @@ public async Task DoggyDog_Should_Cleanup_Multiple_Orphan_Infrastructures_When_P public async Task DoggyDog_Should_Display_InfrastructureLifecycleEvents() { var environmentId = Guid.NewGuid(); - SqliteInfrastructure registry = CurrentEnvironment.GetInfrastructure(); + SqliteInfrastructure registry = Environment.GetInfrastructure(); Process fakeProcess = DoggyDogTestFramework.Arrange.StartFakeProcess(environmentId, timeToExit: 999); - (Process doggyDogProcess, StringBuilder stdoutBuilder) = DoggyDogTestFramework.Act.StartDoggyDog(fakeProcess.Id, typeof(DoggyDogTests).Assembly.Location, registry.GetDatabaseConnectionString(), environmentId); + (Process doggyDogProcess, StringBuilder stdoutBuilder) = DoggyDogTestFramework.Act.StartDoggyDog(fakeProcess.Id, typeof(DoggyDogTestsBase).Assembly.Location, registry.GetDatabaseConnectionString(), environmentId); await Task.Delay(1000, TestContext.Current.CancellationToken); InfrastuctureRegistryEntry fakeEntry1 = await DoggyDogTestFramework.Arrange.CreateInfrastructureInRegistry(registry, fakeProcess, typeof(DoggyDogTestFramework.Arrange.FakeInfrastructureWithCleaner), environmentId); diff --git a/NotoriousTest.IntegrationTests/Infrastructure/InfrastructureLifecycleTests.cs b/NotoriousTest.IntegrationTests/Infrastructure/InfrastructureLifecycleTestsBase.cs similarity index 96% rename from NotoriousTest.IntegrationTests/Infrastructure/InfrastructureLifecycleTests.cs rename to NotoriousTest.IntegrationTests/Infrastructure/InfrastructureLifecycleTestsBase.cs index 9c78423..32bcc3e 100644 --- a/NotoriousTest.IntegrationTests/Infrastructure/InfrastructureLifecycleTests.cs +++ b/NotoriousTest.IntegrationTests/Infrastructure/InfrastructureLifecycleTestsBase.cs @@ -8,7 +8,7 @@ namespace NotoriousTest.IntegrationTests.Infrastructure; -public class InfrastructureLifecycleTests(NotoriousTestEnvironment environment) +public class InfrastructureLifecycleTestsBase(XUnitFixture environment) : IntegrationTest(environment) { [Fact] diff --git a/NotoriousTest.IntegrationTests/Infrastructures/Postgre/PostgreInfrastructureEnvironment.cs b/NotoriousTest.IntegrationTests/Infrastructures/Postgre/PostgreInfrastructureEnvironment.cs index 9ce7303..9e28c8a 100644 --- a/NotoriousTest.IntegrationTests/Infrastructures/Postgre/PostgreInfrastructureEnvironment.cs +++ b/NotoriousTest.IntegrationTests/Infrastructures/Postgre/PostgreInfrastructureEnvironment.cs @@ -4,16 +4,18 @@ using NotoriousTest.TestContainers; using System.Reflection; - +using NotoriousTest.Core.Environments; +using NotoriousTest.Core.Runtime; +using NotoriousTest.Core.Watchdog; using Testcontainers.PostgreSql; using Xunit.Sdk; namespace NotoriousTest.IntegrationTests.Postgre { - public class PostgreInfrastructureEnvironment : XUnit.Environment + public class PostgreInfrastructureEnvironment : EnvironmentBase { - public PostgreInfrastructureEnvironment(IMessageSink sink) : base(sink) + public PostgreInfrastructureEnvironment(EnvironmentSettings settings, IWatchDog watchDog, IRegistry registry, IRuntime runtime, ITestLogger logger, IServiceProvider serviceProvider) : base(settings, watchDog, registry, runtime, logger, serviceProvider) { } diff --git a/NotoriousTest.IntegrationTests/Infrastructures/Postgre/PostgreInfrastructureTests.cs b/NotoriousTest.IntegrationTests/Infrastructures/Postgre/PostgreInfrastructureTestsBase.cs similarity index 93% rename from NotoriousTest.IntegrationTests/Infrastructures/Postgre/PostgreInfrastructureTests.cs rename to NotoriousTest.IntegrationTests/Infrastructures/Postgre/PostgreInfrastructureTestsBase.cs index 45e13d5..e758973 100644 --- a/NotoriousTest.IntegrationTests/Infrastructures/Postgre/PostgreInfrastructureTests.cs +++ b/NotoriousTest.IntegrationTests/Infrastructures/Postgre/PostgreInfrastructureTestsBase.cs @@ -11,11 +11,10 @@ using NotoriousTest.XUnit; namespace NotoriousTest.IntegrationTests.Postgre { - - public class PostgreInfrastructureTests : IntegrationTest + public class PostgreInfrastructureTestsBase : IntegrationTest { private ITestSettingsProvider _testSettingsProvider = A.Fake(); - public PostgreInfrastructureTests(PostgreInfrastructureEnvironment environment) : base(environment) + public PostgreInfrastructureTestsBase(XUnitFixture environment) : base(environment) { string serverConnectionString = CurrentEnvironment.GetInfrastructure().OutputConfiguration[0].Value; A.CallTo(() => _testSettingsProvider.Get(nameof(PostgreInfrastructure))).Returns(new DatabaseSettings { ConnectionString = serverConnectionString + ";Pooling=false" }); diff --git a/NotoriousTest.IntegrationTests/Infrastructures/SqlServer/SqlServerInfrastructureEnvironment.cs b/NotoriousTest.IntegrationTests/Infrastructures/SqlServer/SqlServerInfrastructureEnvironment.cs index 67e1bd1..fcfba32 100644 --- a/NotoriousTest.IntegrationTests/Infrastructures/SqlServer/SqlServerInfrastructureEnvironment.cs +++ b/NotoriousTest.IntegrationTests/Infrastructures/SqlServer/SqlServerInfrastructureEnvironment.cs @@ -4,16 +4,16 @@ using NotoriousTest.TestContainers; using System.Reflection; - +using NotoriousTest.Core.Environments; +using NotoriousTest.Core.Runtime; +using NotoriousTest.Core.Watchdog; using Testcontainers.MsSql; -using Xunit.Sdk; - namespace NotoriousTest.IntegrationTests.Environment { - public class SqlServerInfrastructureEnvironment : XUnit.Environment + public class SqlServerInfrastructureEnvironment : EnvironmentBase { - public SqlServerInfrastructureEnvironment(IMessageSink sink) : base(sink) + public SqlServerInfrastructureEnvironment(EnvironmentSettings settings, IWatchDog watchDog, IRegistry registry, IRuntime runtime, ITestLogger logger, IServiceProvider serviceProvider) : base(settings, watchDog, registry, runtime, logger, serviceProvider) { } diff --git a/NotoriousTest.IntegrationTests/Infrastructures/SqlServer/SqlServerInfrastructureTests.cs b/NotoriousTest.IntegrationTests/Infrastructures/SqlServer/SqlServerInfrastructureTestsBase.cs similarity index 93% rename from NotoriousTest.IntegrationTests/Infrastructures/SqlServer/SqlServerInfrastructureTests.cs rename to NotoriousTest.IntegrationTests/Infrastructures/SqlServer/SqlServerInfrastructureTestsBase.cs index f1e264d..1ca4193 100644 --- a/NotoriousTest.IntegrationTests/Infrastructures/SqlServer/SqlServerInfrastructureTests.cs +++ b/NotoriousTest.IntegrationTests/Infrastructures/SqlServer/SqlServerInfrastructureTestsBase.cs @@ -12,10 +12,10 @@ namespace NotoriousTest.IntegrationTests.SqlServer { - public class SqlServerInfrastructureTests : IntegrationTest + public class SqlServerInfrastructureTestsBase : IntegrationTest { private ITestSettingsProvider _testSettingsProvider = A.Fake(); - public SqlServerInfrastructureTests(SqlServerInfrastructureEnvironment environment) : base(environment) + public SqlServerInfrastructureTestsBase(XUnitFixture environment) : base(environment) { string serverConnectionString = CurrentEnvironment.GetInfrastructure().OutputConfiguration[0].Value; A.CallTo(() => _testSettingsProvider.Get(nameof(SqlServerInfrastructure))).Returns(new DatabaseSettings { ConnectionString = serverConnectionString + ";Pooling=false" }); diff --git a/NotoriousTest.IntegrationTests/SystemUnderTest/NotoriousTestEnvironment.cs b/NotoriousTest.IntegrationTests/SystemUnderTest/NotoriousTestEnvironment.cs index d995b00..a8dc9e8 100644 --- a/NotoriousTest.IntegrationTests/SystemUnderTest/NotoriousTestEnvironment.cs +++ b/NotoriousTest.IntegrationTests/SystemUnderTest/NotoriousTestEnvironment.cs @@ -1,11 +1,20 @@ using System.Reflection; +using NotoriousTest.Core.Environments; +using NotoriousTest.Core.Logger; +using NotoriousTest.Core.Registry; +using NotoriousTest.Core.Runtime; +using NotoriousTest.Core.Watchdog; using NotoriousTest.IntegrationTests.Infrastructure; using Xunit.Sdk; namespace NotoriousTest.IntegrationTests.SystemUnderTest; -public class NotoriousTestEnvironment(IMessageSink sink) : XUnit.Environment(sink) +public class NotoriousTestEnvironment : EnvironmentBase { + public NotoriousTestEnvironment(EnvironmentSettings settings, IWatchDog watchDog, IRegistry registry, IRuntime runtime, ITestLogger logger, IServiceProvider serviceProvider) : base(settings, watchDog, registry, runtime, logger, serviceProvider) + { + } + public override Assembly CurrentAssembly => Assembly.GetExecutingAssembly(); public override Task ConfigureEnvironment() => Task.FromResult(AddInfrastructure()); diff --git a/NotoriousTest.MSTest/DI/MSTestDependencyInjectionConfigurator.cs b/NotoriousTest.MSTest/DI/MSTestDependencyInjectionConfigurator.cs new file mode 100644 index 0000000..d0c2194 --- /dev/null +++ b/NotoriousTest.MSTest/DI/MSTestDependencyInjectionConfigurator.cs @@ -0,0 +1,17 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NotoriousTest.Core.DI; +using NotoriousTest.Core.Logger; +using NotoriousTest.MSTest.Logger; + +namespace NotoriousTest.MSTest.DI; + +public class MSTestDependencyInjectionConfigurator : IDependencyInjectionConfigurator +{ + internal static TestContext TestContext { get; set; } + + public IServiceCollection ConfigureServices(IServiceCollection services) => + services + .AddSingleton(TestContext) + .AddSingleton(); +} diff --git a/NotoriousTest.MSTest/Environment.cs b/NotoriousTest.MSTest/Environment.cs deleted file mode 100644 index 272aabe..0000000 --- a/NotoriousTest.MSTest/Environment.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -using NotoriousTest.Core.Logger; -using NotoriousTest.Environments; -using NotoriousTest.MSTest.Logger; - -using System.Threading.Tasks; - -namespace NotoriousTest.MSTest -{ - public abstract class Environment : EnvironmentBase - { - private readonly TestContext _testContext; - - protected Environment(TestContext testContext) - { - _testContext = testContext; - } - - protected override void ConfigureInfrastructureServices(IServiceCollection collection) - { - base.ConfigureInfrastructureServices(collection); - - collection - .AddSingleton(_testContext) - .AddSingleton(); - } - - public async Task InitializeAsync() - { - await Initialize(); - } - - public async Task DestroyAsync() - { - await Destroy(); - } - } -} diff --git a/NotoriousTest.MSTest/IntegrationTest.cs b/NotoriousTest.MSTest/IntegrationTest.cs deleted file mode 100644 index cd78c09..0000000 --- a/NotoriousTest.MSTest/IntegrationTest.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace NotoriousTest.MSTest -{ - [TestClass] - public abstract class IntegrationTest where T : Environment - { - private static T? _environment; - - protected T CurrentEnvironment => _environment!; - - [ClassInitialize(InheritanceBehavior.BeforeEachDerivedClass)] - public static async Task ClassInitializeAsync(TestContext testContext) - { - _environment = (T)System.Activator.CreateInstance(typeof(T), testContext)!; - await _environment.InitializeAsync(); - } - - [ClassCleanup(InheritanceBehavior.BeforeEachDerivedClass)] - public static async Task ClassCleanupAsync() - { - if (_environment != null) - { - await _environment.DestroyAsync(); - _environment = null; - } - } - - [TestCleanup] - public async Task TestCleanupAsync() - { - await CurrentEnvironment.Reset(); - } - } -} diff --git a/NotoriousTest.MSTest/IntegrationTestBase.cs b/NotoriousTest.MSTest/IntegrationTestBase.cs new file mode 100644 index 0000000..b02af77 --- /dev/null +++ b/NotoriousTest.MSTest/IntegrationTestBase.cs @@ -0,0 +1,41 @@ +using System.Reflection; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NotoriousTest.Core; +using NotoriousTest.Core.DI; +using NotoriousTest.Core.Environments; +using NotoriousTest.MSTest.DI; + +namespace NotoriousTest.MSTest +{ + [InjectionConfigurator(typeof(MSTestDependencyInjectionConfigurator))] + [TestClass] + public abstract class IntegrationTestBase : NotoriousTest.IntegrationTestBase where T : EnvironmentBase + { + public static Fixture _fixture; + public IntegrationTestBase() + { + Fixture = _fixture; + } + + [ClassInitialize(InheritanceBehavior.BeforeEachDerivedClass)] + public static async Task ClassInitializeAsync(TestContext testContext) + { + MSTestDependencyInjectionConfigurator.TestContext = testContext; + Type? type = GetCurrentTestClass(testContext); + _fixture = new Fixture(type); + await _fixture.Environment.Initialize(); + } + + + [ClassCleanup(InheritanceBehavior.BeforeEachDerivedClass)] + public static async Task ClassCleanupAsync() => await _fixture.Environment.Destroy(); + + [TestCleanup] + public Task TestCleanupAsync() => Environment.Reset(); + + private static Type? GetCurrentTestClass(TestContext testContext) => + AppDomain.CurrentDomain + .GetAssemblies() + .Select(x => x.GetType(testContext.FullyQualifiedTestClassName)).FirstOrDefault(t => t != null); + } +} diff --git a/NotoriousTest.MSTest/Logger/TestLogger.cs b/NotoriousTest.MSTest/Logger/MSTestTestLogger.cs similarity index 55% rename from NotoriousTest.MSTest/Logger/TestLogger.cs rename to NotoriousTest.MSTest/Logger/MSTestTestLogger.cs index e61c1b2..1eb585e 100644 --- a/NotoriousTest.MSTest/Logger/TestLogger.cs +++ b/NotoriousTest.MSTest/Logger/MSTestTestLogger.cs @@ -5,20 +5,19 @@ namespace NotoriousTest.MSTest.Logger { - public class TestLogger : ITestLogger + public class MSTestTestLogger : ITestLogger { private readonly TestContext _testContext; private readonly EnvironmentId _contextId; - public TestLogger(TestContext testContext, EnvironmentId contextId) + public MSTestTestLogger(TestContext testContext) { _testContext = testContext; - _contextId = contextId; } - public void Log(string message) + public void Log(string message, EnvironmentId environmentId) { - _testContext.WriteLine($"[NotoriousTest][{_contextId.Value}]{message}"); + _testContext.WriteLine($"[NotoriousTest][{environmentId.Value}]{message}"); } } } diff --git a/NotoriousTest.NUnit/DI/NUnitDependencyInjectionConfigurator.cs b/NotoriousTest.NUnit/DI/NUnitDependencyInjectionConfigurator.cs new file mode 100644 index 0000000..66d4ac5 --- /dev/null +++ b/NotoriousTest.NUnit/DI/NUnitDependencyInjectionConfigurator.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.DependencyInjection; +using NotoriousTest.Core; +using NotoriousTest.Core.Logger; +using NotoriousTest.Core.DI; +using NotoriousTest.NUnit.Logger; + +namespace NotoriousTest.XUnit.DI; + +public class NUnitDependencyInjectionConfigurator : IDependencyInjectionConfigurator +{ + public IServiceCollection ConfigureServices(IServiceCollection services) => + services + .AddSingleton(); +} diff --git a/NotoriousTest.NUnit/Environment.cs b/NotoriousTest.NUnit/Environment.cs deleted file mode 100644 index 435cd25..0000000 --- a/NotoriousTest.NUnit/Environment.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; - -using NotoriousTest.Core.Logger; -using NotoriousTest.Environments; -using NotoriousTest.NUnit.Logger; - -using System.Threading.Tasks; - -namespace NotoriousTest.NUnit -{ - public abstract class Environment : EnvironmentBase - { - protected override void ConfigureInfrastructureServices(IServiceCollection collection) - { - base.ConfigureInfrastructureServices(collection); - - collection - .AddSingleton(); - } - - public async Task InitializeAsync() - { - await Initialize(); - } - - public async Task DestroyAsync() - { - await Destroy(); - } - } -} diff --git a/NotoriousTest.NUnit/IntegrationTest.cs b/NotoriousTest.NUnit/IntegrationTest.cs deleted file mode 100644 index 002ed35..0000000 --- a/NotoriousTest.NUnit/IntegrationTest.cs +++ /dev/null @@ -1,35 +0,0 @@ -using NUnit.Framework; - -namespace NotoriousTest.NUnit -{ - [TestFixture] - public abstract class IntegrationTest where T : Environment - { - private static T? _environment; - - protected T CurrentEnvironment => _environment!; - - [OneTimeSetUp] - public async Task OneTimeSetUpAsync() - { - _environment = (T)System.Activator.CreateInstance(typeof(T))!; - await _environment.InitializeAsync(); - } - - [OneTimeTearDown] - public async Task OneTimeTearDownAsync() - { - if (_environment != null) - { - await _environment.DestroyAsync(); - _environment = null; - } - } - - [TearDown] - public async Task TearDownAsync() - { - await CurrentEnvironment.Reset(); - } - } -} diff --git a/NotoriousTest.NUnit/IntegrationTestBase.cs b/NotoriousTest.NUnit/IntegrationTestBase.cs new file mode 100644 index 0000000..d66f73e --- /dev/null +++ b/NotoriousTest.NUnit/IntegrationTestBase.cs @@ -0,0 +1,27 @@ +using NotoriousTest.Core; +using NotoriousTest.Core.Environments; +using NUnit.Framework; +using NotoriousTest.Core.DI; +using NotoriousTest.XUnit.DI; + +namespace NotoriousTest.NUnit +{ + [InjectionConfigurator(typeof(NUnitDependencyInjectionConfigurator))] + [TestFixture] + public abstract class IntegrationTestBase : NotoriousTest.IntegrationTestBase where T : EnvironmentBase + { + public IntegrationTestBase() + { + Fixture = new Fixture(GetType()); + } + + [OneTimeSetUp] + public Task OneTimeSetUpAsync() => Environment.Initialize(); + + [OneTimeTearDown] + public Task OneTimeTearDownAsync() => Environment.Destroy(); + + [TearDown] + public Task TearDownAsync() => Environment.Reset(); + } +} diff --git a/NotoriousTest.NUnit/Logger/NUnitTestLogger.cs b/NotoriousTest.NUnit/Logger/NUnitTestLogger.cs new file mode 100644 index 0000000..9ec929b --- /dev/null +++ b/NotoriousTest.NUnit/Logger/NUnitTestLogger.cs @@ -0,0 +1,15 @@ +using NUnit.Framework; + +using NotoriousTest.Core; +using NotoriousTest.Core.Logger; + +namespace NotoriousTest.NUnit.Logger +{ + public class NUnitTestLogger : ITestLogger + { + public void Log(string message, EnvironmentId environmentId) + { + TestContext.Progress.WriteLine($"[NotoriousTest][{environmentId.Value}]{message}"); + } + } +} diff --git a/NotoriousTest.NUnit/Logger/TestLogger.cs b/NotoriousTest.NUnit/Logger/TestLogger.cs deleted file mode 100644 index 95723a7..0000000 --- a/NotoriousTest.NUnit/Logger/TestLogger.cs +++ /dev/null @@ -1,22 +0,0 @@ -using NUnit.Framework; - -using NotoriousTest.Core; -using NotoriousTest.Core.Logger; - -namespace NotoriousTest.NUnit.Logger -{ - public class TestLogger : ITestLogger - { - private readonly EnvironmentId _contextId; - - public TestLogger(EnvironmentId contextId) - { - _contextId = contextId; - } - - public void Log(string message) - { - TestContext.Progress.WriteLine($"[NotoriousTest][{_contextId.Value}]{message}"); - } - } -} diff --git a/NotoriousTest.Runtime/RuntimeConfigurationProvider.cs b/NotoriousTest.Runtime/RuntimeConfigurationProvider.cs index 7c586d4..1db7dfb 100644 --- a/NotoriousTest.Runtime/RuntimeConfigurationProvider.cs +++ b/NotoriousTest.Runtime/RuntimeConfigurationProvider.cs @@ -30,7 +30,7 @@ public RuntimeConfigurationProvider(ITestLogger logger) return null; - var json = File.ReadAllText(runtimePath); + string json = File.ReadAllText(runtimePath); RuntimeConfigurationEntity? entity = JsonSerializer.Deserialize(json, JSON_OPTIONS); @@ -38,26 +38,24 @@ public RuntimeConfigurationProvider(ITestLogger logger) return null; FrameworkEntry[]? frameworkEntries = entity.RuntimeOptions.Frameworks ?? [entity.RuntimeOptions.Framework!]; - SupportedFramework[]? frameworks = frameworkEntries.Select(ToDomain).ToArray(); + var result = new RuntimeConfiguration(entity.RuntimeOptions.Tfm, frameworks); _cache = result; return result; } - private SupportedFramework ToDomain(FrameworkEntry entry) - { - return new SupportedFramework(entry.Name, entry.Version, GetNearestVersionDirectory(entry)); - } - private string GetNearestVersionDirectory(FrameworkEntry framework) + private SupportedFramework ToDomain(FrameworkEntry entry) => new(entry.Name, entry.Version, GetNearestVersionDirectory(entry)); + + private string? GetNearestVersionDirectory(FrameworkEntry framework) { - var dotnetRoot = GetDotnetRoot(); + string dotnetRoot = GetDotnetRoot(); - var frameworkPath = $"{dotnetRoot}/shared/{framework.Name}"; + string frameworkPath = $"{dotnetRoot}/shared/{framework.Name}"; - var prefix = $"{new Version(framework.Version).Major}.{new Version(framework.Version).Minor}."; - // Find the nearest version - var best = Directory.GetDirectories(frameworkPath) + string prefix = $"{new Version(framework.Version).Major}.{new Version(framework.Version).Minor}."; + // Find the nearest version + string? best = Directory.GetDirectories(frameworkPath) .Where(d => Path.GetFileName(d).StartsWith(prefix)) .OrderByDescending(d => new Version(Path.GetFileName(d))) .FirstOrDefault(); @@ -67,17 +65,19 @@ private string GetNearestVersionDirectory(FrameworkEntry framework) private string GetDotnetRoot() { - string dotnetRoot = Environment.GetEnvironmentVariable("DOTNET_ROOT"); + string? dotnetRoot = Environment.GetEnvironmentVariable("DOTNET_ROOT"); if (!string.IsNullOrWhiteSpace(dotnetRoot)) return dotnetRoot; - var mainModule = Process.GetCurrentProcess().MainModule!.FileName; - var isNotSelfContained = Path.GetFileNameWithoutExtension(mainModule) + string mainModule = Process.GetCurrentProcess().MainModule!.FileName; + + // If the test project is self-contained (wich is rare), the main module will be the test executable itself. + bool isNotSelfContained = Path.GetFileNameWithoutExtension(mainModule) .Equals("dotnet", StringComparison.OrdinalIgnoreCase); if (isNotSelfContained) - return Path.GetDirectoryName(mainModule); + return Path.GetDirectoryName(mainModule)!; return Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), diff --git a/NotoriousTest.TUnit/DI/TUnitDependencyInjectionConfigurator.cs b/NotoriousTest.TUnit/DI/TUnitDependencyInjectionConfigurator.cs new file mode 100644 index 0000000..4188aa7 --- /dev/null +++ b/NotoriousTest.TUnit/DI/TUnitDependencyInjectionConfigurator.cs @@ -0,0 +1,13 @@ +using Microsoft.Extensions.DependencyInjection; +using NotoriousTest.Core.DI; +using NotoriousTest.Core.Logger; +using NotoriousTest.TUnit.Logger; + +namespace NotoriousTest.TUnit.DI; + +public class TUnitDependencyInjectionConfigurator : IDependencyInjectionConfigurator +{ + public IServiceCollection ConfigureServices(IServiceCollection services) => + services + .AddSingleton(); +} diff --git a/NotoriousTest.TUnit/Environment.cs b/NotoriousTest.TUnit/Environment.cs deleted file mode 100644 index 9ccd56d..0000000 --- a/NotoriousTest.TUnit/Environment.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; - -using NotoriousTest.Core.Logger; -using NotoriousTest.Environments; -using NotoriousTest.TUnit.Logger; - -using TUnit.Core.Interfaces; - -namespace NotoriousTest.TUnit -{ - public abstract class Environment : EnvironmentBase, IAsyncInitializer, IAsyncDisposable - { - protected override void ConfigureInfrastructureServices(IServiceCollection collection) - { - base.ConfigureInfrastructureServices(collection); - - collection - .AddSingleton(); - } - - public async ValueTask DisposeAsync() - { - await Destroy(); - } - - - async Task IAsyncInitializer.InitializeAsync() - { - await Initialize(); - } - } -} diff --git a/NotoriousTest.TUnit/IntegrationTest.cs b/NotoriousTest.TUnit/IntegrationTest.cs deleted file mode 100644 index 3f41e2d..0000000 --- a/NotoriousTest.TUnit/IntegrationTest.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace NotoriousTest.TUnit -{ - [ClassDataSource(Shared = [SharedType.PerClass])] - [NotInParallel] - public abstract class IntegrationTest where T : Environment - { - protected readonly T CurrentEnvironment; - - public IntegrationTest(T environment) - { - // Called before each tests - CurrentEnvironment = environment; - } - - [After(Test)] - public async ValueTask Reset() - { - await CurrentEnvironment.Reset(); - } - } -} diff --git a/NotoriousTest.TUnit/IntegrationTestBase.cs b/NotoriousTest.TUnit/IntegrationTestBase.cs new file mode 100644 index 0000000..a98346e --- /dev/null +++ b/NotoriousTest.TUnit/IntegrationTestBase.cs @@ -0,0 +1,23 @@ +using NotoriousTest.Core.DI; +using NotoriousTest.Core.Environments; +using NotoriousTest.TUnit.DI; + +namespace NotoriousTest.TUnit +{ + [InjectionConfigurator(typeof(TUnitDependencyInjectionConfigurator))] + [ClassDataSource(Shared = [SharedType.PerClass])] + [NotInParallel] + public abstract class IntegrationTestBase : NotoriousTest.IntegrationTestBase where T : EnvironmentBase + { + public IntegrationTestBase(TUnitFixture fixture) + { + Fixture = fixture; + } + + [After(Test)] + public async ValueTask Reset() + { + await Environment.Reset(); + } + } +} diff --git a/NotoriousTest.TUnit/Logger/TUnitTestLogger.cs b/NotoriousTest.TUnit/Logger/TUnitTestLogger.cs new file mode 100644 index 0000000..ba0bff9 --- /dev/null +++ b/NotoriousTest.TUnit/Logger/TUnitTestLogger.cs @@ -0,0 +1,13 @@ +using NotoriousTest.Core; +using NotoriousTest.Core.Logger; + +namespace NotoriousTest.TUnit.Logger +{ + public class TUnitTestLogger : ITestLogger + { + public void Log(string message, EnvironmentId environment) + { + TestContext.Current!.Output.WriteLine($"[NotoriousTest][{environment.Value}]{message}"); + } + } +} diff --git a/NotoriousTest.TUnit/Logger/TestLogger.cs b/NotoriousTest.TUnit/Logger/TestLogger.cs deleted file mode 100644 index cdad880..0000000 --- a/NotoriousTest.TUnit/Logger/TestLogger.cs +++ /dev/null @@ -1,20 +0,0 @@ -using NotoriousTest.Core; -using NotoriousTest.Core.Logger; - -namespace NotoriousTest.TUnit.Logger -{ - public class TestLogger : ITestLogger - { - private readonly EnvironmentId _contextId; - - public TestLogger(EnvironmentId contextId) - { - _contextId = contextId; - } - - public void Log(string message) - { - TestContext.Current!.Output.WriteLine($"[NotoriousTest][{_contextId.Value}]{message}"); - } - } -} diff --git a/NotoriousTest.TUnit/TUnitFixture.cs b/NotoriousTest.TUnit/TUnitFixture.cs new file mode 100644 index 0000000..eb38639 --- /dev/null +++ b/NotoriousTest.TUnit/TUnitFixture.cs @@ -0,0 +1,18 @@ +using NotoriousTest.Core; +using NotoriousTest.Core.Environments; + +using TUnit.Core.Interfaces; + +namespace NotoriousTest.TUnit; + +public class TUnitFixture : Fixture, IAsyncInitializer, IAsyncDisposable where TEnvironment : EnvironmentBase +{ + + public TUnitFixture(): base(TestBuilderContext.Current?.TestMetadata.Class.Type) + { + + } + + public async Task InitializeAsync() => await Environment.Initialize(); + public async ValueTask DisposeAsync() => await Environment.Destroy(); +} diff --git a/NotoriousTest.TestContainers/DockerInfrastructureCleaner.cs b/NotoriousTest.TestContainers/DockerInfrastructureCleaner.cs index 4a89e44..1abdad3 100644 --- a/NotoriousTest.TestContainers/DockerInfrastructureCleaner.cs +++ b/NotoriousTest.TestContainers/DockerInfrastructureCleaner.cs @@ -10,7 +10,7 @@ public class DockerInfrastructureCleaner : IInfrastructureCleaner(); _watchDog = A.Fake(); _runtime = A.Fake(); - _settings = A.Fake(); + _provider = A.Fake(); } [Fact] @@ -39,7 +41,7 @@ public async Task AggregateConfiguration_Should_MergeAllEntries_WhenMultipleProd infrastructure1.AddEntry("key", "value"); infrastructure2.AddEntry("key2", "value2"); - EnvironmentStub environment = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub environment = new(settings: new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); environment.OnConfigureEnvironment += () => { @@ -63,7 +65,7 @@ public async Task AggregateConfiguration_Should_ReturnEmptyList_WhenNoConfigurat var infrastructure1 = new InfrastructureStub(_testLogger, _registry); var infrastructure2 = new ConsumerInfrastructureStub(_testLogger, _registry); - EnvironmentStub environment = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub environment = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); environment.OnConfigureEnvironment += () => { @@ -82,7 +84,7 @@ public async Task ConfigurationConsumer_Should_ReceiveConfigurationBeforeItsOwnI var infrastructure1 = new InfrastructureStub(_testLogger, _registry); var infrastructure2 = new ConsumerInfrastructureStub(_testLogger, _registry); - EnvironmentStub environment = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub environment = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); infrastructure1.AddEntry("key", "value"); diff --git a/NotoriousTest.UnitTests/Environments/EnvironmentBaseTests.cs b/NotoriousTest.UnitTests/Environments/EnvironmentBaseTests.cs index 567dee9..1387e20 100644 --- a/NotoriousTest.UnitTests/Environments/EnvironmentBaseTests.cs +++ b/NotoriousTest.UnitTests/Environments/EnvironmentBaseTests.cs @@ -10,7 +10,6 @@ using NotoriousTest.Core.Logger; using NotoriousTest.Core.Registry; using NotoriousTest.Core.Runtime; -using NotoriousTest.Core.Settings; using NotoriousTest.Core.Watchdog; using NotoriousTest.UnitTests.Stubs; @@ -24,7 +23,8 @@ public class EnvironmentBaseTests private readonly IRegistry _registry; private readonly IWatchDog _watchDog; private readonly IRuntime _runtime; - private readonly ITestSettingsProvider _settings; + private readonly IServiceProvider _provider; + private readonly EnvironmentId _environmentId = EnvironmentId.Create(); public EnvironmentBaseTests() { @@ -32,25 +32,21 @@ public EnvironmentBaseTests() _registry = A.Fake(); _watchDog = A.Fake(); _runtime = A.Fake(); - _settings = A.Fake(); + _provider = new ServiceCollection() + .AddSingleton(_testLogger) + .AddSingleton(_registry) + .AddSingleton(_watchDog) + .AddSingleton(_runtime) + .AddSingleton(_environmentId) + .BuildServiceProvider(); } - [Fact] - public async Task Initialize_Should_BuildServiceProvider() - { - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, _settings); - await stub.Initialize(); - stub.PublicServiceProvider.Should().NotBeNull(); - stub.PublicServiceProvider!.GetService().Should().NotBeNull().And.Be(_testLogger); - stub.PublicServiceProvider!.GetService().Should().NotBeNull().And.Be(_registry); - stub.PublicServiceProvider!.GetService().Should().NotBeNull().And.Be(_watchDog); - } [Fact] public async Task Initialize_Should_CallConfigureEnvironment() { bool called = false; - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, _settings) + EnvironmentStub stub = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider) { OnConfigureEnvironment = () => { @@ -66,7 +62,7 @@ public async Task Initialize_Should_CallConfigureEnvironment() [Fact] public async Task Initialize_Should_CallSetupRegistry() { - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub stub = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); await stub.Initialize(); A.CallTo(() => _registry.Ensure()).MustHaveHappenedOnceExactly(); @@ -75,7 +71,7 @@ public async Task Initialize_Should_CallSetupRegistry() [Fact] public async Task Initialize_Should_StartWatchdog() { - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub stub = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); await stub.Initialize(); A.CallTo(() => _watchDog.Start(A._, A._, A._, A>._)).MustHaveHappenedOnceExactly(); } @@ -84,7 +80,7 @@ public async Task Initialize_Should_StartWatchdog() public async Task Initialize_Should_InitializeInfrastructuresInAscendingOrder() { List initializationOrder = new(); - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub stub = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); stub.OnConfigureEnvironment = async () => { stub.AddInfrastructure(new InfrastructureStub(_testLogger, _registry, order: 2) { OnInitialize = async () => initializationOrder.Add(2) }); @@ -98,7 +94,8 @@ public async Task Initialize_Should_InitializeInfrastructuresInAscendingOrder() [Fact] public async Task AddInfrastructure_Should_SetContextId_WhenGeneric() { - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, _settings); + + EnvironmentStub stub = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); stub.OnConfigureEnvironment = async () => { @@ -113,7 +110,7 @@ public async Task AddInfrastructure_Should_SetContextId_WhenGeneric() [Fact] public async Task AddInfrastructure_Should_SetContextId_WhenInstance() { - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub stub = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); InfrastructureStub infra = new(_testLogger, _registry); stub.OnConfigureEnvironment = async () => @@ -128,7 +125,7 @@ public async Task AddInfrastructure_Should_SetContextId_WhenInstance() [Fact] public async Task GetInfrastructure_Should_ReturnInstance_WhenTypeExists() { - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub stub = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); InfrastructureStub infra = new(_testLogger, _registry); stub.OnConfigureEnvironment = async () => { @@ -143,7 +140,7 @@ public async Task GetInfrastructure_Should_ReturnInstance_WhenTypeExists() [Fact] public void GetInfrastructure_Should_ThrowInfrastructureNotFoundException_WhenTypeIsMissing() { - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub stub = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); Action act = () => stub.GetInfrastructure(); act.Should().Throw(); } @@ -152,7 +149,7 @@ public void GetInfrastructure_Should_ThrowInfrastructureNotFoundException_WhenTy public async Task Reset_Should_OnlyResetInfrastructuresWithAutoResetEnabled() { List resetOrder = new(); - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub stub = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); stub.OnConfigureEnvironment = async () => { @@ -170,7 +167,7 @@ public async Task Reset_Should_OnlyResetInfrastructuresWithAutoResetEnabled() public async Task Reset_Should_ResetInfrastructuresInAscendingOrder() { List initializationOrder = new(); - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub stub = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); stub.OnConfigureEnvironment = async () => { @@ -187,7 +184,7 @@ public async Task Reset_Should_ResetInfrastructuresInAscendingOrder() public async Task Destroy_Should_DestroyAllInfrastructures() { List destroyOrder = new(); - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub stub = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); stub.OnConfigureEnvironment = async () => { stub.AddInfrastructure(new InfrastructureStub(_testLogger, _registry, order: 2) { OnDestroy = async () => destroyOrder.Add(2) }); @@ -202,8 +199,8 @@ public async Task Destroy_Should_DestroyAllInfrastructures() [Fact] public void EnvironmentId_Should_BeUniquePerInstance() { - EnvironmentStub stub1 = new(_testLogger, _watchDog, _registry, _runtime, _settings); - EnvironmentStub stub2 = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub stub1 = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); + EnvironmentStub stub2 = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); stub1.EnvironmentId.Should().NotBeNull(); stub1.EnvironmentId.Value.Should().NotBeEmpty(); stub2.EnvironmentId.Should().NotBeNull(); @@ -216,7 +213,7 @@ public void EnvironmentId_Should_BeUniquePerInstance() public async Task Initialize_Should_InitializeInfrastructuresInAddOrder_WhenOrderIsNull() { List initializationOrder = new(); - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub stub = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); stub.OnConfigureEnvironment = async () => { stub.AddInfrastructure(new InfrastructureStub(_testLogger, _registry, order: null) { OnInitialize = async () => initializationOrder.Add(1) }); @@ -231,7 +228,7 @@ public async Task Initialize_Should_InitializeInfrastructuresInAddOrder_WhenOrde public async Task Initialize_Should_InitializeInAscendingOrder_WhenOrdersAreMixed() { List initializationOrder = new(); - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub stub = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); stub.OnConfigureEnvironment = async () => { stub.AddInfrastructure(new InfrastructureStub(_testLogger, _registry, order: 2) { OnInitialize = async () => initializationOrder.Add(2) }); @@ -246,7 +243,7 @@ public async Task Initialize_Should_InitializeInAscendingOrder_WhenOrdersAreMixe public async Task Reset_Should_UseTheSameOrderingAsInitialize() { List order = new(); - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub stub = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); stub.OnConfigureEnvironment = async () => { stub.AddInfrastructure(new InfrastructureStub(_testLogger, _registry, order: 2) { OnInitialize = async () => order.Add(2), OnReset = async () => order.Add(2) }); @@ -263,7 +260,7 @@ public async Task Reset_Should_UseTheSameOrderingAsInitialize() public async Task Initialize_Should_OrderMultipleInfrastructures() { List order = new(); - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub stub = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); stub.OnConfigureEnvironment = async () => { stub.AddInfrastructure(new InfrastructureStub(_testLogger, _registry, order: 2) { OnInitialize = async () => order.Add(2), OnReset = async () => order.Add(2) }); @@ -281,7 +278,7 @@ public async Task Initialize_Should_OrderMultipleInfrastructures() public async Task Initialize_Should_ExecuteIConsumerLast_InEachGroup() { List order = new(); - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, _settings); + EnvironmentStub stub = new(new EnvironmentSettings(), _watchDog, _registry, _runtime, _testLogger, _provider); stub.OnConfigureEnvironment = async () => { stub.AddInfrastructure(new ConsumerInfrastructureStub(_testLogger, _registry, order: 2) { OnInitialize = async () => order.Add(22), OnReset = async () => order.Add(2) }); @@ -298,19 +295,12 @@ public async Task Initialize_Should_ExecuteIConsumerLast_InEachGroup() // --- Watchdog disabled --- - private ITestSettingsProvider BuildSettingsWithWatchdog(bool disabled) - { - var settings = A.Fake(); - A.CallTo(() => settings.Get(EnvironmentConfiguration.SECTION_NAME)) - .Returns(new EnvironmentConfiguration { DisableWatchdog = disabled }); - return settings; - } [Fact] public async Task Initialize_Should_NotSetupRegistry_WhenWatchdogIsDisabled() { - var settings = BuildSettingsWithWatchdog(disabled: true); - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, settings); + EnvironmentSettings settings = new() { DisableWatchdog = true }; + EnvironmentStub stub = new(settings, _watchDog, _registry, _runtime, _testLogger, _provider); await stub.Initialize(); @@ -320,8 +310,8 @@ public async Task Initialize_Should_NotSetupRegistry_WhenWatchdogIsDisabled() [Fact] public async Task Initialize_Should_NotStartWatchdog_WhenWatchdogIsDisabled() { - var settings = BuildSettingsWithWatchdog(disabled: true); - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, settings); + EnvironmentSettings settings = new() { DisableWatchdog = true }; + EnvironmentStub stub = new(settings, _watchDog, _registry, _runtime, _testLogger, _provider); await stub.Initialize(); @@ -331,8 +321,8 @@ public async Task Initialize_Should_NotStartWatchdog_WhenWatchdogIsDisabled() [Fact] public async Task Destroy_Should_NotSendSuccessSignal_WhenWatchdogIsDisabled() { - var settings = BuildSettingsWithWatchdog(disabled: true); - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, settings); + EnvironmentSettings settings = new() { DisableWatchdog = true }; + EnvironmentStub stub = new(settings, _watchDog, _registry, _runtime, _testLogger, _provider); await stub.Initialize(); await stub.Destroy(); @@ -343,8 +333,8 @@ public async Task Destroy_Should_NotSendSuccessSignal_WhenWatchdogIsDisabled() [Fact] public async Task Initialize_Should_NotRegisterInfrastructureInRegistry_WhenWatchdogIsDisabled() { - var settings = BuildSettingsWithWatchdog(disabled: true); - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, settings); + EnvironmentSettings settings = new() { DisableWatchdog = true }; + EnvironmentStub stub = new(settings, _watchDog, _registry, _runtime, _testLogger, _provider); stub.OnConfigureEnvironment = async () => { stub.AddInfrastructure(new InfrastructureStub(_testLogger, _registry)); @@ -358,8 +348,8 @@ public async Task Initialize_Should_NotRegisterInfrastructureInRegistry_WhenWatc [Fact] public async Task Reset_Should_NotNotifyResetInRegistry_WhenWatchdogIsDisabled() { - var settings = BuildSettingsWithWatchdog(disabled: true); - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, settings); + EnvironmentSettings settings = new() { DisableWatchdog = true }; + EnvironmentStub stub = new(settings, _watchDog, _registry, _runtime, _testLogger, _provider); stub.OnConfigureEnvironment = async () => { stub.AddInfrastructure(new InfrastructureStub(_testLogger, _registry)); @@ -374,8 +364,8 @@ public async Task Reset_Should_NotNotifyResetInRegistry_WhenWatchdogIsDisabled() [Fact] public async Task Destroy_Should_NotRemoveInfrastructureFromRegistry_WhenWatchdogIsDisabled() { - var settings = BuildSettingsWithWatchdog(disabled: true); - EnvironmentStub stub = new(_testLogger, _watchDog, _registry, _runtime, settings); + EnvironmentSettings settings = new() { DisableWatchdog = true }; + EnvironmentStub stub = new(settings, _watchDog, _registry, _runtime, _testLogger, _provider); stub.OnConfigureEnvironment = async () => { stub.AddInfrastructure(new InfrastructureStub(_testLogger, _registry)); diff --git a/NotoriousTest.UnitTests/FixtureTests.cs b/NotoriousTest.UnitTests/FixtureTests.cs new file mode 100644 index 0000000..213c93a --- /dev/null +++ b/NotoriousTest.UnitTests/FixtureTests.cs @@ -0,0 +1,30 @@ +using AwesomeAssertions; +using FakeItEasy; +using Microsoft.Extensions.DependencyInjection; +using NotoriousTest.Core; +using NotoriousTest.Core.DI; +using NotoriousTest.Core.Environments; +using NotoriousTest.Core.Logger; +using NotoriousTest.Core.Registry; +using NotoriousTest.Core.Runtime; +using NotoriousTest.Core.Watchdog; +using NotoriousTest.UnitTests.Stubs; + +namespace NotoriousTest.UnitTests; + + + +public class FixtureTests +{ + [Fact] + public Task Fixture_Should_ConfigureEnvironmentWithInjectionAttributes() + { + var fixture = new Fixture(typeof(IntegrationTestStub)); + fixture.Environment.PublicServiceProvider.GetService().Should().NotBeNull(); + fixture.Environment.PublicServiceProvider.GetService().Should().NotBeNull(); + fixture.Environment.PublicServiceProvider.GetService().Should().NotBeNull(); + fixture.Environment.PublicServiceProvider.GetService().Should().NotBeNull(); + fixture.Environment.PublicServiceProvider.GetService().Should().NotBeNull(); + return Task.CompletedTask; + } +} diff --git a/NotoriousTest.UnitTests/Infrastructure/InfrastructureLifecycleTests.cs b/NotoriousTest.UnitTests/Infrastructure/InfrastructureLifecycleTests.cs index 2f20257..e8cc713 100644 --- a/NotoriousTest.UnitTests/Infrastructure/InfrastructureLifecycleTests.cs +++ b/NotoriousTest.UnitTests/Infrastructure/InfrastructureLifecycleTests.cs @@ -10,20 +10,14 @@ namespace NotoriousTest.UnitTests.Infrastructure; public class InfrastructureLifecycleTests { - private readonly ITestLogger _testLogger; - private readonly IRegistry _registry; - - public InfrastructureLifecycleTests() - { - _testLogger = A.Fake(); - _registry = A.Fake(); - } + private readonly ITestLogger _testLogger = A.Fake(); + private readonly IRegistry _registry = A.Fake(); [Fact] public async Task InitializeAsync_Should_CallInitialize() { bool called = false; - InfrastructureStub infrastructure = new InfrastructureStub(_testLogger, _registry) + var infrastructure = new InfrastructureStub(_testLogger, _registry) { OnInitialize = async () => called = true }; @@ -36,7 +30,7 @@ public async Task InitializeAsync_Should_CallInitialize() [Fact] public async Task InitializeAsync_Should_RegisterInRegistry() { - InfrastructureStub infrastructure = new InfrastructureStub(_testLogger, _registry); + var infrastructure = new InfrastructureStub(_testLogger, _registry); await infrastructure.InitializeAsync(); A.CallTo(() => _registry.Register(A._)).MustHaveHappenedOnceExactly(); } @@ -44,7 +38,7 @@ public async Task InitializeAsync_Should_RegisterInRegistry() [Fact] public async Task InitializeAsync_Should_SkipRegistration_WhenRegistryDisabled() { - InfrastructureStub infrastructure = new InfrastructureStub(_testLogger, _registry, disableRegistry: true); + var infrastructure = new InfrastructureStub(_testLogger, _registry, disableRegistry: true); await infrastructure.InitializeAsync(); A.CallTo(() => _registry.Register(A._)).MustNotHaveHappened(); } @@ -52,7 +46,7 @@ public async Task InitializeAsync_Should_SkipRegistration_WhenRegistryDisabled() [Fact] public async Task InitializeAsync_Should_SkipRegistration_WhenAlreadyRegistered() { - RegisteredInfrastructureStub infrastructure = new RegisteredInfrastructureStub(_testLogger, _registry); + var infrastructure = new RegisteredInfrastructureStub(_testLogger, _registry); await infrastructure.InitializeAsync(); A.CallTo(() => _registry.Register(A._)).MustHaveHappenedOnceExactly(); } @@ -60,17 +54,18 @@ public async Task InitializeAsync_Should_SkipRegistration_WhenAlreadyRegistered( [Fact] public async Task InitializeAsync_Should_LogStartAndCompletionTimes() { - InfrastructureStub infrastructure = new InfrastructureStub(_testLogger, _registry); + var infrastructure = new InfrastructureStub(_testLogger, _registry); await infrastructure.InitializeAsync(); - A.CallTo(() => _testLogger.Log(A.That.Matches(s => s.Contains($"[{infrastructure.GetType().Name}] Initialization ...")))).MustHaveHappenedOnceExactly(); - A.CallTo(() => _testLogger.Log(A.That.Matches(s => s.Contains($"[{infrastructure.GetType().Name}] Initialization completed in")))).MustHaveHappenedOnceExactly(); + + A.CallTo(() => _testLogger.Log(A.That.Matches(s => s.Contains($"[{infrastructure.GetType().Name}] Initialization ...")), infrastructure.EnvironmentId)).MustHaveHappenedOnceExactly(); + A.CallTo(() => _testLogger.Log(A.That.Matches(s => s.Contains($"[{infrastructure.GetType().Name}] Initialization completed in")), infrastructure.EnvironmentId)).MustHaveHappenedOnceExactly(); } [Fact] public async Task ResetAsync_Should_CallReset() { bool called = false; - InfrastructureStub infrastructure = new InfrastructureStub(_testLogger, _registry) + var infrastructure = new InfrastructureStub(_testLogger, _registry) { OnReset = async () => called = true }; @@ -82,7 +77,7 @@ public async Task ResetAsync_Should_CallReset() public async Task DestroyAsync_Should_CallDestroy() { bool called = false; - InfrastructureStub infrastructure = new InfrastructureStub(_testLogger, _registry) + var infrastructure = new InfrastructureStub(_testLogger, _registry) { OnDestroy = async () => called = true }; @@ -93,7 +88,7 @@ public async Task DestroyAsync_Should_CallDestroy() [Fact] public async Task DestroyAsync_Should_RemoveFromRegistry() { - InfrastructureStub infrastructure = new InfrastructureStub(_testLogger, _registry); + var infrastructure = new InfrastructureStub(_testLogger, _registry); await infrastructure.DestroyAsync(); A.CallTo(() => _registry.Remove(infrastructure.Id)).MustHaveHappenedOnceExactly(); @@ -102,7 +97,7 @@ public async Task DestroyAsync_Should_RemoveFromRegistry() [Fact] public async Task DestroyAsync_Should_SkipRemove_WhenRegistryDisabled() { - InfrastructureStub infrastructure = new InfrastructureStub(_testLogger, _registry, disableRegistry: true); + var infrastructure = new InfrastructureStub(_testLogger, _registry, disableRegistry: true); await infrastructure.DestroyAsync(); A.CallTo(() => _registry.Remove(infrastructure.Id)).MustNotHaveHappened(); } @@ -110,7 +105,7 @@ public async Task DestroyAsync_Should_SkipRemove_WhenRegistryDisabled() [Fact] public async Task ResetAsync_Should_NotifyResetAtRegistry() { - InfrastructureStub infrastructure = new InfrastructureStub(_testLogger, _registry, disableRegistry: false); + var infrastructure = new InfrastructureStub(_testLogger, _registry, disableRegistry: false); await infrastructure.ResetAsync(); A.CallTo(() => _registry.NotifyReset(infrastructure.Id)).MustHaveHappenedOnceExactly(); } @@ -118,7 +113,7 @@ public async Task ResetAsync_Should_NotifyResetAtRegistry() [Fact] public async Task ResetAsync_Should_NotNotifyResetAtRegistry_WhenRegistryDisabled() { - InfrastructureStub infrastructure = new InfrastructureStub(_testLogger, _registry, disableRegistry: true); + var infrastructure = new InfrastructureStub(_testLogger, _registry, disableRegistry: true); await infrastructure.ResetAsync(); A.CallTo(() => _registry.NotifyReset(infrastructure.Id)).MustNotHaveHappened(); } @@ -126,8 +121,8 @@ public async Task ResetAsync_Should_NotNotifyResetAtRegistry_WhenRegistryDisable [Fact] public async Task DisposeAsync_Should_CallDestroyAsync() { - var called = false; - InfrastructureStub infrastructure = new InfrastructureStub(_testLogger, _registry) + bool called = false; + var infrastructure = new InfrastructureStub(_testLogger, _registry) { OnDestroy = async () => called = true }; diff --git a/NotoriousTest.UnitTests/Stubs/DIConfiguratorStub.cs b/NotoriousTest.UnitTests/Stubs/DIConfiguratorStub.cs new file mode 100644 index 0000000..4c643d7 --- /dev/null +++ b/NotoriousTest.UnitTests/Stubs/DIConfiguratorStub.cs @@ -0,0 +1,27 @@ +using FakeItEasy; +using Microsoft.Extensions.DependencyInjection; +using NotoriousTest.Core.DI; +using NotoriousTest.Core.Environments; +using NotoriousTest.Core.Logger; +using NotoriousTest.Core.Registry; +using NotoriousTest.Core.Runtime; +using NotoriousTest.Core.Watchdog; + +namespace NotoriousTest.UnitTests; + +public class DIConfiguratorStub : IDependencyInjectionConfigurator +{ + public IServiceCollection ConfigureServices(IServiceCollection services) => + services + .AddSingleton(A.Fake()) + .AddSingleton(A.Fake()) + .AddSingleton(new EnvironmentSettings()); +} + +public class DIConfiguratorStub2 : IDependencyInjectionConfigurator +{ + public IServiceCollection ConfigureServices(IServiceCollection services) => + services + .AddSingleton(A.Fake()) + .AddSingleton(A.Fake()); +} diff --git a/NotoriousTest.UnitTests/Stubs/EnvironmentStub.cs b/NotoriousTest.UnitTests/Stubs/EnvironmentStub.cs index fa22719..f0c67e8 100644 --- a/NotoriousTest.UnitTests/Stubs/EnvironmentStub.cs +++ b/NotoriousTest.UnitTests/Stubs/EnvironmentStub.cs @@ -8,46 +8,29 @@ using NotoriousTest.Core.Watchdog; using System.Reflection; +using NotoriousTest.Core; namespace NotoriousTest.UnitTests.Stubs { public class EnvironmentStub : EnvironmentBase { - private readonly ITestLogger _logger; - private readonly IWatchDog _watchDog; - private readonly IRegistry _registry; - private readonly IRuntime _runtime; - private readonly ITestSettingsProvider _settings; + public EnvironmentStub(EnvironmentSettings settings, IWatchDog watchDog, IRegistry registry, IRuntime runtime, ITestLogger logger, IServiceProvider serviceProvider) : base(settings, watchDog, registry, runtime, logger, serviceProvider) + { + + } public override Assembly CurrentAssembly => Assembly.GetExecutingAssembly(); + public override Task ConfigureEnvironment() => OnConfigureEnvironment?.Invoke() ?? Task.CompletedTask; + public Func? OnConfigureEnvironment { get; set; } public Action? OnConfigureInfrastructureServices { get; set; } public IServiceProvider PublicServiceProvider => ServiceProvider; - public EnvironmentStub(ITestLogger logger, IWatchDog watchDog, IRegistry registry, IRuntime runtime, ITestSettingsProvider settings) - { - _logger = logger; - _watchDog = watchDog; - _registry = registry; - _runtime = runtime; - _settings = settings; - } - public override Task ConfigureEnvironment() => OnConfigureEnvironment?.Invoke() ?? Task.CompletedTask; - protected override void ConfigureInfrastructureServices(IServiceCollection collection) - { - base.ConfigureInfrastructureServices(collection); - collection.AddSingleton(_logger); - collection.AddSingleton(_registry); - collection.AddSingleton(_watchDog); - collection.AddSingleton(_runtime); - collection.AddSingleton(_settings); - OnConfigureInfrastructureServices?.Invoke(collection); - } } } diff --git a/NotoriousTest.UnitTests/Stubs/InfrastructureStub.cs b/NotoriousTest.UnitTests/Stubs/InfrastructureStub.cs index 2818a36..11ccad0 100644 --- a/NotoriousTest.UnitTests/Stubs/InfrastructureStub.cs +++ b/NotoriousTest.UnitTests/Stubs/InfrastructureStub.cs @@ -1,4 +1,6 @@ -using NotoriousTest.Core.Configuration; +using Microsoft.Extensions.DependencyInjection; +using NotoriousTest.Core; +using NotoriousTest.Core.Configuration; using NotoriousTest.Core.Logger; using NotoriousTest.Core.Registry; @@ -32,6 +34,14 @@ public InfrastructureStub(ITestLogger logger, IRegistry provider, int? order = n AutoReset = autoReset; } + [ActivatorUtilitiesConstructor] + public InfrastructureStub(EnvironmentId id, ITestLogger logger, IRegistry registry): base(id, logger, registry) + { + _order = 1; + _disableRegistry = false; + AutoReset = true; + } + public override Task Destroy() => OnDestroy?.Invoke() ?? Task.CompletedTask; public override Task Initialize() => OnInitialize?.Invoke() ?? Task.CompletedTask; diff --git a/NotoriousTest.UnitTests/Stubs/IntegrationTestStub.cs b/NotoriousTest.UnitTests/Stubs/IntegrationTestStub.cs new file mode 100644 index 0000000..da37105 --- /dev/null +++ b/NotoriousTest.UnitTests/Stubs/IntegrationTestStub.cs @@ -0,0 +1,9 @@ +using NotoriousTest.Core.DI; + +namespace NotoriousTest.UnitTests; + +[InjectionConfigurator(typeof(DIConfiguratorStub))] +[InjectionConfigurator(typeof(DIConfiguratorStub2))] +public class IntegrationTestStub{ + +} diff --git a/NotoriousTest.Watchdog/DoggyDogWatchDog.cs b/NotoriousTest.Watchdog/DoggyDogWatchDog.cs index d7551c9..147055b 100644 --- a/NotoriousTest.Watchdog/DoggyDogWatchDog.cs +++ b/NotoriousTest.Watchdog/DoggyDogWatchDog.cs @@ -22,23 +22,22 @@ public DoggyDogWatchDog(SqliteRegistryProviderConfiguration registryConfiguratio _config = config; } - public Process Start(Assembly currentAssembly, int currentPid, EnvironmentId contextId, IEnumerable? runtimePaths) + public Process Start(Assembly currentAssembly, int currentPid, EnvironmentId environmentId, IEnumerable? runtimePaths) { - var assemblyPath = currentAssembly.Location; + string assemblyPath = currentAssembly.Location; string? runtimesParams = runtimePaths == null ? null : string.Join("|", runtimePaths); if (_config.ManualLaunch) - return WaitForDoggyDogToLaunch(currentPid, contextId, assemblyPath, runtimesParams); - else - return LaunchDoggyDog(currentPid, contextId, assemblyPath, runtimesParams); + return WaitForDoggyDogToLaunch(currentPid, environmentId, assemblyPath, runtimesParams); + return LaunchDoggyDog(currentPid, environmentId, assemblyPath, runtimesParams) ?? throw new Exception("Could not launch DoggyDog"); } - private Process LaunchDoggyDog(int currentPid, EnvironmentId contextId, string assemblyPath, string? runtimesParams) + private Process? LaunchDoggyDog(int currentPid, EnvironmentId contextId, string assemblyPath, string? runtimesParams) { - var watchdogPath = Path.Combine(AppContext.BaseDirectory, RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "DoggyDog.exe" : "DoggyDog"); + string watchdogPath = Path.Combine(AppContext.BaseDirectory, RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "DoggyDog.exe" : "DoggyDog"); - var runtimeParameter = runtimesParams == null ? "" : $"--runtimes \"{runtimesParams}\" "; - Process process = Process.Start(new ProcessStartInfo + string runtimeParameter = runtimesParams == null ? "" : $"--runtimes \"{runtimesParams}\" "; + var process = Process.Start(new ProcessStartInfo { FileName = watchdogPath, Arguments = $"--pid {currentPid} " + @@ -55,19 +54,19 @@ private Process LaunchDoggyDog(int currentPid, EnvironmentId contextId, string a return process; } - private Process WaitForDoggyDogToLaunch(int currentPid, EnvironmentId contextId, string assemblyPath, string? runtimesParams) + private Process WaitForDoggyDogToLaunch(int currentPid, EnvironmentId environmentId, string assemblyPath, string? runtimesParams) { Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_PID", currentPid.ToString(), EnvironmentVariableTarget.User); Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_ASSEMBLY", assemblyPath, EnvironmentVariableTarget.User); Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_CONNECTIONSTRING", _registyConfiguration.ConnectionString, EnvironmentVariableTarget.User); - Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_ENVIRONMENT", contextId.Value.ToString(), EnvironmentVariableTarget.User); + Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_ENVIRONMENT", environmentId.Value.ToString(), EnvironmentVariableTarget.User); Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_RUNTIMES", runtimesParams, EnvironmentVariableTarget.User); Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_LOGLEVEL", "Debug", EnvironmentVariableTarget.User); - Process? doggyDogProcess = null; + Process? doggyDogProcess; do { - _logger.Log("Waiting for DoggyDog to launch..."); + _logger.Log("Waiting for DoggyDog to launch...", environmentId); doggyDogProcess = Process.GetProcessesByName("DoggyDog")?.FirstOrDefault(); Thread.Sleep(5000); @@ -76,18 +75,15 @@ private Process WaitForDoggyDogToLaunch(int currentPid, EnvironmentId contextId, return doggyDogProcess; } - public void SendSuccessSignal(EnvironmentId contextId) - { - File.WriteAllText(Path.Combine(Path.GetTempPath(), $"nt-{contextId.Value}.signal"), "OK"); - } + public void SendSuccessSignal(EnvironmentId contextId) => File.WriteAllText(Path.Combine(Path.GetTempPath(), $"nt-{contextId.Value}.signal"), "OK"); public static bool ReadSuccessSignal(EnvironmentId contextId) { - var path = Path.Combine(Path.GetTempPath(), $"nt-{contextId.Value}.signal"); - var isSuccess = File.Exists(path); + string path = Path.Combine(Path.GetTempPath(), $"nt-{contextId.Value}.signal"); + bool isSuccess = File.Exists(path); if (isSuccess) File.Delete(path); return isSuccess; } } -} \ No newline at end of file +} diff --git a/NotoriousTest.Web/Environments/WebEnvironmentExtensions.cs b/NotoriousTest.Web/Environments/WebEnvironmentExtensions.cs index ea8f0dc..30f0b66 100644 --- a/NotoriousTest.Web/Environments/WebEnvironmentExtensions.cs +++ b/NotoriousTest.Web/Environments/WebEnvironmentExtensions.cs @@ -1,7 +1,7 @@ -using NotoriousTest.Web.Applications; +using NotoriousTest.Core.Environments; +using NotoriousTest.Web.Applications; using NotoriousTest.Web.Infrastructures; -using EnvironmentBase = NotoriousTest.Environments.EnvironmentBase; namespace NotoriousTest.Web { diff --git a/NotoriousTest.XUnit/DI/XUnitDependencyInjectionConfigurator.cs b/NotoriousTest.XUnit/DI/XUnitDependencyInjectionConfigurator.cs new file mode 100644 index 0000000..ec153df --- /dev/null +++ b/NotoriousTest.XUnit/DI/XUnitDependencyInjectionConfigurator.cs @@ -0,0 +1,15 @@ +using Microsoft.Extensions.DependencyInjection; +using NotoriousTest.Core; +using NotoriousTest.Core.Logger; +using NotoriousTest.Core.DI; +using NotoriousTest.XUnit.Logger; +using Xunit; + +namespace NotoriousTest.XUnit.DI; + +public class XUnitDependencyInjectionConfigurator : IDependencyInjectionConfigurator +{ + public IServiceCollection ConfigureServices(IServiceCollection services) => + services + .AddSingleton(); +} diff --git a/NotoriousTest.XUnit/Environment.cs b/NotoriousTest.XUnit/Environment.cs deleted file mode 100644 index 13fc70e..0000000 --- a/NotoriousTest.XUnit/Environment.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; - -using NotoriousTest.Core.Logger; -using NotoriousTest.Environments; -using NotoriousTest.XUnit.Logger; - -using Xunit; -using Xunit.Sdk; - -namespace NotoriousTest.XUnit -{ - public abstract class Environment : EnvironmentBase, IAsyncLifetime - { - private readonly IMessageSink _sink; - - protected Environment(IMessageSink sink) - { - _sink = sink; - } - - protected override void ConfigureInfrastructureServices(IServiceCollection collection) - { - base.ConfigureInfrastructureServices(collection); - - collection - .AddSingleton(_sink) - .AddSingleton(); - } - - public async ValueTask DisposeAsync() - { - await Destroy(); - } - - public async ValueTask InitializeAsync() - { - await Initialize(); - } - } -} diff --git a/NotoriousTest.XUnit/IntegrationTest.cs b/NotoriousTest.XUnit/IntegrationTest.cs deleted file mode 100644 index 8cb7e31..0000000 --- a/NotoriousTest.XUnit/IntegrationTest.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Threading.Tasks; - -using Xunit; - -namespace NotoriousTest.XUnit -{ - public abstract class IntegrationTest : IClassFixture, IAsyncLifetime where T : Environment - { - protected readonly T CurrentEnvironment; - - public IntegrationTest(T environment) - { - // Called before each tests - CurrentEnvironment = environment; - } - - public async ValueTask InitializeAsync() - { - } - - public async ValueTask DisposeAsync() - { - await CurrentEnvironment.Reset(); - } - } -} diff --git a/NotoriousTest.XUnit/IntegrationTestBase.cs b/NotoriousTest.XUnit/IntegrationTestBase.cs new file mode 100644 index 0000000..addcbaf --- /dev/null +++ b/NotoriousTest.XUnit/IntegrationTestBase.cs @@ -0,0 +1,20 @@ +using NotoriousTest.Core.Environments; +using NotoriousTest.Core.DI; +using NotoriousTest.XUnit.DI; +using Xunit; + +namespace NotoriousTest.XUnit +{ + [InjectionConfigurator(typeof(XUnitDependencyInjectionConfigurator))] + public abstract class IntegrationTest : NotoriousTest.IntegrationTestBase, + IClassFixture>, + IAsyncDisposable where TEnvironment : EnvironmentBase + { + public IntegrationTest(XUnitFixture fixture) + { + Fixture = fixture; + } + + public async ValueTask DisposeAsync() => await Environment.Reset(); + } +} diff --git a/NotoriousTest.XUnit/Logger/TestLogger.cs b/NotoriousTest.XUnit/Logger/TestLogger.cs deleted file mode 100644 index fc0e585..0000000 --- a/NotoriousTest.XUnit/Logger/TestLogger.cs +++ /dev/null @@ -1,25 +0,0 @@ -using NotoriousTest.Core; -using NotoriousTest.Core.Logger; - -using Xunit.Sdk; -using Xunit.v3; - -namespace NotoriousTest.XUnit.Logger -{ - public class TestLogger : ITestLogger - { - private readonly IMessageSink _sink; - private readonly EnvironmentId _contextId; - - public TestLogger(IMessageSink sink, EnvironmentId contextId) - { - _sink = sink; - _contextId = contextId; - } - - public void Log(string message) - { - _sink.OnMessage(new DiagnosticMessage($"[NotoriousTest][{_contextId.Value.ToString()}]{message}")); - } - } -} diff --git a/NotoriousTest.XUnit/Logger/XUnitTestLogger.cs b/NotoriousTest.XUnit/Logger/XUnitTestLogger.cs new file mode 100644 index 0000000..204f302 --- /dev/null +++ b/NotoriousTest.XUnit/Logger/XUnitTestLogger.cs @@ -0,0 +1,13 @@ +using NotoriousTest.Core; +using NotoriousTest.Core.Logger; +using Xunit; +using Xunit.Sdk; +using Xunit.v3; + +namespace NotoriousTest.XUnit.Logger +{ + public class XUnitTestLogger : ITestLogger + { + public void Log(string message, EnvironmentId environmentId) => TestContext.Current.SendDiagnosticMessage($"[NotoriousTest][{environmentId.Value.ToString()}]{message}"); + } +} diff --git a/NotoriousTest.XUnit/XUnitFixture.cs b/NotoriousTest.XUnit/XUnitFixture.cs new file mode 100644 index 0000000..2ae7d48 --- /dev/null +++ b/NotoriousTest.XUnit/XUnitFixture.cs @@ -0,0 +1,16 @@ +using NotoriousTest.Core; +using NotoriousTest.Core.Environments; +using Xunit; +using Xunit.v3; + +namespace NotoriousTest.XUnit; + +public class XUnitFixture : Fixture, IAsyncLifetime where TEnvironment : EnvironmentBase +{ + public XUnitFixture() : base((TestContext.Current.TestClass as XunitTestClass)?.Class) + { + } + + public async ValueTask InitializeAsync() => await Environment.Initialize(); + public async ValueTask DisposeAsync() => await Environment.Destroy(); +} diff --git a/NotoriousTest.sln.DotSettings.user b/NotoriousTest.sln.DotSettings.user index 03644ab..eec3120 100644 --- a/NotoriousTest.sln.DotSettings.user +++ b/NotoriousTest.sln.DotSettings.user @@ -1,7 +1,17 @@  + ForceIncluded + ForceIncluded + ForceIncluded ForceIncluded - <SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from &lt;src&gt;\&lt;5. Samples&gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> - <Project Location="C:\Repositories\Notorious Test" Presentation="&lt;src&gt;\&lt;5. Samples&gt;" /> + ForceIncluded + ForceIncluded + ForceIncluded + <SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from &lt;src&gt;\&lt;5. Samples&gt;\&lt;NotoriousTest.Sample.NUnit&gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> + <Or> + <Project Location="C:\Repositories\Notorious Test\NotoriousTest.IntegrationTests" Presentation="&lt;src&gt;\&lt;4. Tests&gt;\&lt;NotoriousTest.IntegrationTests&gt;" /> + <Project Location="C:\Repositories\Notorious Test\NotoriousTest.UnitTests" Presentation="&lt;src&gt;\&lt;4. Tests&gt;\&lt;NotoriousTest.UnitTests&gt;" /> + <Project Location="C:\Repositories\Notorious Test" Presentation="&lt;src&gt;\&lt;5. Samples&gt;" /> + </Or> </SessionState> @@ -13,4 +23,6 @@ + + KillOrphaned \ No newline at end of file diff --git a/NotoriousTest/DI/DependencyInjectionConfigurator.cs b/NotoriousTest/DI/DependencyInjectionConfigurator.cs new file mode 100644 index 0000000..cc6ad08 --- /dev/null +++ b/NotoriousTest/DI/DependencyInjectionConfigurator.cs @@ -0,0 +1,42 @@ +using Microsoft.Data.Sqlite; +using Microsoft.Extensions.DependencyInjection; +using NotoriousTest.Core; +using NotoriousTest.Core.DI; +using NotoriousTest.Core.Environments; +using NotoriousTest.Core.Logger; +using NotoriousTest.Core.Registry; +using NotoriousTest.Core.Runtime; +using NotoriousTest.Core.Settings; +using NotoriousTest.Core.Watchdog; +using NotoriousTest.Environments; +using NotoriousTest.Runtime; +using NotoriousTest.SqlLiteRegistry; +using NotoriousTest.Watchdog; + +namespace NotoriousTest.DI; + +public class DependencyInjectionConfigurator : IDependencyInjectionConfigurator +{ + public virtual IServiceCollection ConfigureServices(IServiceCollection services) + { + var builder = new SqliteConnectionStringBuilder + { + DataSource = SettingsDefaults.DefaultRegistryConnectionString + }; + + var registryConfig = new SqliteRegistryProviderConfiguration() + { + ConnectionString = builder.ConnectionString + }; + + var settingsProvider = new TestSettingsProvider(); + services + .AddSingleton(settingsProvider) + .AddSingleton(settingsProvider.Get(EnvironmentSettings.SECTION_NAME) ?? new EnvironmentSettings()) + .AddSingleton((_) => new SqliteRegistryProvider(registryConfig)) + .AddSingleton((services) => new DoggyDogWatchDog(registryConfig, services.GetRequiredService(), settingsProvider.Get("Watchdog") ?? new DoggyDogWatchdogConfiguration())) + .AddSingleton(); + + return services; + } +} diff --git a/NotoriousTest/Environments/EnvironmentBase.cs b/NotoriousTest/Environments/EnvironmentBase.cs deleted file mode 100644 index c99e367..0000000 --- a/NotoriousTest/Environments/EnvironmentBase.cs +++ /dev/null @@ -1,40 +0,0 @@ - - -using Microsoft.Data.Sqlite; -using Microsoft.Extensions.DependencyInjection; - -using NotoriousTest.Core.Logger; -using NotoriousTest.Core.Registry; -using NotoriousTest.Core.Runtime; -using NotoriousTest.Core.Settings; -using NotoriousTest.Core.Watchdog; -using NotoriousTest.Runtime; -using NotoriousTest.SqlLiteRegistry; -using NotoriousTest.Watchdog; - -namespace NotoriousTest.Environments -{ - public abstract class EnvironmentBase : Core.Environments.EnvironmentBase - { - protected override void ConfigureInfrastructureServices(IServiceCollection collection) - { - base.ConfigureInfrastructureServices(collection); - - var builder = new SqliteConnectionStringBuilder - { - DataSource = EnvironmentBaseDefaults.DefaultRegistryConnectionString - }; - - var registryConfig = new SqliteRegistryProviderConfiguration() - { - ConnectionString = builder.ConnectionString - }; - var settingsProvider = new TestSettingsProvider(); - collection.AddSingleton(settingsProvider) - .AddSingleton((_) => new SqliteRegistryProvider(registryConfig)) - .AddSingleton((services) => new DoggyDogWatchDog(registryConfig, services.GetRequiredService(), settingsProvider.Get("Watchdog") ?? new DoggyDogWatchdogConfiguration())) - .AddSingleton(); - - } - } -} diff --git a/NotoriousTest/IntegrationTestBase.cs b/NotoriousTest/IntegrationTestBase.cs new file mode 100644 index 0000000..97cf612 --- /dev/null +++ b/NotoriousTest/IntegrationTestBase.cs @@ -0,0 +1,11 @@ +using NotoriousTest.Core.DI; +using NotoriousTest.Core.Environments; +using DependencyInjectionConfigurator = NotoriousTest.DI.DependencyInjectionConfigurator; + +namespace NotoriousTest; + +[InjectionConfigurator(typeof(DependencyInjectionConfigurator))] +public abstract class IntegrationTestBase : NotoriousTest.Core.IntegrationTestBase where T : EnvironmentBase +{ + +} diff --git a/NotoriousTest/NotoriousTest.csproj b/NotoriousTest/NotoriousTest.csproj index 7f6d5cf..5b9c055 100644 --- a/NotoriousTest/NotoriousTest.csproj +++ b/NotoriousTest/NotoriousTest.csproj @@ -23,4 +23,10 @@ + + + + + + \ No newline at end of file diff --git a/NotoriousTest/Environments/EnvironmentBaseDefaults.cs b/NotoriousTest/SettingsDefaults.cs similarity index 85% rename from NotoriousTest/Environments/EnvironmentBaseDefaults.cs rename to NotoriousTest/SettingsDefaults.cs index 797a2c1..fba5c0c 100644 --- a/NotoriousTest/Environments/EnvironmentBaseDefaults.cs +++ b/NotoriousTest/SettingsDefaults.cs @@ -1,6 +1,6 @@ namespace NotoriousTest.Environments { - internal class EnvironmentBaseDefaults + internal class SettingsDefaults { public static readonly string DefaultRegistryConnectionString = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "notorioustest/doggydog-registry.db"); } diff --git a/Samples/NotoriousTest.Sample.MSTest/Environments/TestEnvironment.cs b/Samples/NotoriousTest.Sample.MSTest/Environments/TestEnvironment.cs index ef90af7..f5d20f5 100644 --- a/Samples/NotoriousTest.Sample.MSTest/Environments/TestEnvironment.cs +++ b/Samples/NotoriousTest.Sample.MSTest/Environments/TestEnvironment.cs @@ -5,13 +5,28 @@ using NotoriousTest.Sample.MSTest.Infrastructures; using System.Reflection; +using NotoriousTest.Core.Environments; +using NotoriousTest.Core.Logger; +using NotoriousTest.Core.Registry; +using NotoriousTest.Core.Runtime; +using NotoriousTest.Core.Watchdog; namespace NotoriousTest.Sample.MSTest.Environments { // In fact, this is a test fixture (MSTest terminology: ClassInitialize/ClassCleanup). - public class TestEnvironment : NotoriousTest.MSTest.Environment + public class TestEnvironment : EnvironmentBase { - public TestEnvironment(TestContext testContext) : base(testContext) + public TestEnvironment(EnvironmentSettings settings, + IWatchDog watchDog, + IRegistry registry, + IRuntime runtime, + ITestLogger logger, + IServiceProvider serviceProvider) : base(settings, + watchDog, + registry, + runtime, + logger, + serviceProvider) { } diff --git a/Samples/NotoriousTest.Sample.MSTest/SampleTests.cs b/Samples/NotoriousTest.Sample.MSTest/SampleTestsBase.cs similarity index 83% rename from Samples/NotoriousTest.Sample.MSTest/SampleTests.cs rename to Samples/NotoriousTest.Sample.MSTest/SampleTestsBase.cs index c1602f7..19ce644 100644 --- a/Samples/NotoriousTest.Sample.MSTest/SampleTests.cs +++ b/Samples/NotoriousTest.Sample.MSTest/SampleTestsBase.cs @@ -10,7 +10,7 @@ namespace NotoriousTest.Sample.MSTest { [TestClass] - public class SampleTests : NotoriousTest.MSTest.IntegrationTest + public class SampleTestsBase : NotoriousTest.MSTest.IntegrationTestBase { // Do not hesitate to create your test framework for your app, that will use the environment. // Example : new MyAppTestFramework(environment); @@ -22,13 +22,13 @@ public async Task Test1() { // You can access an infrastructure directly from the CurrentEnvironment property of the test class. // This is useful to access the database connection for example. - HttpClient client = CurrentEnvironment.GetWebApplication().HttpClient; + HttpClient client = Environment.GetWebApplication().HttpClient; HttpResponseMessage response = await client.PostAsync("users", null); // Then assert that the database is in the expected state Assert.IsTrue(response.IsSuccessStatusCode); - SqlServerInfrastructure sqlInfrastructure = CurrentEnvironment.GetInfrastructure(); + SqlServerInfrastructure sqlInfrastructure = Environment.GetInfrastructure(); await using (DbConnection sql = sqlInfrastructure.GetDatabaseConnection()) { await sql.OpenAsync(); @@ -46,13 +46,13 @@ public async Task Test2() { // You can access an infrastructure directly from the CurrentEnvironment property of the test class. // This is useful to access the database connection for example. - HttpClient client = CurrentEnvironment.GetWebApplication().HttpClient; + HttpClient client = Environment.GetWebApplication().HttpClient; HttpResponseMessage response = await client.PostAsync("users", null); // Then assert that the database is in the expected state Assert.IsTrue(response.IsSuccessStatusCode); - SqlServerInfrastructure sqlInfrastructure = CurrentEnvironment.GetInfrastructure(); + SqlServerInfrastructure sqlInfrastructure = Environment.GetInfrastructure(); await using (DbConnection sql = sqlInfrastructure.GetDatabaseConnection()) { await sql.OpenAsync(); diff --git a/Samples/NotoriousTest.Sample.NUnit/Environments/TestEnvironment.cs b/Samples/NotoriousTest.Sample.NUnit/Environments/TestEnvironment.cs index 89cf324..a9233ac 100644 --- a/Samples/NotoriousTest.Sample.NUnit/Environments/TestEnvironment.cs +++ b/Samples/NotoriousTest.Sample.NUnit/Environments/TestEnvironment.cs @@ -3,11 +3,20 @@ using NotoriousTest.Sample.NUnit.Infrastructures; using System.Reflection; +using NotoriousTest.Core.Environments; +using NotoriousTest.Core.Logger; +using NotoriousTest.Core.Registry; +using NotoriousTest.Core.Runtime; +using NotoriousTest.Core.Watchdog; namespace NotoriousTest.Sample.NUnit.Environments { - public class TestEnvironment : NotoriousTest.NUnit.Environment + public class TestEnvironment : EnvironmentBase { + public TestEnvironment(EnvironmentSettings settings, IWatchDog watchDog, IRegistry registry, IRuntime runtime, ITestLogger logger, IServiceProvider serviceProvider) : base(settings, watchDog, registry, runtime, logger, serviceProvider) + { + } + public override Assembly CurrentAssembly => Assembly.GetExecutingAssembly(); // This is called at the start of the test campaign diff --git a/Samples/NotoriousTest.Sample.NUnit/SampleTests.cs b/Samples/NotoriousTest.Sample.NUnit/SampleTestsBase.cs similarity index 80% rename from Samples/NotoriousTest.Sample.NUnit/SampleTests.cs rename to Samples/NotoriousTest.Sample.NUnit/SampleTestsBase.cs index ae1d551..c65c19b 100644 --- a/Samples/NotoriousTest.Sample.NUnit/SampleTests.cs +++ b/Samples/NotoriousTest.Sample.NUnit/SampleTestsBase.cs @@ -10,7 +10,7 @@ namespace NotoriousTest.Sample.NUnit { [TestFixture] - public class SampleTests : NotoriousTest.NUnit.IntegrationTest + public class SampleTestsBase : NotoriousTest.NUnit.IntegrationTestBase { // Do not hesitate to create your test framework for your app, that will use the environment. // Example : new MyAppTestFramework(environment); @@ -22,13 +22,13 @@ public async Task Test1() { // You can access an infrastructure directly from the CurrentEnvironment property of the test class. // This is useful to access the database connection for example. - HttpClient client = CurrentEnvironment.GetWebApplication().HttpClient; - HttpResponseMessage response = await client.PostAsync("users", null); + HttpClient? client = Environment.GetWebApplication().HttpClient; + HttpResponseMessage response = await client?.PostAsync("users", null)!; // Then assert that the database is in the expected state Assert.That(response.IsSuccessStatusCode, Is.True); - SqlServerInfrastructure sqlInfrastructure = CurrentEnvironment.GetInfrastructure(); + SqlServerInfrastructure sqlInfrastructure = Environment.GetInfrastructure(); await using (DbConnection sql = sqlInfrastructure.GetDatabaseConnection()) { await sql.OpenAsync(); @@ -46,13 +46,13 @@ public async Task Test2() { // You can access an infrastructure directly from the CurrentEnvironment property of the test class. // This is useful to access the database connection for example. - HttpClient client = CurrentEnvironment.GetWebApplication().HttpClient; + HttpClient client = Environment.GetWebApplication().HttpClient; HttpResponseMessage response = await client.PostAsync("users", null); // Then assert that the database is in the expected state Assert.That(response.IsSuccessStatusCode, Is.True); - SqlServerInfrastructure sqlInfrastructure = CurrentEnvironment.GetInfrastructure(); + SqlServerInfrastructure sqlInfrastructure = Environment.GetInfrastructure(); await using (DbConnection sql = sqlInfrastructure.GetDatabaseConnection()) { await sql.OpenAsync(); diff --git a/Samples/NotoriousTest.Sample.TUnit/Environments/TestEnvironment.cs b/Samples/NotoriousTest.Sample.TUnit/Environments/TestEnvironment.cs index 9ef4797..72365d6 100644 --- a/Samples/NotoriousTest.Sample.TUnit/Environments/TestEnvironment.cs +++ b/Samples/NotoriousTest.Sample.TUnit/Environments/TestEnvironment.cs @@ -3,12 +3,31 @@ using NotoriousTest.Sample.TUnit.Infrastructures; using System.Reflection; +using NotoriousTest.Core.Environments; +using NotoriousTest.Core.Logger; +using NotoriousTest.Core.Registry; +using NotoriousTest.Core.Runtime; +using NotoriousTest.Core.Watchdog; namespace NotoriousTest.Sample.TUnit.Environments { // In fact, this is a test fixture (MSTest terminology: ClassInitialize/ClassCleanup). - public class TestEnvironment : NotoriousTest.TUnit.Environment + public class TestEnvironment : EnvironmentBase { + public TestEnvironment(EnvironmentSettings settings, + IWatchDog watchDog, + IRegistry registry, + IRuntime runtime, + ITestLogger logger, + IServiceProvider serviceProvider) : base(settings, + watchDog, + registry, + runtime, + logger, + serviceProvider) + { + } + public override Assembly CurrentAssembly => System.Reflection.Assembly.GetExecutingAssembly(); // This is called at the start of the test campaign diff --git a/Samples/NotoriousTest.Sample.TUnit/SampleTests.cs b/Samples/NotoriousTest.Sample.TUnit/SampleTestsBase.cs similarity index 70% rename from Samples/NotoriousTest.Sample.TUnit/SampleTests.cs rename to Samples/NotoriousTest.Sample.TUnit/SampleTestsBase.cs index 0414bc0..0b1919c 100644 --- a/Samples/NotoriousTest.Sample.TUnit/SampleTests.cs +++ b/Samples/NotoriousTest.Sample.TUnit/SampleTestsBase.cs @@ -4,32 +4,32 @@ using NotoriousTest.Sample.TUnit.Infrastructures; using System.Data.Common; +using NotoriousTest.TUnit; namespace NotoriousTest.Sample.TUnit { - public class SampleTests : NotoriousTest.TUnit.IntegrationTest + public class SampleTestsBase : NotoriousTest.TUnit.IntegrationTestBase { - public SampleTests(TestEnvironment environment) : base(environment) + public SampleTestsBase(TUnitFixture fixture) : base(fixture) { + // Do not hesitate to create your test framework for your app, that will use the environment. + // Example : new MyAppTestFramework(environment); + // Then, you could create multiple methods to assert, arrange, act + // that you could do multiple times in your tests. } - // Do not hesitate to create your test framework for your app, that will use the environment. - // Example : new MyAppTestFramework(environment); - // Then, you could create multiple methods to assert, arrange, act - // that you could do multiple times in your tests. - [Test] public async Task Test1() { // You can access an infrastructure directly from the CurrentEnvironment property of the test class. // This is useful to access the database connection for example. - HttpClient client = CurrentEnvironment.GetWebApplication().HttpClient; + HttpClient client = Environment.GetWebApplication().HttpClient; HttpResponseMessage response = await client.PostAsync("users", null); // Then assert that the database is in the expected state await Assert.That(response.IsSuccessStatusCode).IsTrue(); - SqlServerInfrastructure sqlInfrastructure = CurrentEnvironment.GetInfrastructure(); + SqlServerInfrastructure sqlInfrastructure = Environment.GetInfrastructure(); await using (DbConnection sql = sqlInfrastructure.GetDatabaseConnection()) { await sql.OpenAsync(); @@ -47,13 +47,13 @@ public async Task Test2() { // You can access an infrastructure directly from the CurrentEnvironment property of the test class. // This is useful to access the database connection for example. - HttpClient client = CurrentEnvironment.GetWebApplication().HttpClient; + HttpClient client = Environment.GetWebApplication().HttpClient; HttpResponseMessage response = await client.PostAsync("users", null); // Then assert that the database is in the expected state await Assert.That(response.IsSuccessStatusCode).IsTrue(); - SqlServerInfrastructure sqlInfrastructure = CurrentEnvironment.GetInfrastructure(); + SqlServerInfrastructure sqlInfrastructure = Environment.GetInfrastructure(); await using (DbConnection sql = sqlInfrastructure.GetDatabaseConnection()) { await sql.OpenAsync(); diff --git a/Samples/NotoriousTest.Sample.With/WithNotoriousTestSample.cs b/Samples/NotoriousTest.Sample.With/WithNotoriousTestBaseSample.cs similarity index 94% rename from Samples/NotoriousTest.Sample.With/WithNotoriousTestSample.cs rename to Samples/NotoriousTest.Sample.With/WithNotoriousTestBaseSample.cs index 7a7dc42..e1652e2 100644 --- a/Samples/NotoriousTest.Sample.With/WithNotoriousTestSample.cs +++ b/Samples/NotoriousTest.Sample.With/WithNotoriousTestBaseSample.cs @@ -7,9 +7,9 @@ namespace NotoriousTest.Sample.With { - public class WithNotoriousTestSample : IntegrationTest + public class WithNotoriousTestBaseSample : IntegrationTest { - public WithNotoriousTestSample(MyEnvironment environment) : base(environment) + public WithNotoriousTestBaseSample(MyEnvironment environment) : base(environment) { } diff --git a/Samples/NotoriousTest.Sample.XUnit/Environments/TestEnvironment.cs b/Samples/NotoriousTest.Sample.XUnit/Environments/TestEnvironment.cs index 6bb70df..6c0dc73 100644 --- a/Samples/NotoriousTest.Sample.XUnit/Environments/TestEnvironment.cs +++ b/Samples/NotoriousTest.Sample.XUnit/Environments/TestEnvironment.cs @@ -3,15 +3,29 @@ using NotoriousTest.Sample.XUnit.Infrastructures; using System.Reflection; - +using NotoriousTest.Core.Environments; +using NotoriousTest.Core.Logger; +using NotoriousTest.Core.Registry; +using NotoriousTest.Core.Runtime; +using NotoriousTest.Core.Watchdog; using Xunit.Sdk; namespace NotoriousTest.Sample.XUnit.Environments { // In fact, this is a test fixture (xUnit terminology). - public class TestEnvironment : NotoriousTest.XUnit.Environment + public class TestEnvironment : EnvironmentBase { - public TestEnvironment(IMessageSink sink) : base(sink) + public TestEnvironment(EnvironmentSettings settings, + IWatchDog watchDog, + IRegistry registry, + IRuntime runtime, + ITestLogger logger, + IServiceProvider serviceProvider) : base(settings, + watchDog, + registry, + runtime, + logger, + serviceProvider) { } @@ -24,7 +38,7 @@ public override async Task ConfigureEnvironment() // Every environment generate an EnvironmentId that is unique for each test campaign AddInfrastructure(); - // Here, we directly use the WebApplication without infrastructure. + // Here, we directly use the WebApplication without infrastructure. // It will be added to a default web application infrastructure // already configured to use environment Program class // and to consume the configuration generated by other infrastructures. diff --git a/Samples/NotoriousTest.Sample.XUnit/SampleTests.cs b/Samples/NotoriousTest.Sample.XUnit/SampleTestsBase.cs similarity index 81% rename from Samples/NotoriousTest.Sample.XUnit/SampleTests.cs rename to Samples/NotoriousTest.Sample.XUnit/SampleTestsBase.cs index 732dd4d..94aa500 100644 --- a/Samples/NotoriousTest.Sample.XUnit/SampleTests.cs +++ b/Samples/NotoriousTest.Sample.XUnit/SampleTestsBase.cs @@ -4,12 +4,14 @@ using NotoriousTest.XUnit; using System.Data.Common; +using NotoriousTest.Core.DI; +using NotoriousTest.XUnit.DI; namespace NotoriousTest.Sample.XUnit { - public class SampleTests : IntegrationTest + public class SampleTestsBase : IntegrationTest { - public SampleTests(TestEnvironment environment) : base(environment) + public SampleTestsBase(XUnitFixture fixture) : base(fixture) { // Do not hesitate to create your test framework for your app, that will use the environment. // Example : new MyAppTestFramework(environment); @@ -22,13 +24,13 @@ public async Task Test1() { // You can access an infrastructure directly from the CurrentEnvironment property of the test class. // This is useful to access the database connection for example. - HttpClient client = CurrentEnvironment.GetWebApplication().HttpClient; + HttpClient client = Environment.GetWebApplication().HttpClient; HttpResponseMessage response = await client.PostAsync("users", null); // Then assert that the database is in the expected state Assert.True(response.IsSuccessStatusCode); - SqlServerInfrastructure sqlInfrastructure = CurrentEnvironment.GetInfrastructure(); + SqlServerInfrastructure sqlInfrastructure = Environment.GetInfrastructure(); await using (DbConnection sql = sqlInfrastructure.GetDatabaseConnection()) { // Then act with a call to the API @@ -47,13 +49,13 @@ public async Task Test2() { // You can access an infrastructure directly from the CurrentEnvironment property of the test class. // This is useful to access the database connection for example. - HttpClient client = CurrentEnvironment.GetWebApplication().HttpClient; + HttpClient client = Environment.GetWebApplication().HttpClient; HttpResponseMessage response = await client.PostAsync("users", null); // Then assert that the database is in the expected state Assert.True(response.IsSuccessStatusCode); - SqlServerInfrastructure sqlInfrastructure = CurrentEnvironment.GetInfrastructure(); + SqlServerInfrastructure sqlInfrastructure = Environment.GetInfrastructure(); await using (DbConnection sql = sqlInfrastructure.GetDatabaseConnection()) { // Then act with a call to the API diff --git a/TestResults/NotoriousTest.Sample.TUnit-windows-net10.0-report.html b/TestResults/NotoriousTest.Sample.TUnit-windows-net10.0-report.html index 05d6346..be3a229 100644 --- a/TestResults/NotoriousTest.Sample.TUnit-windows-net10.0-report.html +++ b/TestResults/NotoriousTest.Sample.TUnit-windows-net10.0-report.html @@ -12,7 +12,7 @@ -
-19 avr. 2026, 23:23:43 UTC +03 mai 2026, 11:04:02 UTC DESKTOP-G35EPH3 Microsoft Windows 10.0.19045 -.NET 10.0.6 +.NET 10.0.7 TUnit 1.27.0.0
- - + + @@ -104,7 +104,7 @@

NotoriousTest.Sample.TUnit

- +