上手くいくかは未検証!
データは、if exists drop database + import bacpac で考える。
※楽だから
Local DB 前提で書いたけど、Local DB じゃなくても問題無さそう。
テスト側ではトランザクション制御出来ない前提。
Web App とかで HTTP 跨ぐようなイメージ。
メソッドのテストなら、テストで呼び出すときに、
TransactionScope で囲って Complete 呼ばないとかでトランザクション 制御出来るケースが多そう。
- テストの種類
- DB 使わない
- DB 使う : read only (テストデータ投入もしない。bacpac だけで完結)
- DB 使う : read write (bacpac + 個別のテストデータ or テスト中に書き換え)
xUnit.NET は何もしてないと全テストパラレルで動くはず。
- DB 使わない (パラで問題なし)
- DB 使う (read only) (以下の内容に気を付ければパラで問題なし)
- DB 使う (read write) (パラでは問題あり)
- write があるので、「他のテストと同じ database を参照している」とタイミングで問題が出そう。
- read write がある テスト は、他のテストと別の database (database 名 / 接続文字列 Initial Catalog)に変えて、bacpac を import して動かしたら他のテストとパラでも問題無い。
- テスト対象のアプリは、HostBuilder なりなんなりで、接続文字列を差し替え出来る前提
- 同じ database 名で動作するテストは パラ だと困る。
- XUnit.Collection でグルーピング。Collection 名を database 名したら良さげ。
- read write がある テスト は、他のテストと別の database (database 名 / 接続文字列 Initial Catalog)に変えて、bacpac を import して動かしたら他のテストとパラでも問題無い。
- write があるので、「他のテストと同じ database を参照している」とタイミングで問題が出そう。
まとめ
- module initializer で read only で使う共通の DB を import する
- write があるテストは、それぞれ XUnit.Collection + Database 名を変更して、別の Database として import して、Collection 単位でパラレルに動く
参考資料
NuGet Gallery | xunit 2.4.1
NuGet Gallery | Microsoft.SqlServer.DacFx 150.5164.1
Running Tests in Parallel > xUnit.net
Shared Context between Tests > xUnit.net
Module initializers - C# 9.0 specification proposals | Microsoft Docs
DROP DATABASE (Transact-SQL) - SQL Server | Microsoft Docs
ASP.NET Core MVC アプリのテスト | Microsoft Docs
DACExtensions/SqlTestDb.cs at 6ed437b23fdc0fb959394afd7d5aba99f64022f8 · microsoft/DACExtensions · GitHub