上篇我们添加了登录失败的test case,完成了整个登录模块。这篇我们继续写下一个模块 - 用户模块。当你用一组员工代号/密码登录成功示例网站后点击导航栏Employee,出现的是所有员工的基本信息:
注意第三列是Last Login Date,指的是最后一次登录日期。你每次只要用一组员工代号/密码登录成功,系统就会返回该员工最新登录的日期。从上图中可以看出来,每个员工最后登录日期都是2018年5月31日。我这里设计了一个测试用例,验证的是最后登录日期是否和你电脑屏幕右下角的系统时间一致。
1. 登录http://www.cslm-test.com/hrsystem/index.php
2. 输入员工代号和密码;
3. 点击登录按钮;
4. 点击Employee;
5. 验证登录员工的最后登录日期是否和系统时间一致
这里请注意一下,由于页面上显示的是网站服务器的日期,不是真正你屏幕右下角的系统日期,但世界各地又差不过24小时,所以我们只要确保页面日期在系统日期前一天到后一天之间即可。比如我现在电脑上的系统日期是2018-06-01,那我们放宽一下要求,只要页面日期是2018-05-31、2018-06-01、2018-06-02之中的任意一天就行了。
首先还是先定位页面上的元素然后放进object repository中,我整理了一下,其实就两个,一个是导航栏上的Employee,还一个是日期。在com.testalliance.hrsystem.objrepository中新建empPage.properties:
日期的xpath里面员工代号的位置是“||EMPCODE||”,我们有三个员工,所以这地方不能写死,“||EMPCODE||”指的是这个位置未来是要被刚刚登录的员工代号替换的。
下一步就该写包括所有操作和断言的page object的类了。写登录操作时起的名字是LoginPage.java,那我就叫用户模块EmpPage.java吧。在com.testalliance.hrsystem.pageobj中新建EmpPage.java:
测试用例中的前三步都沿用LoginPage.java里的操作方法,不说了,我们只需要把第4步和第5步写到EmpPage.java中。完整代码如下:
首先还是在第25行读取page objects。接下来点击Employee的操作是navToEmployee()方法,在第43行。验证日期的操作是第50行的verifyLoginDate()方法,那问题来了,怎样比较两个日期是否相等呢?网站页面上的日期本质上其实就是个字符串,而你屏幕右下角的系统日期是日期格式的,格式都不一样你怎么比较这两者呢?
这就需要日期和字符串之间进行转换了。我的想法是把屏幕右下角系统日期转换成字符串,然后和页面上的比较。页面日期字符串很容易取出,定位后用getText()方法就可以了,这步操作在第74行到第77行之间。之前说需要把"||EMPCODE||"这个字符串替换成登录员工的员工代号,也是在这里完成,这就是为什么verifyLoginDate()方法需要传入一个员工代号的参数。
接下来我就要把系统日期转成字符串了。java文档中有个类叫Date,主要负责日期之类的处理:
这里有关于日期和时间的所有操作,大家有机会可以多看一看。回来看程序,第53行是实例化一个Date对象的过程,得到的就是今天日期的对象,我给它起名为today。其实仅仅做这一步我已经取到了系统日期,但这个today是Date类型的,我要把它转成字符串,这就需要借助另一个叫SimpleDateFormat的类:
看第54行和55行我是怎么用它的,先实例化对象再调用format方法。实例化对象时需要一个日期格式,它指的是日期转换后的字符串格式。因为页面上的日期字符串格式是"yyyy-MM-dd":
我只有把今天日期的对象today转成相同格式的字符串才可以进行比较,否则没可比性。所以,我把参数也写成"yyyy-MM-dd"。当然,这只是我们例子中的需要,SimpleDateFormat还可以接受其它的日期格式,比如"yyyy-MM-dd hh:mm:ss",精确到秒。总之,你希望目标字符串是什么日期格式,你的参数就写成什么格式。第55行是转换过程,用SimpleDateFormat的对象df调用format()方法,里面传入today对象,返回的就是今天日期的字符串。
这还没完,刚才说了,由于页面上显示的是网站服务器的日期,不是真正你屏幕右下角的系统日期,但世界各地又差不过24小时,所以我们只要确保页面日期在系统日期前一天到后一天之间即可,我们还需要拿到昨天和明天的日期字符串。改变日期还需要一个类,叫Calendar,日历类:
通过这个类改变日期的具体做法是通过把日期放到日历中再执行加减得到以给定日期为基准的前后日期。不明白没关系,一行一行解释。程序中第58行到65行是取得昨天日期的方法。还是要先取得Calendar对象,做法不是new一个,而是是通过Calendar调用静态方法getInstance()获取的,之前介绍静态方法时说过,它们可以通过类名来调用。通过Calendar对象c调用setTime()方法就是把日期放入日历的过程,它接受一个Date类型的日期参数,我把today传进去,把今天放进了日历。然后日历对象c调用add方法可以在刚才的日期参数也就是today的基础上进行加减得到之前或之后的日期,“-1”表示前一天,也就是昨天。完成这步之后日历上的日期也就变成了昨天,调用getTime()方法从日历中再把日期取出来,因为是Date类型,所以我还要转成字符串类型,和之前的一样。同理,我们还可以获取明天的字符串形式,在第68到72行。当我们同时取得了昨天、今天和明天后,就可以进行比较了。只要页面上的日期和其中一个相等,我们就可以说测试通过了。步骤在79到84行。
操作方法写完了就该设计数据源文件了。之前登录模块的四个数据源文件都放在了files里,因为只有一个模块。现在我们新增了员工模块,最好把它们分开,把files改成testdata.login,再新建testdata.employee -> TCEmp1.xlsx:
该改写测试用例了。和刚才的道理一样,之前登录模块的四个测试用例都放在了com.testalliance.hrsystem.tests里,因为只有一个模块。现在我们新增了员工模块,需要给它们分开,登录模块放在com.testalliance.hrsystem.tests.login中,员工模块放在com.testalliance.hrsystem.tests.emp中。新建com.testalliance.hrsystem.tests.emp -> TCEmp1.java:
添加如下代码:
注意,因为我们修改了文件夹的名字,文件的路径也就改变了。提醒一下,登录模块的四个用例也需要修改文件路径,我就不贴截图了。画红框的位置就是第四步和第五步的步骤,我们需要先得到page objects,然后再调用verifyLoginDate()方法。
最后,我们在TestRunner.java中添加TCEmp1的实例化以及调用test()方法的过程:
执行一下,测试通过:
这就是一个关于员工模块用例的演示,现在TestRunner.java已经越来越长了,如果有很多test case你就得实例化每一个+调用test()方法,很不方便维护。下一篇我们就来解决这个问题。
这篇文章的源代码在SeleniumExcelDataDrivenFrame3项目里边。