# What Is the Test Directory in ASP.NET Core? Repository Structure and Architecture

> Discover the role of the test directory in aspnetcore. Explore unit, functional, and integration tests that ensure subsystem integrity and stability.

- Repository: [.NET Platform/aspnetcore](https://github.com/dotnet/aspnetcore)
- Tags: architecture
- Published: 2026-08-01

---

**The `test` directories in the ASP.NET Core repository are distributed component-level folders containing unit, functional, and integration tests that validate each subsystem using xUnit, TestServer, and shared infrastructure from `src/Testing/`.**

The ASP.NET Core repository (`dotnet/aspnetcore`) organizes its massive codebase into modular components under `src/`, with each module containing its own `test/` subdirectory. These distributed test folders serve as the framework's quality gate, housing automated validations that run in CI pipelines to prevent regressions and document API behavior for millions of developers.

## Distributed Test Architecture

Unlike monolithic repositories that centralize tests in a single top-level folder, ASP.NET Core employs a **co-located test strategy**. Every component under `src/`—such as Hosting, Routing, SignalR, and Components—maintains its own `test/` directory adjacent to its source code.

This architectural decision ensures that:

- **Tests evolve with their components**—developers modify tests in the same PR as feature changes.
- **Dependencies remain isolated**—test projects reference only the specific APIs they validate, preventing cross-component pollution.
- **Build performance improves**—the build system can filter tests by component rather than executing the entire suite.

For example, the Hosting layer's functional tests reside at `src/Hosting/test/FunctionalTests/Microsoft.AspNetCore.Hosting.FunctionalTests.csproj`, while Routing tests exist at `src/Http/Routing/test/FunctionalTests/Microsoft.AspNetCore.Routing.FunctionalTests.csproj`.

## Types of Tests in ASP.NET Core

Each `test/` directory organizes validation into distinct categories based on scope and execution environment.

### Unit Tests

Unit tests validate individual classes and methods in isolation using **xUnit** as the primary framework and **Moq** for mocking. These tests execute quickly and target specific implementation details without spinning up a web server. They typically appear in `test/UnitTests/` subdirectories within component folders.

### Functional and Integration Tests

Functional tests exercise the full HTTP pipeline using `TestServer` or `WebApplicationFactory<T>`. These integration suites spin up an in-memory host, configure middleware pipelines, and make actual HTTP requests to verify end-to-end behavior. The Hosting component's functional tests demonstrate this pattern in `src/Hosting/test/FunctionalTests/`, where tests create real `WebHost` instances to validate startup logic and configuration.

### Performance Benchmarks

Performance tests utilize **BenchmarkDotNet** to measure throughput, memory allocations, and latency across releases. Located in `test/Benchmarks/` folders, these tests detect regressions in critical paths like routing table construction or SignalR message serialization.

## Shared Testing Infrastructure

Despite the distributed layout, ASP.NET Core centralizes common test utilities in **`src/Testing/`** and **`src/Testing/internal/`**. This shared infrastructure prevents duplication across hundreds of test projects.

Key shared resources include:

- **`TestServer`**—An in-memory HTTP server implementation that allows tests to make requests against a fully configured pipeline without network overhead. Defined in the Hosting abstractions and utilized across components.
- **Test certificates**—Shared cryptographic assets like `src/SignalR/common/Shared/testCert.pfx` enable HTTPS-related tests without requiring system-level certificate installation.
- **Logging and assertion helpers**—Common utilities for capturing log output and asserting on structured logging events.

Test projects reference these utilities via project references, ensuring consistent behavior across unit and integration suites.

## CI Integration and Running Tests

The `test/` directories integrate directly into **Azure Pipelines** workflows. During CI builds, the pipeline executes `dotnet test` against all `*.Tests.csproj` and `*FunctionalTests.csproj` files discovered under `src/**/test/`. Failed tests block PR merges, enforcing the repository's quality standards.

To execute tests locally, developers use component-specific commands rather than running the entire suite:

```bash

# Run all Hosting functional tests

dotnet test src/Hosting/test/FunctionalTests/Microsoft.AspNetCore.Hosting.FunctionalTests.csproj

# Run Routing functional tests

dotnet test src/Http/Routing/test/FunctionalTests/Microsoft.AspNetCore.Routing.FunctionalTests.csproj

```

For end-to-end validation of UI components like Blazor:

```bash
dotnet test src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj

```

## TestServer Usage Example

The following pattern demonstrates how functional tests leverage the shared `TestServer` infrastructure to validate HTTP endpoints:

```csharp
using Microsoft.AspNetCore.TestHost;
using Microsoft.AspNetCore.Hosting;
using System.Net.Http;
using Xunit;

public class EndpointIntegrationTests
{
    [Fact]
    public async Task Get_Endpoint_ReturnsSuccessStatusCode()
    {
        // Arrange
        var builder = new WebHostBuilder()
            .UseStartup<TestStartup>();
        var server = new TestServer(builder);
        var client = server.CreateClient();

        // Act
        var response = await client.GetAsync("/api/values");

        // Assert
        response.EnsureSuccessStatusCode();
    }
}

```

This pattern appears throughout the repository's functional test projects, providing a lightweight yet realistic HTTP testing environment.

## Summary

- **No single root test directory exists**—tests are distributed across `src/<Component>/test/` folders following a co-located architecture.
- **Three test categories** dominate: Unit tests (xUnit/Moq), Functional tests (TestServer/WebHost), and Performance tests (BenchmarkDotNet).
- **Shared infrastructure** in `src/Testing/` provides TestServer, certificates, and logging utilities used by hundreds of test projects.
- **CI integration** automatically executes all test projects under `src/**/test/`, blocking PRs on failure.
- **Local execution** uses `dotnet test` against specific `.csproj` files like `Microsoft.AspNetCore.Hosting.FunctionalTests.csproj`.

## Frequently Asked Questions

### Does ASP.NET Core have a single test directory at the repository root?

No. The repository uses a distributed model where each component under `src/` contains its own `test/` subdirectory. For example, Hosting tests live in `src/Hosting/test/` while SignalR tests reside in `src/SignalR/test/`. This co-location ensures tests evolve alongside their corresponding source code.

### What testing frameworks does ASP.NET Core use?

The repository primarily uses **xUnit** for test discovery and execution, **Moq** for mocking dependencies, and **BenchmarkDotNet** for performance measurements. Integration tests rely on **TestServer** (from `Microsoft.AspNetCore.TestHost`) to host the application pipeline in memory without network overhead.

### How do I run tests for a specific ASP.NET Core component?

Navigate to the component's test directory and execute `dotnet test` against the specific project file. For example, to run the Hosting functional tests, execute `dotnet test src/Hosting/test/FunctionalTests/Microsoft.AspNetCore.Hosting.FunctionalTests.csproj`. This targeted approach avoids the time-consuming process of running the entire repository's test suite.

### What is TestServer and where is it defined?

**TestServer** is an in-memory HTTP server implementation that simulates the ASP.NET Core request pipeline for integration testing. It is defined in the Hosting abstractions layer and referenced by functional test projects throughout the repository. Tests use `new TestServer(WebHostBuilder)` to create a server instance, then call `CreateClient()` to obtain an `HttpClient` that dispatches requests directly to the in-memory pipeline.