Skip to content

V11.1.0/support for integration testing#63

Merged
gimlichael merged 22 commits into
mainfrom
v11.1.0/support-for-integration-testing
Jun 5, 2026
Merged

V11.1.0/support for integration testing#63
gimlichael merged 22 commits into
mainfrom
v11.1.0/support-for-integration-testing

Conversation

@gimlichael
Copy link
Copy Markdown
Member

This pull request introduces version 11.1.0, a significant minor release that expands integration testing support for .NET applications beyond ASP.NET Core, providing new abstractions and patterns for Program.cs-based testing in both generic host and web scenarios. It adds new factory and fixture classes, comprehensive documentation, and a suite of reference applications and functional tests. The solution structure and dependencies are also updated for consistency and modernization.

Key changes:

New Features and Abstractions

  • Introduced ApplicationHostFactory, ApplicationTestFactory, ApplicationTest<TEntryPoint,T>, IApplicationFixture<TEntryPoint>, BlockingManagedApplicationFixture<TEntryPoint>, and ApplicationFixtureExtensions in the Codebelt.Extensions.Xunit.Hosting namespace, enabling Program.cs-based integration testing for console, worker, and generic host applications. [1] [2] [3]
  • Added WebApplicationTestFactory, WebApplicationTest<TEntryPoint,T>, IWebApplicationFixture<TEntryPoint>, BlockingManagedWebApplicationFixture<TEntryPoint>, and WebApplicationFixtureExtensions in the Codebelt.Extensions.Xunit.Hosting.AspNetCore namespace, supporting TestServer-based integration tests for ASP.NET Core applications. [1] [2] [3]

Reference Applications and Functional Tests

  • Added eight bootstrapper reference applications demonstrating various host and web patterns, including minimal hosting, classic Startup, worker services, and top-level statements, all under the new /app/ solution folder. [1] [2] [3] [4] [5]
  • Introduced functional test projects for both hosting and ASP.NET Core abstractions to validate real-world scenarios. [1] [2]

Documentation and Conventions

  • Expanded official documentation in .docfx/api/namespaces/ to clarify fixture naming conventions and public API patterns for both hosting and ASP.NET Core namespaces. [1] [2] [3]

Dependency and Solution Modernization

  • Upgraded dependencies to the latest compatible versions, including new bootstrapper packages and a newer Microsoft.NET.Test.Sdk. [1] [2] [3] [4] [5] [6] [7] [8]
  • Standardized package release notes and solution file structure for clarity and maintainability. [1] [2] [3] [4]

Please review the new abstractions, reference applications, and updated documentation to familiarize yourself with the expanded integration testing capabilities and conventions.

gimlichael and others added 17 commits June 5, 2026 01:46
Core abstractions for Program.cs-based host integration testing:
- ApplicationHostFactory for creating started IHost instances from entry points
- ApplicationTest{TEntryPoint,T} base class for host testing patterns
- IApplicationFixture{TEntryPoint} for fixture-based lifecycle management
- ManagedApplicationFixture{TEntryPoint} implementing host factory integration
- ApplicationFixtureExtensions for convenient fixture setup methods
- ProgramHostFactoryResolver for resolving host factories from entry points
- DeferredHostBuilder for deferred host configuration

Includes functional test coverage validating hosting abstractions.
ASP.NET Core specific abstractions for Program.cs-based TestServer testing:
- WebApplicationTest{TEntryPoint,T} base class for web application testing
- IWebApplicationFixture{TEntryPoint} for web application lifecycle fixtures
- ManagedWebApplicationFixture{TEntryPoint} implementing web fixture integration
- WebApplicationFixtureExtensions for convenient web fixture setup methods
- WebApplicationHostFactory for creating started web application instances

Includes functional test coverage for ASP.NET Core Minimal Hosting and
classic Startup.cs patterns with TestServer integration.
Eight example applications demonstrating host patterns for testing:

Generic Host patterns:
- BootstrapperConsole.App with classic Startup.cs pattern
- BootstrapperMinimalConsole.App with minimal hosting API
- BootstrapperWorker.App with BackgroundService and Startup.cs
- BootstrapperMinimalWorker.App minimal worker service pattern

ASP.NET Core patterns:
- BootstrapperWeb.App with ASP.NET Core and Startup.cs
- BootstrapperMinimalWeb.App minimal ASP.NET Core pattern
- BootstrapperClassicProgram.App top-level statement example
- BootstrapperProgram.App advanced Program.cs customization

Reference implementations for integration test validation.
Added new bootstrapper packages for integration test references:
- Codebelt.Bootstrapper.Console (5.1.0)
- Codebelt.Bootstrapper.Web (5.1.0)
- Codebelt.Bootstrapper.Worker (5.1.0)

Updated existing packages:
- Codebelt.Extensions.BenchmarkDotNet.Console: 1.2.6 → 1.2.7
- Microsoft.NET.Test.Sdk: 18.5.1 → 18.6.0

All target framework versions remain compatible.
Solution structure:
- Added /app/ folder containing 8 bootstrapper reference applications
- Added Codebelt.Extensions.Xunit.Hosting.FunctionalTests to /test/ folder
- Added Codebelt.Extensions.Xunit.Hosting.AspNetCore.FunctionalTests to /test/ folder

Project updates:
- Updated Codebelt.Extensions.Xunit.Hosting.AspNetCore.Tests.csproj with new test references
Codebelt.Extensions.Xunit.Hosting 11.1.0:
- Added ApplicationHostFactory for IHost creation from entry points
- Added ApplicationTest{TEntryPoint,T} and related fixture abstractions
- Updated version and availability across supported frameworks
- Preserved existing version history with formatting cleanup

Codebelt.Extensions.Xunit.Hosting.AspNetCore 11.1.0:
- Added WebApplicationTest{TEntryPoint,T} and fixture abstractions
- Added web application lifecycle and TestServer integration support
- Updated version for .NET 10 and .NET 9 availability
- Preserved existing version history with formatting cleanup
Release documentation for version 11.1.0 including changelog updates and per-package release notes for Codebelt.Extensions.Xunit and Codebelt.Extensions.Xunit.App packages.
Replaced by BlockingManagedApplicationFixture and BlockingManagedWebApplicationFixture as part of the factory-based testing pattern overhaul. The new approach centralizes test lifecycle management through factory methods (ApplicationTestFactory and WebApplicationTestFactory) rather than inheritance-based fixtures.
Add ApplicationTestFactory static factory method for creating IHostTest instances from Program.cs entry points. Implement BlockingManagedApplicationFixture for non-blocking host fixture lifecycle management. Add internal ApplicationTest base class supporting host integration testing patterns with optional IApplicationFixture implementation override. Modify ApplicationHostFactory to remove automatic host.Start() call, allowing tests to control startup timing and resource initialization through the new factory pattern.
Add WebApplicationTestFactory static factory method for creating IWebApplicationTest instances from Program.cs entry points. Implement BlockingManagedWebApplicationFixture for non-blocking web fixture lifecycle management. Add internal WebApplicationTest base class supporting ASP.NET Core TestServer integration testing patterns with optional IWebApplicationFixture implementation override. These additions provide WebApplicationFactory-like testing capabilities aligned with the Generic Host factory pattern introduced for consistency across the entire .NET application stack.
Remove BootstrapperEntryPointTest.cs from both FunctionalTests projects and ManagedWebApplicationFixtureTest.cs from AspNetCore.FunctionalTests. These tests were specific to now-removed fixture implementations and entry point resolver patterns. New factory-based test coverage through ApplicationTestFactoryTest, WebApplicationTestFactoryTest, and updated bootstrapper-specific test classes provides comprehensive replacement coverage.
Refactor all bootstrapper and integration test classes across FunctionalTests projects to adopt the new ApplicationTestFactory and WebApplicationTestFactory static factory methods. Update test initialization to remove dependency on inheritance-based fixture management and instead use the BlockingManagedApplicationFixture and BlockingManagedWebApplicationFixture implementations provided through factory methods. Modify TestTest.cs in unit tests to reflect updated Test base class signatures. These changes align all integration tests with the new standardized factory-based testing pattern.
Add ApplicationTestFactoryTest to FunctionalTests providing full coverage of ApplicationTestFactory method signatures, fixture overrides, and host lifecycle management. Add WebApplicationTestFactoryTest to AspNetCore.FunctionalTests validating WebApplicationTestFactory behavior and TestServer integration. Add BlockingManagedWebApplicationFixtureTest covering the new blocking web fixture implementation. These tests ensure the new factory pattern works reliably across Generic Host and ASP.NET Core scenarios with all bootstrapper configuration variations.
Regenerate and update the official DocFX namespace pages for Codebelt.Extensions.Xunit.Hosting and Codebelt.Extensions.Xunit.Hosting.AspNetCore namespaces to document the new factory classes (ApplicationTestFactory, WebApplicationTestFactory), base classes (ApplicationTest, WebApplicationTest), and fixture implementations (BlockingManagedApplicationFixture, BlockingManagedWebApplicationFixture). Documentation pages serve as the authoritative source for public API conventions and are updated to reflect the factory-based testing pattern.
Add new 'Official Documentation' section to AGENTS.md establishing that public API conventions belong in .docfx/api/namespaces/ and should be treated as the authoritative documentation source for library behavior and naming vocabulary. Clarify that public APIs should have corresponding updates to the relevant namespace page when introducing or clarifying a convention. Emphasize that internal reasoning, exploratory notes, and agent discussion should be excluded from DocFX pages, which should contain only stable public guidance.
Update CHANGELOG.md [11.1.0] entry to emphasize the release brings WebApplicationFactory-like integration testing patterns to the entire .NET application stack through ApplicationHostFactory and ApplicationTest abstractions for Generic Host, and WebApplicationTest for ASP.NET Core. Reorganize Added section to highlight ApplicationTestFactory and WebApplicationTestFactory along with BlockingManagedApplicationFixture and BlockingManagedWebApplicationFixture. Update per-assembly package release notes for both Hosting and AspNetCore namespaces with version 11.1.0 feature summaries and availability information.
Update .gitignore to exclude build outputs, generated artifacts, and temporary files that are created during the build and test process but should not be committed to version control.
@gimlichael gimlichael self-assigned this Jun 5, 2026
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Jun 5, 2026

Greptile Summary

This PR introduces v11.1.0, expanding integration testing support to generic-host and console/worker applications (not just ASP.NET Core) by adding new factory and fixture abstractions, eight reference bootstrapper apps, and functional test suites for both the hosting and ASP.NET Core packages. CI is also extended with an optional macOS test matrix and a test_qualitygate aggregation gate.

  • New ApplicationHostFactory / ApplicationTestFactory and ASP.NET Core counterparts resolve an entry point's host using either a reflected CreateHostBuilder factory or a DiagnosticListener-based deferred builder adapted from the .NET runtime's own HostFactoryResolver.
  • BlockingManagedApplicationFixture<TEntryPoint> and BlockingManagedWebApplicationFixture<TEntryPoint> synchronously start the resolved host within the xUnit fixture lifecycle; eight bootstrapper reference apps validate the full matrix of hosting patterns (minimal/classic, console/worker/web).
  • CI pipeline adds a gated test_qualitygate job that aggregates Linux, Windows, and optional macOS results before allowing SonarCloud, Codecov, CodeQL, and NuGet deploy to proceed.

Confidence Score: 4/5

Safe to merge after fixing the undisposed host in one functional test; the core abstractions and CI changes are solid.

One functional test (ShouldHaveValidFixtureState_WhenApplicationIsBootstrapped) starts a full TestServer-backed host inside the test method body but never disposes it, leaving a background entry-point thread and in-memory server running for the lifetime of the test process. In parallel test runs this accumulates silently. The new factory and fixture code itself, the deferred host builder logic, and the CI quality-gate changes are well-structured and correct.

test/Codebelt.Extensions.Xunit.Hosting.AspNetCore.FunctionalTests/WebApplicationTestTest.cs — the ShouldHaveValidFixtureState_WhenApplicationIsBootstrapped test leaks an undisposed host.

Important Files Changed

Filename Overview
src/Codebelt.Extensions.Xunit.Hosting/ApplicationHostFactory.cs New factory that resolves a host builder from an entry-point assembly (via CreateHostBuilder reflection or a DiagnosticListener-based HostingListener), applies test-environment configuration, and returns a started IHost.
src/Codebelt.Extensions.Xunit.Hosting/Internal/ProgramHostFactoryResolver.cs Adapted from Microsoft's HostFactoryResolver; runs the entry-point in a background thread and intercepts the built IHost via a DiagnosticListener subscription — correct and isolated implementation.
src/Codebelt.Extensions.Xunit.Hosting/Internal/DeferredHostBuilder.cs Deferred IHostBuilder that accumulates configuration delegates and passes them into the real host builder intercepted from the entry point; DeferredHost.StartAsync correctly awaits the entry-point completion signal.
src/Codebelt.Extensions.Xunit.Hosting/BlockingManagedApplicationFixture.cs New fixture that synchronously starts a generic-host application from an entry-point assembly; uses #if NETSTANDARD2_0 guards correctly for null-check compat.
src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/BlockingManagedWebApplicationFixture.cs ASP.NET Core counterpart of BlockingManagedApplicationFixture; missing the #if NETSTANDARD2_0 guard around ArgumentNullException.ThrowIfNull, but safe if the AspNetCore package does not target netstandard2.0.
src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/WebApplicationTestFactory.cs Static factory for ASP.NET Core entry-point tests; RunAsync was flagged in a prior review for leaking the host created by Create<TEntryPoint> (only the HttpClient is disposed, not the IHostTest).
src/Codebelt.Extensions.Xunit.Hosting/ApplicationTestFactory.cs Thin static factory delegating to Internal.ApplicationTest; correctly creates and returns a disposable IHostTest.
src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/Internal/WebApplicationHostFactory.cs Internal helper that delegates to ApplicationHostFactory.Create with TestServer added to the web host; passes stopApplication: false so the host keeps running.
test/Codebelt.Extensions.Xunit.Hosting.AspNetCore.FunctionalTests/WebApplicationTestTest.cs ShouldHaveValidFixtureState_WhenApplicationIsBootstrapped starts a full TestServer host but never disposes it; Test_VerifyAbstractions violates the repository's test-method naming convention.
test/Codebelt.Extensions.Xunit.Hosting.FunctionalTests/ApplicationTestFactoryTest.cs Comprehensive factory tests; all fixtures are properly disposed via using; async dispose path is covered.
.github/workflows/ci-pipeline.yml Adds optional macOS test matrix behind a workflow-dispatch boolean, introduces a test_qualitygate aggregation job, and gates downstream analysis/deploy jobs on the quality gate result — logic is correct.

Sequence Diagram

sequenceDiagram
    participant Test as ApplicationTest / WebApplicationTest
    participant Fixture as BlockingManagedApplicationFixture
    participant Factory as ApplicationHostFactory
    participant Resolver as ProgramHostFactoryResolver
    participant DHB as DeferredHostBuilder
    participant EP as EntryPoint thread

    Test->>Fixture: ConfigureHost(this)
    Fixture->>Factory: "Create<TEntryPoint>(configureHost)"
    Factory->>Resolver: ResolveHostBuilderFactory(assembly)
    alt CreateHostBuilder method found
        Resolver-->>Factory: "Func<string[], IHostBuilder>"
        Factory->>Factory: BuildHost(hostBuilder, configureHost)
    else Top-level / minimal hosting
        Factory->>Resolver: ResolveHostFactory(assembly, stopApp, ...)
        Resolver-->>Factory: HostingListener factory
        Factory->>DHB: new DeferredHostBuilder()
        Factory->>DHB: SetHostFactory(hostFactory)
        DHB->>DHB: Build() calls _hostFactory(args)
        DHB->>EP: Start background thread (InvokeEntryPoint)
        EP-->>DHB: "HostBuilding diagnostic -> ConfigureHostBuilder"
        EP-->>DHB: "HostBuilt diagnostic -> _host.TrySetResult"
        DHB-->>Factory: IHost (DeferredHost)
        Factory->>Factory: BuildHost(deferredHostBuilder, configureHost)
    end
    Factory-->>Fixture: IHost
    Fixture->>Fixture: host.Start()
    Fixture-->>Test: Host, Configuration, Environment set
Loading
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
test/Codebelt.Extensions.Xunit.Hosting.AspNetCore.FunctionalTests/WebApplicationTestTest.cs:80-92
**Undisposed host leaks TestServer and background entry-point thread**

The test creates a `BlockingManagedWebApplicationFixture<ModernProgram>`, calls `ConfigureHost`, and thereby starts a fully running host (TestServer + background thread executing `ModernProgram`'s entry point). Neither `fixture` nor the host it owns is disposed before the method returns. In a parallel test suite the leaked background threads accumulate for the lifetime of the test runner process. The fix is to wrap `fixture` in a `using` block — since `BlockingManagedWebApplicationFixture<TEntryPoint>` inherits from `HostFixture`, which implements `IDisposable`, a `using` statement is sufficient.

### Issue 2 of 2
test/Codebelt.Extensions.Xunit.Hosting.AspNetCore.FunctionalTests/WebApplicationTestTest.cs:81
**`Test_VerifyAbstractions` does not follow the repository's test-method naming convention**

AGENTS.md requires all test method names to use the `Should{ExpectedResult}_When{Condition}` pattern. This name starts with `Test_` and has no `Should` prefix or `When` clause, which is inconsistent with every other test in this file and the broader project.

```suggestion
    public void ShouldImplementExpectedAbstractions_WhenClassIsInstantiated()
```

Reviews (3): Last reviewed commit: "✅ Add async disposal test for Applicatio..." | Re-trigger Greptile

Comment on lines +35 to +39
public static async Task<HttpResponseMessage> RunAsync<TEntryPoint>(Action<IWebHostBuilder> webHostSetup = null, Func<HttpClient, Task<HttpResponseMessage>> responseFactory = null, IWebApplicationFixture<TEntryPoint> hostFixture = null) where TEntryPoint : class
{
using var client = Create<TEntryPoint>(webHostSetup, hostFixture).Host.GetTestClient();
return await client.ToHttpResponseMessageAsync(responseFactory).ConfigureAwait(false);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 The IHostTest returned by Create<TEntryPoint>(...) is immediately dereferenced — only .Host.GetTestClient() is captured. The WebApplicationTest, its BlockingManagedWebApplicationFixture, and the underlying TestServer/IHost are never disposed. Every call to RunAsync leaks a running ASP.NET Core host and its background entry-point thread until the process terminates.

Suggested change
public static async Task<HttpResponseMessage> RunAsync<TEntryPoint>(Action<IWebHostBuilder> webHostSetup = null, Func<HttpClient, Task<HttpResponseMessage>> responseFactory = null, IWebApplicationFixture<TEntryPoint> hostFixture = null) where TEntryPoint : class
{
using var client = Create<TEntryPoint>(webHostSetup, hostFixture).Host.GetTestClient();
return await client.ToHttpResponseMessageAsync(responseFactory).ConfigureAwait(false);
}
public static async Task<HttpResponseMessage> RunAsync<TEntryPoint>(Action<IWebHostBuilder> webHostSetup = null, Func<HttpClient, Task<HttpResponseMessage>> responseFactory = null, IWebApplicationFixture<TEntryPoint> hostFixture = null) where TEntryPoint : class
{
using var hostTest = Create<TEntryPoint>(webHostSetup, hostFixture);
using var client = hostTest.Host.GetTestClient();
return await client.ToHttpResponseMessageAsync(responseFactory).ConfigureAwait(false);
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/Codebelt.Extensions.Xunit.Hosting.AspNetCore/WebApplicationTestFactory.cs
Line: 35-39

Comment:
The `IHostTest` returned by `Create<TEntryPoint>(...)` is immediately dereferenced — only `.Host.GetTestClient()` is captured. The `WebApplicationTest`, its `BlockingManagedWebApplicationFixture`, and the underlying `TestServer`/`IHost` are never disposed. Every call to `RunAsync` leaks a running ASP.NET Core host and its background entry-point thread until the process terminates.

```suggestion
    public static async Task<HttpResponseMessage> RunAsync<TEntryPoint>(Action<IWebHostBuilder> webHostSetup = null, Func<HttpClient, Task<HttpResponseMessage>> responseFactory = null, IWebApplicationFixture<TEntryPoint> hostFixture = null) where TEntryPoint : class
    {
        using var hostTest = Create<TEntryPoint>(webHostSetup, hostFixture);
        using var client = hostTest.Host.GetTestClient();
        return await client.ToHttpResponseMessageAsync(responseFactory).ConfigureAwait(false);
    }
```

How can I resolve this? If you propose a fix, please make it concise.

Add optional stopApplication parameter to ApplicationHostFactory.Create overload, allowing callers to control whether the entry point is stopped after the host is built. Updates ProgramHostFactoryResolver exception handling and WebApplicationHostFactory parameter passing to support this new configuration option.
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 5, 2026

Codecov Report

❌ Patch coverage is 86.67883% with 73 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.45%. Comparing base (8208483) to head (c75ac31).

Files with missing lines Patch % Lines
...nit.Hosting/Internal/ProgramHostFactoryResolver.cs 77.67% 24 Missing and 1 partial ⚠️
...ions.Xunit.Hosting/Internal/DeferredHostBuilder.cs 83.72% 14 Missing ⚠️
...s.Xunit.Hosting.BootstrapperConsole.App/Startup.cs 54.54% 5 Missing ⚠️
....Hosting.BootstrapperMinimalConsole.App/Program.cs 44.44% 5 Missing ⚠️
....Hosting.AspNetCore/Internal/WebApplicationTest.cs 82.14% 4 Missing and 1 partial ⚠️
...imalWorker.App/BootstrapperMinimalWorkerService.cs 0.00% 3 Missing ⚠️
...ootstrapperWorker.App/BootstrapperWorkerService.cs 0.00% 3 Missing ⚠️
...nsions.Xunit.Hosting.ClassicProgram.App/Program.cs 80.00% 3 Missing ⚠️
...lt.Extensions.Xunit.Hosting.Program.App/Program.cs 82.35% 2 Missing and 1 partial ⚠️
...t.Hosting.BootstrapperMinimalWorker.App/Program.cs 71.42% 2 Missing ⚠️
... and 5 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #63      +/-   ##
==========================================
- Coverage   95.68%   92.45%   -3.23%     
==========================================
  Files          46       82      +36     
  Lines         950     1498     +548     
  Branches      115      169      +54     
==========================================
+ Hits          909     1385     +476     
- Misses         32       99      +67     
- Partials        9       14       +5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

gimlichael and others added 3 commits June 5, 2026 05:28
Simplifies marker classes by removing the unused static state property that was only used for testing purposes.
Verifies that ApplicationTestFactory properly disposes the fixture when the application is disposed asynchronously.
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Jun 5, 2026

Want your agent to iterate on Greptile's feedback? Try greploops.

Comment on lines +80 to +92
[Fact]
public void Test_VerifyAbstractions()
{
Assert.IsAssignableFrom<IHostTest>(this);
Assert.IsAssignableFrom<IConfigurationTest>(this);
Assert.IsAssignableFrom<IEnvironmentTest>(this);
Assert.IsAssignableFrom<ITest>(this);
Assert.IsAssignableFrom<IDisposable>(this);
Assert.IsAssignableFrom<IAsyncDisposable>(this);
}

protected override void ConfigureWebHost(IWebHostBuilder builder)
{
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Undisposed host leaks TestServer and background entry-point thread

The test creates a BlockingManagedWebApplicationFixture<ModernProgram>, calls ConfigureHost, and thereby starts a fully running host (TestServer + background thread executing ModernProgram's entry point). Neither fixture nor the host it owns is disposed before the method returns. In a parallel test suite the leaked background threads accumulate for the lifetime of the test runner process. The fix is to wrap fixture in a using block — since BlockingManagedWebApplicationFixture<TEntryPoint> inherits from HostFixture, which implements IDisposable, a using statement is sufficient.

Prompt To Fix With AI
This is a comment left during a code review.
Path: test/Codebelt.Extensions.Xunit.Hosting.AspNetCore.FunctionalTests/WebApplicationTestTest.cs
Line: 80-92

Comment:
**Undisposed host leaks TestServer and background entry-point thread**

The test creates a `BlockingManagedWebApplicationFixture<ModernProgram>`, calls `ConfigureHost`, and thereby starts a fully running host (TestServer + background thread executing `ModernProgram`'s entry point). Neither `fixture` nor the host it owns is disposed before the method returns. In a parallel test suite the leaked background threads accumulate for the lifetime of the test runner process. The fix is to wrap `fixture` in a `using` block — since `BlockingManagedWebApplicationFixture<TEntryPoint>` inherits from `HostFixture`, which implements `IDisposable`, a `using` statement is sufficient.

How can I resolve this? If you propose a fix, please make it concise.

@gimlichael gimlichael merged commit 9070ae8 into main Jun 5, 2026
20 of 22 checks passed
@gimlichael gimlichael deleted the v11.1.0/support-for-integration-testing branch June 5, 2026 04:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants