Selenium Web Driver自动化测试(java版)系列下半部分(31) - 用数据驱动搭建测试框架雏形(4) - 添加测试配置文件以及利用java反射机制优化控制类

上篇我们添加了用户模块的test case,算上登录模块,我们已经有五个test case了。TestRunner.java看起来如下:

可以看出来,随着TestRunner.java越来越长,如果有很多test case你就得实例化每一个+调用test()方法,很不方便维护。比如我现在只想执行登录模块的,不想执行别的?或者是,现在的系统默认是用chrome来跑的,我想用ie或是firefox该怎么办呢?其中一个答案就是设置一个配置文件来解决。通过读取文件上的值我们可以自由配置我们想要的测试参数,如果希望改变则直接修改配置文件即可。

首先声明一下,配置文件可以是任意格式、任意后缀名的,只要满足你设计的框架要求就行了。我们设计框架以来一直用的都是Excel文件,那这次搞配置文件我们就用csv文件吧,顺便复习一下。新建文件夹config -> config.csv:

在里面写上如下内容:

就这一行,里面有4列,定义了用哪种浏览器,driver的路径,以及测试的模块等:

先把csv文件上的数据读到数组里,文件读取也属于测试中的一些常用的、必要的步骤,所以还是放在com.testalliance.hrsystem.test中,这里我们创建一个新类Utility.java:

写如下代码:

依靠getModules()方法读取csv文件的内容,读到逗号时进行分割并把当前一行信息放入一个数组中,然后把每一个数组放入ArrayList里。不太理解的朋友可以去参考csv文件操作那篇。接下来我们把TestRunner.java改成下面这个样子:

第16行调用getModules()方法获取所有的配置信息,然后通过循环ArrayList一个个读取出来。第27行和28行是处理测试模块的步骤,可能有些人看不太懂。第27行用字符串的replace()方法将"{"和"}"去掉,然后以“|”为新的分隔符再划分成几部分放入arr_modules数组中。比如我们例子中从ArrayList读取出来的最后一列字符串是"{login|employee}",先将左右括号去掉后变成"login|employee",再以"|"为分隔符把login和employee放进数组arr_modules里。另外,你可以把每个case的test()方法都修改成接受三个参数用于执行测试步骤。这么一改,我发现可以有选择性地执行模块了。

但即便是这样,我们还是觉得TestRunner.java很臃肿,测试用例多了之后还要加上各种判断语句和实例化过程,其实并没有改变太多。所以,我们还要继续修改。首先观察一下测试用例类和测试文件的名称:

文件名称是一一对应的,只不过后缀名不一样而已。仔细想一下,如果只希望执行某个模块的测试用例,我们势必要遍历整个测试文件夹:

每读到一个文件,就要实例化对应的用例,比如读到TCLogin3.xlsx,我们就要实例化TCLogin3,读到TCEmp1.xlsx,我们就要实例化TCEmp1。测试文件名本质上是一个字符串,而类名本质上是一个类,那我可不可以有一种办法,可以把字符串转成类,这样是不是程序执行时只要通过循环读取文件名就能自动实例化类了?是不是我们就不用再一遍遍来回写了?做这步之前,我们先简单修改一下TestRunner.java:

画红框的部分就是增加或修改的地方,第30行到37行就是遍历某个测试数据文件夹然后取出某个文件名的过程。取出的文件名带有后缀.xlsx,要去掉,因为类名是没有后缀的。这里用到的都是字符串的操作,不说太多了。正是因为我们每次取出一个文件代表一个类,也就是一个测试用例,我们其实可以把测试的准备工作从每个test()方法中单独提取出来,这步在第45行和46行。因为单独提取出来了,那我们完全可以在准备步骤里就传入driverBrowser,driverPath和browser三个参数,test()方法里只需要传入driver即可。这样,准备工作是准备工作,测试步骤是测试步骤,两者分开了。把测试类中test()方法里的准备步骤去掉,以TCLogin1.java为例:

现在更明显了吧?我们现在要做的就是要把TestRunner.java里面的if-else语句替换成文件名转类名的过程就行了。好了,问题来了,怎样才能把文件名转成类名呢?java里有一个类似的功能,叫做反射机制,可以帮助我们。

首先我们回顾一下之前介绍的一些java基本概念。在讨论面向对象的时候我们说实例化一个对象时内存中应该是这样的:

当执行到Wanghong w = new Wanghong()时,Wanghong对象被创建出来,但与此同时其实还有一个对象被创建出来(其实是在.class文件被加载到JVM的时候),这个对象的类型是Class,指向的是Wanghong类的一些信息:

我们在介绍java的第一篇就说了,一段程序运行时首先会生成一个.class文件,随后这个.class文件会被加载到java虚拟机(JVM)中并被执行,这个Class类型的对象就是这个时候创建的。那怎样得到这个对象呢?为了演示,我新建了一个叫JavaReflection的项目:

看下面的代码:

Wanghong.java:

Test.java:

看Test.java,第一种得到Class类对象的方法就是用Wanghong类的对象调用一个叫getClass()的方法,然后可以打印出来它的一些基本信息;第二种方法直接调用class属性;第三种调用forName()方法,需要添加该类的完整路径作为参数,注意是完整路径,包括包名。

有一点需要指出的是,在同一个运行时一个类只有一个Class类对象被创建出来,也就是说wClass1、wClass2、wClass3它们都是一个东西。Java反射这部分知识在测试中暂时用得不多,我就讲到这儿,具体可以参考其它一些文章,我参考的就是这篇,讲得很详细。大家现在仔细看看第三种方式,类的完整路径是一个字符串,我们通过这个字符串可以获得类名。有人说你讲这个反射我还是没明白和咱们的测试执行有什么关系,接着看。java映射的概念就是可以把一个类中的成员(包,构造方法,成员方法,成员变量等等)映射成一个个对象,比如Class对象,是通过com.test包中的Wanghong类得到的。同样,如果我们写Class c = Class.forName("com.testalliance.hrsystem.tests.login.TCLogin1“)也会得到一个Class对象。TCLogin1.java里有一个test()方法,用于执行测试用例,我们也可以把这个成员方法映射成对象。TCLogin1.java默认还有构造函数,用于初始化一个对象,我们还可以把构造函数映射成对象。这么多对象干什么用?答案在下面的红框里:

第59行是成员方法的反射使用。用Class对象调用getMethod()方法可以获取到某个成员方法的对象,它接收的参数一个是方法名,还一个是参数类型,因为我们是driver,所以写WebDriver.class。参数类型根据方法的参数个数而定,test()方法只有一个driver参数,所以我们只放一个WebDriver.class。第61行是构造方法的反射使用,构造方法的作用是初始化一个类,在这里会得到测试类的对象classObj,这一步相当于Wanghong w = new Wanghong()。第63行用方法对象调用invoke方法传入classObj和driver作为参数,相当于调用了test()方法。其实还是一个道理,只不过对象、方法、参数都颠倒过来了,感觉很别扭。这种正向反向可以看下图对比一下:

想初始化测试类就得先获取Class对象,想调用test()方法就得先获取方法对象,这么理解可能就容易些。更多反射的用法还是可以参照这篇,我就不再啰嗦了。

执行一下,测试通过。改动到此为止,下一篇我们再做几个简单的变化,这个框架雏形就完成了。对于配置文件来说还是那句话,只要和自己设计的框架吻合就可以了。

这篇文章的源代码在SeleniumExcelDataDrivenFrame4项目里边。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,565评论 18 399
  • 上两篇我们结合数据驱动讨论了page object模型,分别用了Excel和csv进行演示。其中Excel参与的演...
    马可吃菠萝阅读 712评论 0 2
  • 屋顶不高。瓦片灰尘掉落在地板上,像一朵朵雪白的云絮没有一丝风堆在一起。淡淡的阳光在玻璃窗缝射进来。辛而紧接对着她的...
    兔m阅读 329评论 0 0
  • 防皱养颜:山药烩秋葵 主料:山药180克,胡萝卜180克,黄秋葵120克,玉米笋120克,大枣30克。 配料:油3...
    89不离食阅读 315评论 0 0
  • 想研究美图的初衷在于其做为厦门目前最知名的互联网公司之神秘(身为厦门人的我更为好奇)。 而且这2年其动作之频繁: ...
    ElekChen阅读 488评论 4 2