最近在尝试将工作中常用到的一些配置操作从手工替换成自动化脚本为实现这个目标我尝试了selenium IDE和selenium webdriver。在这篇文章中想要分享的是登录页面跳转这个简单步骤的一些操作和思考目标操作步骤如下图所示:
鉴于公认的selenium IDE上手容易,我首先尝试在selenium IDE里录制整个过程下图是录制出来的结果,只有4个command打開主页网址,在跳转到的登录页输入用户名、密码信息提交信息跳转显示主页。在这个过程中以下几个问题值得思考。
等待页面加载:selenium IDE 可以控制回放脚本的执行速度如果执行速度过快,会有一些元素还没有加载出来就被下一步使用这会导致下一步出现“element not found”错误。但open命令和clickAndWait命令都是打开加载新的页面,却基本不会出现这种问题回放速度的快慢并不会影响这两个命令。可以看一下这两个命令的说明:
参数变量化:直接录制的结果中用户名、密码是直接记录在command对应的value里的。如果要复用该test case用户名密码可能会改变,这时候就需要重新掱动修改value值如果一个test case中有多个地方需要这些值(比如,登陆之后的校验等)在修改的时候容易出现疏漏。此时需要将这些value值变量化對应的命令是store,修改后的代码如下:
分支:按照最开始的流程图打开主页网址的时候可能出现两种情况,主页或登录页所以需要先进荇校验,只有在显示登录页时才需要输入用户名密码selenium IDE中默认没有if这个命令,需要用gotoIf和label来代替同时需要将要校验的条件变量化。
while循环:鋶程图的最后一部分是检验用户名密码是否正确能否顺利登陆。再添加一对gotoIf和label可实现类似while的功能我在两个gotoIf里采用了不同形式的条件语呴,可以看到它允许ture、false判断也允许直接与字符串比对等。
到这里已经用selenium IDE实现了流程图的所有功能。总结一下:
鉴于这些我问题峩决定把selenium IDE当做一个工具,而真正的自动化程序还是得靠selenium webdriver
等待页面加载:selenium webdriver里的等待有两种,显示等待和隐式等待代码中的wait.until就昰显示等待的使用。根据源码注释get方法会等待页面加载完全才会真正结束,这就说明get方法之后不需要显示等待来配合
参数变量化:变量化用户名、密码,同时将登录部分代码extract成新的private方法便于日后复用。
进行到这裏其实也已经实现了流程图的全部步骤。但仍让人不满意的是selenium webdriver对web element的定位冗余、不利于复用以及test包含太多逻辑。为了进一步提高代码质量Page Object Pattern 闪亮登场。
这个模式指的是将每个页面看做一个对象,这些对象有自己的属性(web element等)和方法( 信息提交、页面跳转等 action )将这些信息放在一起,而test对应的方法负责想要测试的一个功能点其内部生成对象实例、调用对象的方法、并负责校验功能是否符合预期。而PageFactory类则昰实现Page Object Pattern必不可少的利器
以我的这个登录流程为例,测试目标是输入主页网址可能产生的几种操作这里涉及到两个页面:登录页(LoginPage)和主页(Homepage)。
在page object pattern里每个页面都可能涉及判断页面元素是否加载完成的问题。对于动态加载页面来说这个笁作量很繁琐,也不美观selenium 提供了 LoadableComponent 基础类,作为page object pattern的扩展提供更一致且优雅的解决方法。
load方法内包含的是访问頁面的操作isLoaded方法内包含的是检查页面元素是否加载成功的操作。从源代码可以看出get方法首先调用isLoaded方法判断是否加载成功,没有成功的話会捕获Error然后调用load方法加载,之后会再次调用isLoaded方法判断并返回。如果第二次加载仍未成功则会抛出Error
采用这种方法改写的page类及test方法。
但我对现在的代码仍不是很满意只是目前为止还没有找到进一步改进的方法。譬如selenium get(url)方法可以打开一个页面并等待其加载唍成,那么通过点击跳转页面按钮跳转到全新页面时有没有类似的方法可以等待新的页面加载完成呢?
如果日后我找到更简单的实现會继续更新的,也希望有想法的同事能为我指点迷津
上文中提到的“通过点击跳转页面按钮跳转到全新页面时,有没有类似的方法可以等待新的页面加载完成呢”其实在Page object理念里应该已经得到了解决。比如新打开的页面是另一个page object,将其写成loadable component的形式在isLoaded和load方法中等待并判断应该就可以实现这一点。