Project Naming Conventions
Project Naming Conventions
Section titled “Project Naming Conventions”The SDK applies several conventions automatically based on the .csproj filename and
NamespacePrefix.
Defaults (no extra configuration)
Section titled “Defaults (no extra configuration)”RootNamespace is always derived from $(NamespacePrefix).$(ProjectName) and is the canonical
default public name. By default (EnableAssemblyNameGeneration=true), AssemblyName and PackageId
both follow the fully evaluated RootNamespace. Test projects retain their detected suffix so test
assemblies stay distinct from the source assembly. Set EnableAssemblyNameGeneration=false (before the
SDK import) to opt out and use standard .NET behaviour (the .csproj filename):
.csproj filename |
AssemblyName / PackageId |
RootNamespace |
Detected as |
|---|---|---|---|
Api.csproj |
Acme.Api |
Acme.Api |
Source project |
Api.UnitTests.csproj |
Acme.Api.UnitTests |
Acme.Api |
IsTestProject=true, TestingType=Unit |
Api.IntegrationTests.csproj |
Acme.Api.IntegrationTests |
Acme.Api |
IsTestProject=true, TestingType=Integration |
SharedTestingFramework.csproj |
Acme.SharedTestingFramework |
Acme |
IsSharedTestingProject=true |
Note:
InternalsVisibleTofollows$(AssemblyName)— so forApi.csprojthe SDK generatesAcme.Api.UnitTests,Acme.Api.IntegrationTests, etc.
Use short .csproj names — the SDK handles the prefixing:
✅ Api.csproj → short name, SDK resolves the rest❌ Acme.Api.csproj → redundant prefix, avoidA build-time check (PurviewProjectFileNameMismatch) enforces that the .csproj filename matches its
parent directory name, preventing inconsistent naming. Set DisableProjectFileNamingConventionCheck=true
to opt out.
Recommended structure: src/ + tests/
Section titled “Recommended structure: src/ + tests/”For larger repos, separate source and test projects into src/ and tests/ folders:
MyRepo/├── Directory.Build.props ← NamespacePrefix=Acme├── Directory.Build.targets├── Directory.Packages.props├── global.json├── src/│ ├── Api/│ │ └── Api.csproj│ ├── Core/│ │ └── Core.csproj│ └── SourceGenerator/│ └── SourceGenerator.csproj├── tests/│ ├── Api.UnitTests/│ │ └── Api.UnitTests.csproj → IsTestProject=true, TestingType=Unit│ ├── Api.IntegrationTests/│ │ └── Api.IntegrationTests.csproj│ └── SharedTestingFramework/│ └── SharedTestingFramework.csproj → IsSharedTestingProject=true└── package.jsonFlat structure: everything together
Section titled “Flat structure: everything together”For smaller repos, source and test projects can live side-by-side:
MyRepo/├── Directory.Build.props├── Directory.Build.targets├── Directory.Packages.props├── global.json├── Api/│ └── Api.csproj├── Api.UnitTests/│ └── Api.UnitTests.csproj├── Core/│ └── Core.csproj├── Core.IntegrationTests/│ └── Core.IntegrationTests.csproj└── package.jsonBoth layouts work identically — the SDK detects test projects by name suffix, not folder location.
Quick reference
Section titled “Quick reference”# Create a source projectmkdir src/Api && cd src/Apidotnet new classlib -n Api
# Create its unit testsmkdir ../../tests/Api.UnitTests && cd ../../tests/Api.UnitTestsdotnet new classlib -n Api.UnitTests # SDK wires TUnit automatically
# Or flat:mkdir Api.UnitTests && cd Api.UnitTestsdotnet new classlib -n Api.UnitTestsTest project naming conventions
Section titled “Test project naming conventions”Test projects are automatically detected by their suffix. Supported patterns:
MyProject.UnitTests → IsTestProject=true, TestingType=UnitMyProject.IntegrationTests→ IsTestProject=true, TestingType=IntegrationMyProject.E2ETests → IsTestProject=true, TestingType=E2EAny suffix from the full list is recognised: Unit, Integration, E2E, EndToEnd, Acceptance,
Functional, Performance, Load, Smoke, Stress, Regression, Security, Chaos, Scenario,
System, Threat, BlackBox, WhiteBox, Accessibility, Interactive, Environment,
Architecture, Contract.
Shared testing projects
Section titled “Shared testing projects”Projects named SharedTestingFramework, SharedTestingInfrastructure, SharedTestingInfra,
SharedTestingUtilities, SharedTestingUtils, SharedTestingLibrary, SharedTestingLib, or
SharedTestingHelpers are treated as shared testing helpers — they get test package references but
not the test runner or coverage settings.
See Project Type Detection for how these names are classified, and Assembly Name Generation for how the identities are derived.