測試用例(Test Case)是為某個特殊目標而編制的一組測試輸入、執行條件以及預期結果,以便測試某個程序路徑或核實是否滿足某個特定需求。 測試用例(Test Case)目前沒有經典的定義。比較通常的說法是:指對一項特定的軟件產品進行測試任務的描述,體現測試方案、方法、技術和策略。內容包括測試目標、測試環境、輸入數據、測試步驟、預期結果、測試腳本等,并形成文檔。
在前面的網站自動化系統里面,大概聊了下如何結合Selenium生成的代碼和VSTT創建一個簡單的自動化系統。雖然在文章網站測試自動化系統—基于Selenium和VSTT、數據驅動測試、在測試代碼中硬編碼測試數據里,我講了一些封裝代碼以及測試數據的技巧,規避后續開發過程中,程序員修改代碼時,對測試程序帶來的影響。但是每次程序員做出大的改動的時候,測試人員還是要修改大量的測試代碼,更糟糕的是,每次大的改動,又涉及到測試覆蓋是否足夠的問題。為了規避類似的風險,以及幫助測試人員創建盡量多的測試用例,有些人提出了模型驅動測試的概念。
模型驅動測試的想法和飛機的風洞測試差不多,即根據功能需求說明書,對要測試的程序先建立一個模型,然后有另外一個程序分析這個模型,產生測試用例。就好比為了驗證新飛機的氣動布局,不可能建一個全比例的飛機,去測試它的布局是否合理;而是建立一個小的飛機模型,模型的氣動布局和整機的布局是一致的。飛機模型建好以后,才放到風洞里面測試一下。
市面上已經有幾個做模型驅動測試的工具了,這里我用的是NModel,本來想拿SpecExplorer嘗一下鮮的,但最后發現這個想法太貴了—需要安裝了Visual Studio 2010才能使用“免費”的SpecExplorer。你可以在這個網頁里下載 NModel:
在NModel中,測試人員使用C#創建程序的模型,模型創建的原理是:
1.程序是用來處理數據的,數據也可以稱作狀態(State);
2.用戶通過程序提供的操作界面來處理數據,操作界面也可以稱作動作(Action);
3.數據的更動 又反過來影響一些動作是否可以執行。
比如說,使用Word的時候,剛啟動程序時是沒有任何數據的,這個時候有些動作,例如“保存”是禁用的。當用戶通過“新建”這個動作創建了一個新文件(數據),這個新文件反過來激活“保存”動作。
因此當測試人員建模時,他要做的工作就是將程序的動作和狀態抽象出來,并且描述動作和狀態相互影響的過程。
來看一個例子,假如現在要測試一個用戶登錄程序,登錄界面就是一個輸入用戶名和密碼的文本框,而程序支持的用戶有兩種:管理員和授權用戶。
先來做第一步,將動作和狀態抽象出來,程序的狀態應該包括:
1.程序狀態:運行狀態和未運行狀態。
2.用戶類型:管理員和授權用戶。
3.密碼:正確的密碼和錯誤的密碼。
4.登錄狀態:成功登錄和登錄失敗。
動作應該包括:
1.登錄:即用戶在界面上輸入用戶名和密碼。
2.注銷。
第二步,編寫C#?程序建模。
狀態已經抽象出來了,在NModel里面,抽象出來的狀態一般是用枚舉值表示的。
MILY: 'Courier New'">public enum ModeState { Initializing, Running }
public enum User { Authenticated, Administrator }
public enum Password { Correct, Incorrect }
public enum LoginStatus { Success, Failure } |
接下來模擬動作:
[Feature("Login")] public static class Login { public static Map<User, LoginStatus> ActiveLoginRequests = Map<User, LoginStatus>.EmptyMap;
[Requirement("Send username and password to the server to log in.")] [Action] public static void Login_Start(User user, Password password) { if (password == Password.Correct) ActiveLoginRequests = ActiveLoginRequests.Add(user, LoginStatus.Success); else ActiveLoginRequests = ActiveLoginRequests.Add(user, LoginStatus.Failure); }
public static bool Login_StartEnabled() { return WebSiteModel.State == ModeState.Running; }
public static bool Login_StartEnabled(User user) { return !ActiveLoginRequests.ContainsKey(user) && !WebSiteModel.UsersLoggedIn.Contains(user); }
[Requirement("It should be possible to log out from any page")] [Action] public static void Logout(User user) { WebSiteModel.UsersLoggedIn = WebSiteModel.UsersLoggedIn.Remove(user); } public static bool LogoutEnabled() { return WebSiteModel.State == ModeState.Running; }
public static bool LogoutEnabled(User user) { return WebSiteModel.UsersLoggedIn.Contains(user); } } |
上面的代碼稍微解釋一下,標注了[Action]的函數,就是抽象出來的程序所支持的動作,例如Logout;而在動作函數名后面加上Enabled的函數,是NModel用來判定指定的動作是否可以執行,例如LogoutEnabled函數。
Feature屬性,我們現在不講,NModel用這個屬性來標識一個大的功能。
另外要注意的是,在NModel里面,集合Set、Map是不可變的,即創建好了以后,就不能從里面刪除和添加新元素了。每一次修改都會創建一個新的Set、Map實例。所以你會看到類似下面的用法:
ActiveLoginRequests = ActiveLoginRequests.Add(user, LoginStatus.Success);
最后,你需要采用一個工廠模式的方式,告訴NModel分析哪一個Feature,創建測試用例
public class WebSiteModel { public static ModeState State = ModeState.Initializing;
public static ModelProgram CreateLoginModel() { return new LibraryModelProgram(typeof(WebSiteModel).Assembly, "TrainMode", new Set<string>("Login")); }
[Action] public static void Initialize() { State = ModeState.Running; }
public static bool InitializeEnabled() { return State == ModeState.Initializing; }
public static Set<User> UsersLoggedIn = Set<User>.EmptySet; } |
文章來源于領測軟件測試網 http://www.kjueaiud.com/