TDD自動測試
前言
當開發團隊日趨龐大,如果都在同一個測試資料庫上跑自動測試,難免會造成測試結果互相干擾。
為了解決這些問題,讓每個開發者都在獨立的測試環境下進行測試,Sqllocaldb會是一個很好的選擇。本篇文章分成六個步驟來完成這個範例。
建立資料庫執行個體
這玩意其實很早就出了,安裝VS2012以上的版本,會自動安裝Sqllocaldb。如果不確定是否已經安裝,只需要打開VS開發工具叫出Package Manager Console,然後輸入指令Sqllocaldb,如下圖表示,有跑出說明就代表有安裝。
接下輸入指令sqllocaldb create "執行個體名稱",請參考下圖,會建立出Demosqllocaldb的執行個體。
執行完成之後,請打開SQL Managerment Studio,登入剛剛建好的localdb,這裡的重點只有實體名稱前方要加(localdb)。
登入後可以看到實體名稱其實是對應我們剛剛用sqllocaldb指令建出來的實體名稱,到這裡為止資料庫的執行個體已經建立完畢。Sqllocaldb參考指令
安裝Entity Framework
這個範例用的ORM套件是Entity Framework。而建立資料庫的方式,最常見的就是DB first和Code first,這裡採用的是Code first,如果是原本資料庫就存在的資料表,可以先用DB first的方式將layout匯入成類別,會比自己一個一個屬性手動打要來的快。但這裡不建議正式資料庫使用Code first,因為蠻危險的,localdb搞壞了,大不了就是砍掉重練,但線上資料庫搞壞了,可就不能這樣玩。
建立資料庫
架構圖如下,我們已經完成了建立sqllocaldb的資料庫執行個體,現在要建立資料庫。
建立資料庫第一個步驟是在WebConfig新增connectString,name的名稱可以自己定義,Entity Framework會依照這個名稱找到這條連線字串,Data Source指定成我們已經建好的執行個體名稱,Initial Catalog的名稱可自己定義,以下範例是定義成COMMON,如果(localdb)\Demolocaldb執行個體內沒有COMMON資料庫,Entity Framework會自動建立,剩下的屬性無須修改。
接著新增一個類別,繼承DbContext,名稱可以自定,這裡會用A開頭,主要是希望它排在最前面,裡面提供兩個建構子,預設就是讀取我們剛剛已經建立的COMMON連線字串。
public class APortalDbContext : DbContext
{
public APortalDbContext() : this("COMMON")
{
}
public APortalDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
}
到這裡為止,我們已經完成了資料庫的設定。
建立資料表
接著要建立資料表,我們假設要新增一個Member的資料表,資料表內有兩個欄位,分別是ID和Name。其實就相當於建立一個Member的類別,裡面有兩個屬性,一個是ID,一個是Name。型別可以自己決定,
public class Member
{
[Key]
public Guid ID{ get; set; }
[StringLength(30)]
public string Name{ get; set; }
}
建立好資料表,接著我們要將它掛到我們的資料庫上,所以直接在剛剛新增的APortalDbContext的類別裡新增一個屬性,型別是DbSet,然後用泛型告知是屬於Member的型別,建議屬性名稱後面都加一個小寫的s,因為資料表裡面會有很多資料列,這是一個集合的概念。完整的程式如下所示。
public class APortalDbContext : DbContext
{
public APortalDbContext() : this("COMMON")
{
}
public APortalDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
public DbSet<Member> Members{ get; set; }
}
到這裡為止,就已經完成了資料表的宣告。
設定Migration的Config
Migration主要是在管理資料庫更新的歷程,它需要繼承DbMigrationsConfiguration,建議把AutomaticMigrationsEnabled關掉,因為更新資料庫還是需要謹慎一點比較好,當要異動資料表時,藉由下指令的方式,透過Migration幫我們生成一個檔案,這個在第六個步驟產生語法與更新會提到。程式範例如下所示。
internal sealed class Configuration : DbMigrationsConfiguration<APortalDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(J1A2PortalDbContext context)
{
var member = new Member();
member.ID = Guid.NewGuid();
member.Name = "Test";
member.CodeReviewUrl = "TestUrl";
context.Member.Add(member);
}
}
這裡我們已經完成了簡單的設定步驟,接下來最後的動作就是要產生SQL語法並更新我們的資料庫。
產生語法和更新
現在萬事俱備,只欠東風了,開啟Package Manager Console,輸入add-migration "更新的名稱",如下圖所示。
接著會自動幫你生成以下檔案
這個檔案看內容應該就能理解,它裡面記載了向上更版和向下退版的資訊,之後再執行update-database,資料庫和資料表便會建立起來。更多的相關語法
到此為止,已經成功建置出我們的測試基地。
結論
整個建構的步驟老實講,有點繁瑣,但很多步驟都是一次性的工作。一旦測試基地建立完成,往後要做測試就無需再重複的建立測試資料。並且藉由sqllocalDb的隔離性,可減少測試時不避要的干擾。而本機資料庫的版本控管,可透過版本控管系統把migration產生的程式簽入版控系統中,就能確保每個成員的本機資料庫的一致性,進而享受到sqllocaldb所帶來的好處與便利。