具体实现中出现的问题:
将录制的脚本转成PHPUNIT在服务器端运行总失败。
开始要作如下工作:
1.在setUp()函数中添加语句:每次脚本运行,都将清空数据库的语句
`/home/www/selenium-php/yuezhan/rebuilddb.sh`;注意:用倒斜杠,数字1左边的键
//根据项目需要而修改;
2. 将默认的浏览器代码修改:
将$this->setBrowser("*chrome");
改成$this->setBrowser("*firefox");
可以不用修改代码的方法:
Selenium工具àOptionsàOptionsà选择Formats选项卡à
选择PHP-PHPUNITà将Environment里的浏览器改成firefox即可,
这样子录制的脚本转化成PHP后,也就不用修改此部分代码了。
3.在第2点的基础上,在上面添加两句代码:
$this->setHost("192.168.8.24");
$this->setPort(4445); //此句可以不加,根据自己服务器端口而定
4.录制的脚本中如有上传图片的路径。
也要根据服务器所在的环境作修改。如在同一环境下可不作修改。不在同一环境下,要将图片路径修改成服务器环境中图片所在的路径下。
5.录制的脚本一定要从登录开始录制。在没有解决COOIKE之前,必须这么做。
运行脚本时,
常见问题1:报错:ERROR: There was an unexpected Alert! [ajax错误].
错误原因:AJAX错误,没有找到ALERT提示的框架,因而报异常错误
解决方法一:$this->click("css=input[type=submit]");这是一个“下一步”按钮。
进入的页面中,有AJAX。
可以此句前面添加:setSpeed(1000)让其执行速度变慢1秒。
具体php代码:
$this->setSpeed("1000") //从下一句开始,执行速度放慢
$this->click("css=input[type=submit]");
$this->waitForPageToLoad("30000");
$this->type("name=player[player1][name]", "元一");
$this->setSpeed("0") //恢复到正常执行速度
根本的解决方法:
$this->waitForCondition("selenium.browserbot.getUserWindow().jQuery.active == 0", "3000"); //此处3000,即限定的超时时间timeout。
$this->click("css=input[type=submit]");
解释waitForCondition用法:
waitForCondition(JavaScriptSnippet,time)
-在限定时间内,等待一段JavaScript.代码返回true值,超时则停止等待
其中"selenium.browserbot.getUserWindow().jQuery.active == 0"这是一段javascript语句,
意思:检查得到的窗体里AJAX的活动数量为0时,则为0即无AJAX活动了,则为真,为真就可以继续向下运行。反之,在限定的timeout 3秒时间内,活动数仍不为0,则会报错。
常见的框架:
jQuery : “jQuery.active”
Prototype: “Ajax.activeRequestCount”
Dojo : “dojo.io.XMLHTTPTransport.inFlight.length
我们用的是jQuery框架,即写成jQuery.actiive
3000是限时3秒。
不正确的解决方法:
for ($second = 0; ; $second++) {
if ($second >= 60) $this->fail("timeout");
try {
if ($this->isElementPresent("css=input[type=submit]")) break;
} catch (Exception $e) {}
sleep(1);
}
此处用的方法:waitForElementPresent(locator,variableName)验证指定元素在页面上。
此方法解决AJAX错误时无效。其检验元素的方法,可解决javascript的问题。常见问题4中会详解。
常见问题2:服务器连接不上。
解决方法:目前我们服务器上同时只能边接两台机器。所以,这儿的解决方法,只能限于两台哦。
常见问题3:超时timeout
错误原因:在服务器上跑,页面加载时间有时会变的慢
解决方法一:页面加载时间修改一下。延长页面加载时间
原语句: $this->waitForPageToLoad("30000");
可更改为:$this->waitForPageToLoad("60000");
解决方法二:将运行速度放慢,在页面加载时间前一句加如下语句
$this->setSpeed("1000") //运行速度放慢
当然,页面加载完之后,可以提交接钮语句之后,加如下语句,将运行速度恢复到正常。
$this->setSpeed("0") //恢复到正常执行速度
常见问题4:登录时,没有发现某个元素。[error] Element id=username not found
如,我们虎扑网站,当前状态为未登录。先点击进入论坛页面。然后点击“登录”,
录制的脚本,在回放中,会错误。没有该元素。
例如录制脚本:
Comand Target Value
open /
click link=登录
type id=username admin
type id=password admin
………………
clickAndWait link=退出
转成PHPUNIT后代码为:
$this->open("/");
$this->click("link=登录");
$this->type("id=username", "admin");
$this->type("id=password", "admin");
…………
$this->click("link=退出");
回放时,到了用户名那一句,就会报无法找到元素的错误。
错误原因:登录时,会弹跳出一个登录对话框。此对话框即是Javascript语句写的。
解决方法:用waitForElementPresent 方法,其方法是检查页面上的元素是否存在。
登录之后的语句,都是JAVASCRIPT语句执行之后出现的。建议检验最后一个可输入元素。
例如录制脚本:
Comand Target Value
open /
click link=登录
waitForElementPresent id=password //此句为添加的辅助代码,检查元素
type id=username adminuser
type id=password adminpwd
………………
clickAndWait link=退出
转成PHPUNIT后代码为:
$this->open("/");
$this->click("link=登录");
for ($second = 0; ; $second++) {
if ($second >= 60) $this->fail("timeout"); //超过60秒,则报超时错误
try {
if ($this->isElementPresent("id=password")) break; //检查用户名这个元素
} catch (Exception $e) {}
sleep(1);
}
$this->type("id=username", "adminuser");
$this->type("id=password", "adminpwd");
…………
$this->click("link=退出");
上述中selenium中的waitForElementPresent id=password这一句,转化成PHPUNIT代码后,即是for循环代码那一段。
在PHPUNIT中也可以直接添加该段代码。且完全可以将for循环代码这一段替换成:
$this->waitForElementPresent("id=password");
这样单独的一句。完全可以只写这一句,也可以达到检查这个元素的效果。
解释waitForElementPresent用法:
waitForElementPresent(locator)等待指定元素出现在页面上。
常见问题5:录制时必须从登录开始录制,那么有没有什么办法可以解决呢。
解决方法:如下PHPUNIT代码:
<?php
`/home/www/selenium-php/yuezhan/rebuilddb.sh`; //数据库初始化
class HCYZ_LoginTest extends PHPUnit_Extensions_SeleniumTestCase
{
private static $YZLoginCookie; //定义了一个私有的静态变量,变量名为YZLoginCookie
protected function setUp()
{
$this->setHost("192.168.8.24");
$this->setPort(4445);
$this->setBrowser("*firefox");
$this->setBrowserUrl("http://kangying.yuezhanerqi.test.hc.sf/");
}
public function testLogin() //这个类就是测试登录。
{
$this->open("backend_test.php/om_match"); //打开后台URL
$this->type("name=backend_user[username]", "康莹");
$this->type("name=backend_user[password]", "kangying");
$this->click("css=input.button");
$this->waitForPageToLoad("30000");
self::$YZLoginCookie = $this->getCookieByName("symfony"); //下面详细解释。
}
public function testOmMatch() //这个类就是测试约战二期的。
{
$this->open("backend_test.php/om_match"); //要注意这儿要先打开约战二期的URL
$this->createCookie("symfony=".self::$YZLoginCookie, "path=/"); //下面详细解释
$this->open("backend_test.php/om_match"); //注意,创建完COOKIE要再打开下URL
}
}
解释下面两句:
1. self::$YZLoginCookie = $this->getCookieByName("symfony");
Symfony