用例:我們有一個很大的數據庫(約200個表),用於大型(傳統)系統。它以數據庫優先方式實現,其中一個edmx文件定義了整個數據庫。我們正在使用XUnit和Effort進行自動測試。問題在於這些測試非常緩慢。即使測試覆蓋範圍與我們希望的範圍相去甚遠,我們當前的測試套件也需要大約7-8分鐘的時間來運行。
我注意到,如果我創建edmx文件的較小子集,則通過刪除一些不需要的表,測試運行會更快。
我正在尋找一種解決方案,在該解決方案中,對於特定測試或一組測試,我們可以通過某種方式使Effort僅創建所需表的子集(我認為在許多情況下,我們只需要一個表)。
目前,我們正在建立這樣的連接:
connection = EntityConnectionFactory.CreateTransient("metadata=res://entities.csdl|res://entities.ssdl|res://entities.msl");
有什麼辦法(例如,通過在運行時中運行XML轉換)使Effort僅創建我們定義的表子集所需的數據結構?
免責聲明 :我是項目Entity Framework Effort的所有者
我們的庫具有允許創建還原點並回滾到它的功能。
因此,使用此技巧,您可以在創建所有表時僅使用CreateRestorePoint()
一次,然後對於每個測試,均使用RollbackToRestorePoint
啟動它們。 (還有其他幾種方法可以使它起作用,但是我想您明白了)
毫無疑問,這將使您的測試運行更快,因為不必每次都創建表。
這是一個例子:
var conn = Effort.DbConnectionFactory.CreateTransient();
using (var context = new EntityContext(conn))
{
context.EntitySimples.Add(new EntitySimple { ColumnInt = 1 });
context.EntitySimples.Add(new EntitySimple { ColumnInt = 2 });
context.EntitySimples.Add(new EntitySimple { ColumnInt = 3 });
context.SaveChanges();
}
// Create a RestorePoint that will save all current entities in the "Database"
conn.CreateRestorePoint();
// Make any change
using (var context = new EntityContext(conn))
{
context.EntitySimples.RemoveRange(context.EntitySimples);
context.SaveChanges();
}
// Rollback to the restore point to make more tests
conn.RollbackToRestorePoint();
分開進行單元測試和集成測試。對於集成測試,可以使用數據庫並在更高的環境上運行(以節省時間),但是在本地環境上,可以使用Faker \ Bogus和NBuilder生成大量數據進行單元測試。
https://dzone.com/articles/using-faker-and-nbuilder-to-generate-massive-data
另一個選擇是您可以創建與您的單元測試用例相對應的資源文件https://www.danylkoweb.com/Blog/the-fastest-way-to-mock-a-database-for-unit-testing-B6
我還想讓您了解InMemoryDB與SqlLite的性能, http://www.mukeshkumar.net/articles/efcore/unit-testing-with-inmemory-provider-and-sqlite-in-memory-database-in- ef-core
儘管以上示例是針對EFCore的,但在EF6中,我們也可以使用SqlLite https://www.codeproject.com/Tips/1056400/Setting-up-SQLite-and-Entity-Framework-Code-First
因此,我建議您使用sqllite進行集成測試方案。對於單元測試,可以使用sqllite或Faker \ Bogus和NBuilder。
希望能幫助到你!