使用NModel自动生成测试用例

简介:

在前面的网站自动化系统里面,大概聊了下如何结合Selenium生成的代码和VSTT创建一个简单的自动化系统。虽然在文章网站测试自动化系统—基于Selenium和VSTT数据驱动测试在测试代码中硬编码测试数据里,我讲了一些封装代码以及测试数据的技巧,规避后续开发过程中,程序员修改代码时,对测试程序带来的影响。但是每次程序员做出大的改动的时候,测试人员还是要修改大量的测试代码,更糟糕的是,每次大的改动,又涉及到测试覆盖是否足够的问题。为了规避类似的风险,以及帮助测试人员创建尽量多的测试用例,有些人提出了模型驱动测试的概念。

模型驱动测试的想法和飞机的风洞测试差不多,即根据功能需求说明书,对要测试的程序先建立一个模型,然后有另外一个程序分析这个模型,产生测试用例。就好比为了验证新飞机的气动布局,不可能建一个全比例的飞机,去测试它的布局是否合理;而是建立一个小的飞机模型,模型的气动布局和整机的布局是一致的。飞机模型建好以后,才放到风洞里面测试一下。

市面上已经有几个做模型驱动测试的工具了,这里我用的是NModel,本来想拿SpecExplorer尝一下鲜的,但最后发现这个想法太贵了需要安装了Visual Studio 2010才能使用“免费”的SpecExplorer。你可以在这个网页里下载 NModel

http://nmodel.codeplex.com/

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<UserLoginStatus> 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里面,集合SetMap是不可变的,即创建好了以后,就不能从里面删除和添加新元素了。每一次修改都会创建一个新的SetMap实例。所以你会看到类似下面的用法:

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;

    }

 

编译通过以后,先用NModel提供的图形化模型验证工具查看一下生成的模型是否正确。NModel自带的mpv.exe是用来验证模型的,但是 mpv.exe使用到一个图形布局程序GLEE需要单独下载,下载后,将Microsoft.GLEE.*.dll拷贝到NModelbin文件夹里,就可以执行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"))

    ),

    TestCase(

        Initialize(),

        Login_Start(User("Administrator"), Password("Correct")),

        Login_Start(User("Authenticated"), Password("Correct")),

        Logout(User("Administrator")),

        Logout(User("Authenticated"))

    ),

    TestCase(

        Initialize(),

        Login_Start(User("Administrator"), Password("Incorrect")),

        Login_Start(User("Authenticated"), Password("Incorrect"))

    ),

    TestCase(

        Initialize(),

        Login_Start(User("Authenticated"), Password("Incorrect")),

        Login_Start(User("Administrator"), Password("Correct")),

        Logout(User("Administrator"))

    ),

    TestCase(

        Initialize(),

        Login_Start(User("Administrator"), Password("Incorrect")),

        Login_Start(User("Authenticated"), Password("Correct"))

    ),

    TestCase(

        Initialize(),

        Login_Start(User("Administrator"), Password("Correct")),

        Login_Start(User("Authenticated"), Password("Incorrect"))

    ),

    TestCase(

        Initialize(),

        Login_Start(User("Administrator"), Password("Correct")),

        Logout(User("Administrator")),

        Login_Start(User("Authenticated"), Password("Correct"))

    ),

    TestCase(

        Initialize(),

        Login_Start(User("Authenticated"), Password("Correct")),

        Logout(User("Authenticated")),

        Login_Start(User("Administrator"), Password("Correct"))

    ),

    TestCase(

        Initialize(),

        Login_Start(User("Administrator"), Password("Correct")),

        Logout(User("Administrator")),

        Login_Start(User("Authenticated"), Password("Incorrect"))

    ),

    TestCase(

        Initialize(),

        Login_Start(User("Authenticated"), Password("Correct")),

        Login_Start(User("Administrator"), Password("Correct")),

        Logout(User("Authenticated")),

        Logout(User("Administrator"))

    ),

    TestCase(

        Initialize(),

        Login_Start(User("Authenticated"), Password("Incorrect")),

        Login_Start(User("Administrator"), Password("Incorrect"))

    ),

    TestCase(

        Initialize(),

        Login_Start(User("Authenticated"), Password("Correct")),

        Logout(User("Authenticated")),

        Login_Start(User("Administrator"), Password("Incorrect"))

    )

)

 

标签:  测试
本文转自 donjuan 博客园博客,原文链接: http://www.cnblogs.com/killmyday/archive/2010/04/17/1714257.html   ,如需转载请自行联系原作者

相关文章
|
1月前
|
测试技术
编写测试用例
编写测试用例
22 7
|
2月前
|
数据采集 运维 安全
测试需要写测试用例吗?
测试需要写测试用例吗?
30 0
|
2月前
|
测试技术
你还在写测试用例吗
你还在写测试用例吗
|
7月前
|
测试技术 程序员 数据安全/隐私保护
如何编写测试用例?
如何编写测试用例?
114 1
|
2月前
|
测试技术
接口测试测试用例编写注意事项
接口测试测试用例编写注意事项
|
1月前
|
C# Python
如何让 StyleCop 忽略 refit 自动生成的代码
创建自定义规则:我们需要创建一个自定义规则,该规则将用于排除特定类型的代码,我们可以创建一个自定义规则,用于检查类名是否以大写字母开头,然后忽略符合此规则的代码。
|
3月前
|
数据库
自动生成测试数据—接口
自动生成测试数据—接口
|
2月前
|
测试技术 数据库
怎么样写出好的测试用例?
怎么样写出好的测试用例?
|
4月前
|
C#
C#调试与测试 | DebuggerDisplay使用技巧
DebuggerDisplay可以让你在调试器中显示你自己定义的字符串,代替默认的显示方式。换句话说,它可以让你在调试器中更加方便地查看对象的信息。 当你在调试一个复杂的对象时,往往会发现默认的显示方式不能满足你的需求。这时,你可以使用 DebuggerDisplay 来自定义你想要显示的信息。例如,你可以将一些比较重要的属性或字段的值显示在调试器中,这样你就可以更加方便地了解对象的状态。另外,如果你使用了一些自定义的类,这些类可能没有默认的 ToString 方法,调试器默认的显示方式就会非常简陋,这时你可以使用 DebuggerDisplay 来定义一个更加友好的显示方式。
31 0
|
4月前
|
JavaScript 前端开发 测试技术
一文带你了解图形测试用例|API 自动化测试
Eolink Apikit 的图形用例是指通过图形化的方式去表现 API 流程测试。它包括了条件选择器、单个 API 步骤和操作集等组件。 相较于前面推荐的表格化的通用用例,图形用例可以让测试人员更方便地设计和管理 API 流程测试,同时也更加的灵活。
61 0

热门文章

最新文章