天天看點

使用NModel自動生成測試用例

模型驅動測試的想法和飛機的風洞測試差不多,即根據功能需求說明書,對要測試的程式先建立一個模型,然後有另外一個程式分析這個模型,産生測試用例。就好比為了驗證新飛機的氣動布局,不可能建一個全比例的飛機,去測試它的布局是否合理;而是建立一個小的飛機模型,模型的氣動布局和整機的布局是一緻的。飛機模型建好以後,才放到風洞裡面測試一下。

市面上已經有幾個做模型驅動測試的工具了,這裡我用的是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&lt;User, LoginStatus&gt; ActiveLoginRequests = Map&lt;User,LoginStatus&gt;.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) &amp;&amp;

                   !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&lt;string&gt;("Login"));

        public static void Initialize()

            State = ModeState.Running;

        public static bool InitializeEnabled() { return State == ModeState.Initializing; }

        public static Set&lt;User&gt; UsersLoggedIn = Set&lt;User&gt;.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  ,如需轉載請自行聯系原作者

繼續閱讀