51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 4020|回复: 1
打印 上一主题 下一主题

[转贴] 基于模型生成自动化测试用例

[复制链接]
  • TA的每日心情
    无聊
    昨天 09:13
  • 签到天数: 935 天

    连续签到: 2 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2016-10-11 11:51:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    在前面一文使用NModel自动生成测试用例中,介绍了如何通过给待测试的程序建模,生成测试用例的方法。但前面文章的问题是,生成的都是手工的测试用例,如果让测试人员手工执行程序自动生成的测试用例,呃……这对于测试工程师来说,不蒂于一场噩梦。

    自动产生的测试用例本就应该由程序自动执行,这其实也就是NModel推荐的模式。先回过头来看看前一篇文章中制作的模型,模型里面将登录、注销、用户名以及密码等要素都抽象出来了,而NModel是以这些抽象出来的动作(登录、注销)和状态(用户名、密码)为依据,产生测试用例的。那么要让NModel自动执行产生的测试用例,那么它需要知道如何才能执行登录和注销这些动作,而且它还需要知道在执行登录操作时,User.Administrator这个抽象出来的用户在实际执行测试用例时,应该采用什么用户名等信息。而这些信息NModel自己是无法“猜测”出来的,需要测试人员的引导才能获得。

    因此NModel提供了IStepper这个接口让测试人员提供所需的信息,下面是这个接口的完整定义:
    1. namespace NModel.Conformance

    2. {

    3.     // Summary:

    4.     //     Must be implemented by an IUT for conformance testing

    5.     public interface IStepper

    6.     {

    7.         // Summary:

    8.         //     Make a step according to the given action, the current state becomes the

    9.         //     target state of this transition. If the action is not enabled an exception

    10.         //     is thrown and the resulting state is undefined. An action on null may be

    11.         //     returned.

    12.         //

    13.         // Parameters:

    14.         //   action:

    15.         CompoundTerm DoAction(CompoundTerm action);

    16.         //

    17.         // Summary:

    18.         //     Return to the initial state. If Reset is not enabled in the current state,

    19.         //     an exception is thrown and the resulting state is undefined and is thus not

    20.         //     guaranteed to be the initial state

    21.         void Reset();

    22.     }

    23. }
    复制代码
    这个接口的定义非常简单(但是实现起来就是另外一回事了),核心的函数是 DoAction,从名字可以看出,这个函数就是让测试人员自己实现前面模型中每一个动作。而NModel的工作就是将这些动作按照模型定义好的序列组合多个基本的动作。这样多个基本动作的组合就模拟了现实生活中,用户使用产品时的用户场景。在我们这个例子中,要实现的动作就是所有加上[Action]属性的函数,即Login_Start,Logout和WebSiteModel类里面的Initialize。
    我们看Initialize和Login_Start动作的实现:
    1. private void Initialize()

    2. {

    3.     TestSettings = TestLibrary.SetupTest();

    4. }



    5. public CompoundTerm DoAction(CompoundTerm action)

    6. {

    7.     switch (action.Name)

    8.     {

    9.         case "Initialize":

    10.             Initialize();

    11.             break;



    12.         case "Login_Start":

    13.             string userName;

    14.             modelUserToRealUser.TryGetValue((string)

    15.                 ((CompoundTerm)action.Arguments[0])[0], out userName);



    16.             string userPass = string.Empty;

    17.             switch ((string)((CompoundTerm)action.Arguments[1])[0])

    18.             {

    19.                 case "Correct":

    20.                     userPass = realUserPassword[userName];

    21.                     break;



    22.                 case "Incorrect":

    23.                     userPass = wrongPassword;

    24.                     break;

    25.             }



    26.             TestSettings.UserHelper.LogOn(userName, userPass);

    27.             var status = LoginStatus.Success;

    28.             if (TestSettings.UserHelper.IsLoginFaled())

    29.                 status = LoginStatus.Failure;



    30.             break;

    31.     }



    32.     return null;

    33. }
    复制代码
    这里,我用的是Selenium来实现网站测试用例的自动化, Initialize这个动作很简单,就是在执行所有自动化测试用例之前,做一些初始化操作,在我这个例子当中,就是启动浏览器,将测试用例连接到Selenium-RC上。读者如果不了解Selenium以及网站自动化测试的话,可以参考我的这篇文章网站测试自动化系统—基于Selenium和VSTT ,实际上Initialize函数里面的TestLibrary.SetupTest也是从那篇文章里拷贝出来的。

    而Login_Start这个函数就有点复杂了,因为在模型里面,Login_Start这个动作要求两个参数,或者说是状态—用户名和密码。而且用户分为Administrator和Authenticated两类,密码也类似。那么在哪个地方将这些抽象的状态具体化呢?当然是在执行测试用例之前,要么是构造函数,要么是前文说到的 Initialize函数。我的例子里面是在构造函数里执行初始化操作:
    1. public string wrongPassword;

    2. public Dictionary<ModelUser, RealUser> modelUserToRealUser;

    3. public Dictionary<RealUser, string> realUserPassword;



    4. public Site()

    5. {

    6.     modelUserToRealUser = new Dictionary<string, string>();

    7.     modelUserToRealUser.Add("Anonymous", TestLibrary.Consts.ContributorUser);

    8.     modelUserToRealUser.Add("Authenticated", TestLibrary.Consts.ModeratorUser);

    9.     modelUserToRealUser.Add("Author", TestLibrary.Consts.AuthorUser);

    10.     modelUserToRealUser.Add("Administrator", TestLibrary.Consts.AdminUserName);



    11.     realUserPassword = new Dictionary<string, string>();

    12.     realUserPassword.Add(TestLibrary.Consts.AdminUserName, TestLibrary.Consts.CommonPassword);

    13.     realUserPassword.Add(TestLibrary.Consts.AuthorUser, TestLibrary.Consts.CommonPassword);

    14.     realUserPassword.Add(TestLibrary.Consts.ContributorUser, TestLibrary.Consts.CommonPassword);

    15.     realUserPassword.Add(TestLibrary.Consts.ModeratorUser, TestLibrary.Consts.CommonPassword);



    16.     wrongPassword = "abcefghi";

    17. }
    复制代码
    将所有抽象出来的动作和状态具体化以后,就可以让 NModel产生测试用例并根据我们提供的信息自动执行测试用例了,下面这个命令完成这个操作:
    Ct.exe /r:TrainStep.dll /r:TrainMode.dll /iut:Train.Test.Site.Create TrainMode.WebSiteModel.CreateLoginModel
    Ct.exe用来产生并执行测试用例,为了完成这个工作,ct.exe需要知道模型(TrainModel.dll中的TrainModel.WebSiteModel.CreateLoginModel)和模型的一个实例(TrainStep.dll),但是/iut这个参数是干什么用的?因为一个dll文件当中,你可以有模型的多个实例,或者不同模型的实例,因此,ct.exe需要你明确指定创建模型实例的方法(Train.Test.Site.Create)。

    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏2
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-4-24 05:19 , Processed in 0.068889 second(s), 26 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表