上一篇文章介绍了断言,这篇介绍数据源和数据驱动。讲之前先打开示例网页index.php,应该看到一个登录页面。这是我模拟人力资源系统写的小网站,虽然页面比较简(chou)单(lou),但已经能满足我们的需求。这是我以前给国外的朋友培训时用的示例网站,所以是英文的,不过单词都比较简单。我们就用这个系统来讲参数化的概念。
先简单浏览一下这个网页。首先,你可以用下列其中任何一个员工代号和密码组合成功登录:
1)员工代号:1001,密码:123
2)员工代号:1002,密码:456
3)员工代号:1003,密码:789
登录成功后会自动跳转到home页,home页上有一个员工头像,一句欢迎词,和一个退出按钮:
当然,这仨员工没一个头像是我的。点击退出按钮会回到登录页。
现在我设计一个test case,让这三个员工挨个登录退出,每一次验证是否登录成功。步骤如下:
1. 登录http://www.cslm-test.com/hrsystem/index.php;
2. 输入员工代号和密码;
3. 点击登录按钮(断言点:home按钮的文本为home);
4. 退出(断言点:登录按钮出现在index.php页)。
按现有的知识水平我们只能把test case写3遍,每次用不同的员工代号/密码组合。现在测试数据只有3条,比较少,可如果要是30条呢?100条呢?把test case写100遍显然不是个好方法,所以我们需要把员工信息参数化,让每个员工的代号和密码作为参数传入我们的测试程序。这样还是用同一段代码,同一段执行过程,只是每次需要的测试数据不同而已。说白了就是把数据和代码分开,把数据单独放到一个数据源中:
一个测试系统,或者说框架,可以根据不同模块有很多个数据源,比如一个外贸站,有登录、商品目录、购物车这几个模块,相应的都有自己的数据源。数据源有多种表现形式,放在内存中可以是数组,可以是List,放在硬盘里的可以是文件,还可以是数据库:
先说内存的,说白了也就是直接把数据源写到程序里。它的好处就是数据源会通过程序加载自动生成,比如说用数组,程序编译时创建数组,然后就会创建数据源,毕竟它是程序的一部分嘛。简单演示一下,既然同时有员工代号和密码两个数据,那我们可以声明一个二维数组来存:
先上代码再解释:
第13行到17行是准备工作,声明driver打开网页。然后就是第20行创建数据源。接着我们通过for循环来执行登录过程的test case。arr_testdata[行数][0]取出的是用户名,arr_testdata[行数][1]取出的是密码,每次循环都使用不同的参数。这个测试程序中有两个断言点,一个在44行,一个在54行,都是用findElements配合size()先检查该控件是否存在,再判断字符串是否相等或是显示不显示。这一点在之前的文章中我们说了很多遍了,如果有疑问的朋友请看文本操作那篇。有人说这个例子用得着这么吹毛求疵吗?尤其是第二个断言,你既然登录已经都成功了,那就必然点击过登录按钮了,那退出的时候回到登录页面必然有这个按钮呀?没错,是有点过于小心了,但在实际的项目中谁能保证你退出的时候一定回到登录页呢?万一网站出bug了呢?又得一堆异常抛出来。
执行一下测试通过:
这就是用数组来当数据源的一个演示,程序编译执行时才会创建数据源。List也一样,你既然可以把测试数据存在数组里,当然也就可以存在集合里。不过这种把数据源直接写程序里的做法已经不多了,一是有时数据量大不好管理,二是有可能同一数据集被多个test case使用,每个test case中都要写一遍很麻烦。所以,测试界往往还是习惯于把数据源单独放在硬盘上,其中最常用的媒介就是文件。用文件存放的好处是既可以存大量数据,又省时省力。很多测试员都喜欢用Excel存放数据源,其实用Excel/csv/txt/xml都可以,这篇我就用Excel给大家演示一下。之前介绍java文件流的时候详细说过Excel的操作,忘了的朋友请务必先复习一下。
现在开始演示。打开Eclipse,新建项目SeleniumDataDrivenExcel –> 包com.test,加入selenium jar包。注意,讲Excel读写时我们用的是一个叫POI的jar包来提供Excel的API操作,现在继续使用,把它也加进来。然后建一个Excel测试文件存储数据源,我就用最新的.xlsx格式吧,再把员工代码密码按照下面格式填进去,把下面的sheet名称改成“LoginDetails”:
注意,把每个员工代码和密码前面都加一个单引号变成文本格式,格上就会带一个小绿三角。这么做是因为登录时需要的是字符串,如果你的格式是数字到后边还得转换,不转换就会报类型不匹配的错。最后保存文件,文件名叫Login.xlsx。
项目结构如下:
用文件存数据源这种方式无非就是多一步,首先得把数据从文件中读出来,读出来后边就都一样了,再放入测试程序执行。先做第一步,根据Excel POI每次读一行,并且可以得到行中每一个格中数值的特点:
按上图的样子,我觉得还是可以用一个二维数组来存,一行是一条数据,每一条数据有两列。我声明的二维数组叫arr_testdata。但是,这个二维数组一开始我只知道应该是两列,但行数我并不知道。有人说这文件里总共就四行,不算表头就三行数据,声明三行就行了。那问题是如果我以后再往数据源文件里添加数据呢?到时候就该数组越界了。所以,不要把数据源的大小写死,让程序自动计算。接着我们可以通过一个for循环从文件中把数据一行一行读到arr_testdata中。最后所有的测试数据都存在了二维数组arr_testdata中,和之前演示的用数组的方式一样,通过遍历来执行登录过程的test case。
按照这个思路,完整程序如下:
第45行变量rowCount就是经过计算的数据行数,也就是不算第一行表头"EmpCode|Password"的所有行数,这个例子中也就是3行。这样,不管你以后怎么添加数据,执行程序时都会在第48行动态计算数组大小,也就不怕数组越界了。数据源中每一行的0号位置是用户名,1号位置是密码。注意,真正的数据是从第二行开始到第四行结束,第一行是表头,不管它。所以第51行for循环的初值为1,终值为总行数。第57行arr_testdata[行数][0]取出的是用户名,arr_testdata[行数][1]取出的是密码,每次循环都使用不同的参数。最后第68行别忘了关闭文件流。从文件中读出来后剩下的步骤就不再解释了,和上面数组的一样。
有时间你还可以用csv/txt/xml之类的文件放数据,如果你不嫌麻烦还可以用数据库,数据库用的比较少,比较麻烦没必要。总之,用什么媒介无所谓,只要能保证可以访问就行。外部数据源与测试系统交互这个过程又可以称为数据驱动(Data Driven Testing)。通过数据驱动,测试系统本身不再承载任何数据,所有的测试都在动态发生。下一篇我们继续对这个测试程序进行改进,让它扩展性更强。
这篇文章的源代码在SeleniumExcelDataDriven项目里边。
本篇知识点及注意事项:
1.数据驱动就是把数据和代码分开,把数据单独放到一个数据源中的过程。媒介中以文件(Excel/csv/xml/txt)最常用。
2.数据驱动使得测试系统动态接收数据完成test case的执行。
网友评论