Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

**Migrating?** See the **[Migration Guides](https://tunit.dev/docs/migration/xunit)**

**Learn more:** **[Data-Driven Testing](https://tunit.dev/docs/test-authoring/arguments)**, **[Test Dependencies](https://tunit.dev/docs/test-authoring/depends-on)**, **[Parallelism Control](https://tunit.dev/docs/parallelism/not-in-parallel)**
**Learn more:** **[Data-Driven Testing](https://tunit.dev/docs/writing-tests/arguments)**, **[Test Dependencies](https://tunit.dev/docs/writing-tests/ordering)**, **[Parallelism Control](https://tunit.dev/docs/execution/parallelism)**

</div>

Expand Down
84 changes: 2 additions & 82 deletions docs/docs/examples/complex-test-infrastructure.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,89 +202,9 @@ public class InMemoryPostgreSqlDatabase : IAsyncInitializer, IAsyncDisposable

### EF Core Code First with Per-Test Schema Isolation

For EF Core Code First applications, use per-test PostgreSQL schemas instead of per-test table names. This avoids fighting EF Core's table naming conventions:
For EF Core Code First applications, use per-test PostgreSQL schemas instead of per-test table names. This avoids fighting EF Core's table naming conventions and provides complete isolation using `GetIsolatedName("schema")`.

```csharp
// DbContext with dynamic schema support — reads schema from IConfiguration when
// resolved via DI, falls back to "public" when constructed standalone.
public class TodoDbContext : DbContext
{
public string SchemaName { get; set; }
public DbSet<Todo> Todos => Set<Todo>();

public TodoDbContext(DbContextOptions<TodoDbContext> options, IConfiguration? config = null)
: base(options)
{
SchemaName = config?["Database:Schema"] ?? "public";
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema(SchemaName);
// ... entity configuration
}
}

// IModelCacheKeyFactory ensures different schemas get different model caches
public class SchemaModelCacheKeyFactory : IModelCacheKeyFactory
{
public object Create(DbContext context, bool designTime)
=> context is TodoDbContext tc
? (context.GetType(), tc.SchemaName, designTime)
: (object)(context.GetType(), designTime);
}

// Test base: creates schema + tables in SetupAsync, drops in cleanup
public abstract class EfCoreTodoTestBase
: WebApplicationTest<EfCoreWebApplicationFactory, Program>
{
[ClassDataSource<InMemoryPostgreSqlDatabase>(Shared = SharedType.PerTestSession)]
public InMemoryPostgreSqlDatabase PostgreSql { get; init; } = null!;

protected string SchemaName { get; private set; } = null!;

protected override async Task SetupAsync()
{
SchemaName = GetIsolatedName("schema"); // e.g. "Test_42_schema"

// Create schema, then let EF Core create tables
await using var conn = new NpgsqlConnection(
PostgreSql.Container.GetConnectionString());
await conn.OpenAsync();
await using var cmd = conn.CreateCommand();
cmd.CommandText = $"CREATE SCHEMA IF NOT EXISTS \"{SchemaName}\"";
await cmd.ExecuteNonQueryAsync();

var options = new DbContextOptionsBuilder<TodoDbContext>()
.UseNpgsql(PostgreSql.Container.GetConnectionString())
.ReplaceService<IModelCacheKeyFactory, SchemaModelCacheKeyFactory>()
.Options;
await using var db = new TodoDbContext(options) { SchemaName = SchemaName };
await db.Database.EnsureCreatedAsync();
}

protected override void ConfigureTestConfiguration(IConfigurationBuilder config)
{
config.AddInMemoryCollection(new Dictionary<string, string?>
{
{ "Database:Schema", SchemaName }
});
}

[After(Test)]
public async Task CleanupSchema()
{
await using var conn = new NpgsqlConnection(
PostgreSql.Container.GetConnectionString());
await conn.OpenAsync();
await using var cmd = conn.CreateCommand();
cmd.CommandText = $"DROP SCHEMA IF EXISTS \"{SchemaName}\" CASCADE";
await cmd.ExecuteNonQueryAsync();
}
}
```

See the full working example in `TUnit.Example.Asp.Net.TestProject/EfCore/`.
See the full pattern with `IModelCacheKeyFactory`, `EnsureCreatedAsync()`, and schema cleanup in the [ASP.NET Core Integration Testing](aspnet.md#per-test-schema-isolation-with-ef-core) guide, or the working example in `TUnit.Example.Asp.Net.TestProject/EfCore/`.

## Comparison with Other Frameworks

Expand Down
6 changes: 3 additions & 3 deletions docs/docs/examples/filebased-csharp.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ To use TUnit with a file-based C# application, you can follow these steps:
2. **Add TUnit to your project**: You can add TUnit as a package reference in your file. At the top of your `Program.cs`, add the following line:

```csharp
#:package TUnit@0.*
#:package TUnit@1.*
```

- Alternatively, you can specify a specific version:

```csharp
#:package TUnit@0.25.0
#:package TUnit@1.6.0
```

- You can also use msbuild props files to include TUnit. By creating a `Directory.build.props` file in the same directory as the csharp file.
Expand All @@ -32,7 +32,7 @@ To use TUnit with a file-based C# application, you can follow these steps:
3. **Write your tests**: You can write your tests in the same way you would in a regular C# project. For example:

```csharp
#:package TUnit@0.*
#:package TUnit@1.*

using TUnit;
public class Tests
Expand Down
6 changes: 3 additions & 3 deletions docs/docs/examples/fsharp-interactive.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ format. To use TUnit with F# Interactive, follow these steps:
Alternatively, you can specify a specific version:

```fsharp
#r "nuget: TUnit, 0.20.16"
#r "nuget: TUnit, 1.6.0"
```

2. **Write your tests**: You can write your tests in the same way you would in a regular F# project. For example:

```fsharp
#r "nuget: TUnit, 0.20.16"
#r "nuget: TUnit.Assertions.Fsharp, 0.20.16"
#r "nuget: TUnit"
#r "nuget: TUnit.Assertions.Fsharp"

open System
open TUnit
Expand Down
3 changes: 1 addition & 2 deletions docs/docs/getting-started/running-your-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,7 @@ To continue your journey with TUnit, explore these topics:

**Common Tasks:**
- **[Mocking](../writing-tests/mocking/index.md)** - Use mocks and fakes in your tests
- **[Best Practices](../guides/best-practices.md)** - Write maintainable, reliable tests
- **[Cookbook](../guides/cookbook.md)** - Common testing patterns and recipes
- **[Tips & Pitfalls](../guides/best-practices.md)** - TUnit-specific tips to avoid common mistakes

**Advanced Features:**
- **[Parallelism](../execution/parallelism.md)** - Control how tests run in parallel
Expand Down
Loading
Loading