Docker コンテナ上に DB(PostgreSQL)を構築し、MSTest から単体テストを実行する方法をまとめます。
参考:
必要な要素
- MSTest のコードから Docker コンテナ(PostgreSQL)を作成
- マイグレーションを行い、テストコードから参照できる
MSTest から Docker コンテナ(PostgreSQL)を作成
TestcontainersとTestcontainers.PostgreSqlの Nuget パッケージを使用します。このパッケージを使用するとコンテナを作成することが可能です。
以下のコードで PostgreSQL コンテナを作成できます。
public static PostgreSqlContainer Postgres { get; private set; } = new PostgreSqlBuilder()
.WithImage("postgres:15-alpine")
.WithUsername("postgres")
.WithPassword("postgres")
.WithDatabase("testdb")
.Build();
マイグレーションとテストコードからの参照
MSTest プロジェクト内に以下のテストコードを追加します。
[TestClass]
public class AssemblyHooks
{
public static PostgreSqlContainer Postgres { get; private set; } = new PostgreSqlBuilder()
.WithImage("postgres:15-alpine")
.WithUsername("postgres")
.WithPassword("postgres")
.WithDatabase("testdb")
.Build();
public static string ConnectionString { get; private set; } = string.Empty;
[AssemblyInitialize]
public static async Task AssemblyInit(TestContext context)
{
await Postgres.StartAsync();
ConnectionString = Postgres.GetConnectionString();
var options = new DbContextOptionsBuilder<TempDbContext>()
.UseNpgsql(ConnectionString)
.Options;
using var db = new TempDbContext(options);
db.Database.Migrate();
db.Users.Add(new Models.User { Name = "Bob" });
await db.SaveChangesAsync();
}
[AssemblyCleanup]
public static async Task AssemblyCleanup()
{
await Postgres.DisposeAsync();
}
}
AssemblyInitializeとAssemblyCleanupのライフサイクルで DB の構築・初期データ投入・コンテナ削除を行います。各テストクラスが動く前とテストが完全に終了したタイミングでそれぞれ一度ずつ実行されます。
テストコードから DB に接続する
外部から参照できるConnectionStringを使用して DB に接続します。
var connectionString = AssemblyHooks.ConnectionString;
var options = new DbContextOptionsBuilder<TempDbContext>()
.UseNpgsql(connectionString)
.Options;
using var db = new TempDbContext(options);
まとめ
- Testcontainers を使うことで、MSTest から簡単に DB コンテナを起動できる
- AssemblyInitialize/AssemblyCleanup で DB のセットアップ・削除を自動化
- テストごとに DB を使いまわせるため、実際の環境に近い形でテスト可能
この記事が皆様のコーディングライフの助けになれば幸いです。
参考