上回我们介绍了一些常见的网页元素,从这篇文章开始咱们就聊聊对于这些元素的操作。讲之前先把测试环境搭一下。上节课说过,selenium web driver其实就是个类库,它也是以jar包的形式存在,打开selenium官网,找到这两个小东西:
一个叫selenium standalone server,一个叫selenium client。前者是1.0时代selenium RC为了让程序和浏览器之间交互而使用的服务器,现在大多数人已经使用2.0了,所以这个可以不用下载,只需要下载selenium client里面的jar包就行了。
下载完我们新建一个叫SeleniumDriver的java项目 -> 添加com.test包 -> Test.java,带上main函数:
然后通过build path -> configure build path -> libraries -> Add External jars把下载的jar都加进去:
先说驱动,我们又叫driver。之所以先说driver,是因为它是整个selenium自动化的核心之一,创建driver也是写测试程序时最先要做的。上次咱们把浏览器比喻成selenium的车,而把driver比喻成selenium的司机,对于车来说,主流的浏览器有IE,chrome和firefox三个,那么对应我们也得有三种driver,就好比大部分人只能开小轿车,你不能让他开火车或是公交车,容易出车祸。司机一定要跟车对应,driver类型一定要跟浏览器对应。访问selenium官网,我们可以看到有一些类似“xxdriver”这种字样的东西,它们就是不同浏览器的driver,我们只需要下载给IE,chrome和firefox准备的就好:
你把driver拿来之后是要告诉你自己的电脑的,因为司机再牛也得有公司雇他才行呀,否则你开谁的车呀?你的操作系统就相当于是它的公司。在自动化的世界里驱动可以作为系统的一个属性存在,只要系统把它添加到属性之中,就相当于添加到公司里了,语法是
System是java里的一个类,setProperty是它的静态方法。先以chrome为例,对于我的电脑来说就是:
driver的位置因人而异,但只要是用chrome,那driver类型一定要写成webdriver.chrome.driver,也不难记。
司机加入公司之后就可以正式上岗了,我们先创建一个driver对象,就好比司机已经是待命状态:
司机已经准备好了,下面就该准备车了。再强调一遍,driver类型必须要跟浏览器一致,既然是Chrome的驱动,那就只能用Chrome浏览器。虽然谷歌在咱们国家被禁,但在国内下载Chrome的网站应该还是一大把,找个靠谱网站下载下来安装好。
车夫跟车都准备完了这才差不多了搭好了测试环境。折腾了这么久终于该开始正题了 --- driver的操作。driver有八种最常见的操作方式,也就是说创建出来的driver对象有八个最常见的方法。你在eclipse里查一下咱们刚创建的driver对象的方法,可以看到有很多:
第一个常见方法是get(String url),里面有一个代表网址的字符串参数,这句代码表示打开哪个网站进行测试。咱们用我给大家准备的[示例网页]((http://cslm-test.com/webapps/elements/webelements.html),这是我为了演示咱们这个教程里的事例专门给大家搭建的测试网站:
如果现在运行程序,那大家会看到这个网页打开了。我们通常就是用这个方法打开被测网站。
第二个常见方法是getTitle(),里面不加任何参数,返回的是当前被测网页的标题,也就是在顶端选项卡上写的字。我们也可以用System.out.println()在后台打印出来:
第三个方法是getCurrentUrl(),返回的是当前被测网站的网址:
第四个方法是getPageSource(),这个方法返回当前页面的源代码,也就是它的html,css或javascript之类的东西,我们有时候会在网页上鼠标右键 -> 查看网页源代码,效果是一样的:
上面四个方法一起执行,会一一对应打印出各种信息,没毛病。但我们发现网页并不是全屏的,看起来不爽。第五个方法就能解决这个问题:连续调用manage().window().maximize()可以使浏览器全屏:
再运行一遍,我们发现还是不爽。为什么?每次运行完浏览器都开着,运行两遍也就是开两个页面,你得自己手动给它关上。运行个十次八次的每次都自己关实在太麻烦了。所以第六个方法close()就是用来自动关闭浏览器的:
再运行一遍整个程序,我们发现只有最后一遍运行打开的页面被关闭了,其它用chrome打开的页面并没有被关闭。注意,close()方法只关闭在自动化运行时打开的并且正在控制的网页。这句话有点拗口,但理解起来不难。两个要求:首先,它只关闭在自动化运行时打开的网页,你自己双击电脑桌面上chrome浏览器图标然后手动敲入网址打开的不算数,得人家selenium打开的才行。这也没毛病,人家selenium公司的驱动老司机只能管到它自己打开的东西,管不到你打开的。第二,得是正在控制的网页,就一个。如果selenium在运行过程中打开了两个网页,那只会关一个。比如咱们在这段程序里再加一句代码用来在新窗口显示链接内容:
现在不理解这句话的朋友先别着急,后面说元素操作的时候都会详细讲,现在只要知道它是用来点击一个链接,并且链接内容在新窗口里出现就好。这里我让它打开新窗口并跳转到百度。后面Thread.sleep(5000)代表driver会停留5秒钟,介绍线程那篇我们也讨论过。Thread经常会用到,因为网页跳转需要时间,而且根据你家网速不同需要的时间也不同。但是,当你的网页跳转的时候程序并不知道,它还是会继续执行,不加停留时间的话会直接运行到driver.close(),这样很有可能driver和网页都关了可你新窗口的内容还没显示出来呢。这个例子比较简单,后边没操作了,关了就关了没关系。但如果后面还需要你在新窗口做些操作那就肯定fail了。这里有一个专门的概念叫“异步处理”,不同步的时候就得等等,咱们后面会大量使用,我也会详细讲。
我们发现运行完毕只有webelement.html网页关上了,百度的没关。因为虽然链接跳转,但driver当前控制的还是第一个网页。那要全关上呢?这就需要第七个方法:quit()。把close()改成quit()再执行,这下全关上了,不留痕迹:
做项目时具体问题具体分析,看是用close()还是quit()。有人说你不是说quit()会全关上么?那讲close()方法之前打开的那些网页呢?不也是自动化打开的么?咋还需要手动关呢?是这样,每一次程序执行完毕的时候,driver就算是完成了它的生命周期,或者叫做完成了它当前的会话(session),不管你写不写close()或是quit(),driver都会被强行干掉,老司机都得下班。再运行一遍程序时,new ChromeDriver()又会产生了一个新的driver对象,而新的对象无法关闭上一个生命周期遗留下来的浏览器。就好比昨天司机有个单子没接,今天还能再接相同的单子么?不能。同理,如果你用了close()或是quit(),后面再想用get(),getCurrentUrl(),getPageSource()都会报错,因为生命周期结束,司机下班了:
quit()之后你再想打开网页,对不起报错了,说你的会话已经失效了,你得重新再实例化一个driver对象。
driver的最后一个常用方法我们留到说网页元素操作的时候再介绍,此方法用来定位网页元素,非常重要。此外,需要注意的是,selenium是个开源的网站,但维护得还不错。但正是因为开源,里面常有浏览器和驱动兼容性问题的出现,也就是说司机跟车不兼容。经常上selenium官网的朋友会发现驱动会经常更新。如果你运行不成功,但排错又发现真没什么问题,那就要往兼容性上去想。有时候同一段代码,之前运行没问题,但过几个月发现不行了,中间什么都没改。仔细一查,发现电脑重启的时候浏览器升级了,跟原来的驱动不匹配了。你自己要是不知道兼容性这么一回事就慢慢调试吧,反正出不来。所以查询错误信息很重要。你可以把错误信息复制粘贴到百度上,很可能有人跟你一样遇到过这个问题。我推荐过一个叫stackoverflow的网站,就是专门是解决各种各样问题的一个论坛,虽然都是英文,但读起来应该不费劲,就当学英语了。
这篇只介绍了chrome driver的操作,下次说firefox和IE的。源代码是SeleniumDriverChrome项目。
本篇知识点及注意事项:
1. 自动化测试代码的执行需要驱动(driver)和浏览器共同配合完成。
2. driver的常用操作有打开浏览器、获取网页标题、源代码、定位元素等操作。