模型驅動測試的想法和飛機的風洞測試差不多,即根據功能需求說明書,對要測試的程式先建立一個模型,然後有另外一個程式分析這個模型,産生測試用例。就好比為了驗證新飛機的氣動布局,不可能建一個全比例的飛機,去測試它的布局是否合理;而是建立一個小的飛機模型,模型的氣動布局和整機的布局是一緻的。飛機模型建好以後,才放到風洞裡面測試一下。
市面上已經有幾個做模型驅動測試的工具了,這裡我用的是NModel,本來想拿SpecExplorer嘗一下鮮的,但最後發現這個想法太貴了—需要安裝了Visual Studio 2010才能使用“免費”的SpecExplorer。你可以在這個網頁裡下載下傳 NModel:
<a href="http://nmodel.codeplex.com/" target="_blank">http://nmodel.codeplex.com/</a>
在NModel中,測試人員使用C#建立程式的模型,模型建立的原理是:
1. 程式是用來處理資料的,資料也可以稱作狀态(State);
2. 使用者通過程式提供的操作界面來處理資料,操作界面也可以稱作動作(Action);
3. 資料的更動 又反過來影響一些動作是否可以執行。
比如說,使用Word的時候,剛啟動程式時是沒有任何資料的,這個時候有些動作,例如“儲存”是禁用的。當使用者通過“建立”這個動作建立了一個新檔案(資料),這個新檔案反過來激活“儲存”動作。
是以當測試人員模組化時,他要做的工作就是将程式的動作和狀态抽象出來,并且描述動作和狀态互相影響的過程。
來看一個例子,假如現在要測試一個使用者登入程式,登入界面就是一個輸入使用者名和密碼的文本框,而程式支援的使用者有兩種:管理者和授權使用者。
先來做第一步,将動作和狀态抽象出來,程式的狀态應該包括:
1. 程式狀态:運作狀态和未運作狀态。
2. 使用者類型:管理者和授權使用者。
3. 密碼:正确的密碼和錯誤的密碼。
4. 登入狀态:成功登入和登入失敗。
動作應該包括:
1. 登入:即使用者在界面上輸入使用者名和密碼。
2. 登出。
第二步,編寫C# 程式模組化。
狀态已經抽象出來了,在NModel裡面,抽象出來的狀态一般是用枚舉值表示的。
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")]
public static void Logout(User user)
WebSiteModel.UsersLoggedIn = WebSiteModel.UsersLoggedIn.Remove(user);
public static bool LogoutEnabled()
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"));
public static void Initialize()
State = ModeState.Running;
public static bool InitializeEnabled() { return State == ModeState.Initializing; }
public static Set<User> UsersLoggedIn = Set<User>.EmptySet;
編譯通過以後,先用NModel提供的圖形化模型驗證工具檢視一下生成的模型是否正确。NModel自帶的mpv.exe是用來驗證模型的,但是 mpv.exe使用到一個圖形布局程式GLEE需要單獨下載下傳,下載下傳後,将Microsoft.GLEE.*.dll拷貝到NModel的bin檔案夾裡,就可以執行mpv.exe了。
使用下面的指令檢視生成的模型:
"d:\Program Files\NModel\bin\mpv.exe" /r:TrainMode.dll TrainMode.WebSiteModel.CreateLoginModel
生成的模型應該如下圖所示:
下圖是放大後的結果:
如果檢視模型以後,覺得沒有問題,就可以生成測試用例了,這裡先生成手工的測試用例,下一篇再介紹如何生成自動化的測試用例。
"d:\Program Files\NModel\bin\otg.exe" /r:TrainMode.dll /f:scenario.txt TrainMode.WebSiteModel.CreateLoginModel
下面是生成的測試用例:
TestSuite(
TestCase(
Initialize(),
Login_Start(User("Authenticated"), Password("Correct")),
Login_Start(User("Administrator"), Password("Incorrect")),
Logout(User("Authenticated"))
),
Login_Start(User("Administrator"), Password("Correct")),
Login_Start(User("Authenticated"), Password("Correct")),
Logout(User("Administrator")),
Login_Start(User("Authenticated"), Password("Incorrect"))
Login_Start(User("Authenticated"), Password("Incorrect")),
Logout(User("Administrator"))
Login_Start(User("Authenticated"), Password("Correct"))
Logout(User("Authenticated")),
Login_Start(User("Administrator"), Password("Correct"))
Login_Start(User("Administrator"), Password("Incorrect"))
)
)
本文轉自 donjuan 部落格園部落格,原文連結: http://www.cnblogs.com/killmyday/archive/2010/04/17/1714257.html ,如需轉載請自行聯系原作者