任何建议进行测试过测试码在一浏览器,优选用硒?
-
01-07-2019 - |
题
我们已经在使用硒取得了巨大成功处理高级网站测试(除了广泛的蟒蛇文档测试在一个模块的水平)。但是现在我们正在使用过测试了很多页及其证明难以纳入硒测试的复杂的部件,如电网。
有没有人有成功的编写自动化测试的过测试的基于网页吗?很多google搜索发现人们有类似问题,但几个答案。谢谢!
解决方案
最大的障碍在过测试测试与硒是,过测试并不呈现的标准HTML元素和硒IDE会天真地(和正当)产生的命令针对的元素,只是作为装饰--是多余的因素,帮助过测试与全面的外观和感觉。这里有一些技巧和技巧,我们聚集在编写自动化的硒测试对一个过测试的应用程序。
一般技巧
定位元素
当硒发生的测试案例的记录用户的行动有硒IDE上的火狐,硒会的基本记录的操作标识HTML要素。然而,对于大多数可点击的元素,过测试使用产生的id like"ext-gen-345"这很可能改变的一个后续访问,以同一页上,甚至如果没有代码已经作了修改。后记录用户的操作为一个测试,我们需要一个手动努力通过所有这些行动,取决于所产生的身份证和替换他们。有两种类型的替代品,可以制成:
换一个Id定位器与CSS或XPath定位器
CSS定位器,开始与"css="和XPath定位器开始使用"//"(该"xpath="前缀是任意的)。CSS定位器也不太详细和更容易阅读,并应优先XPath定位器。然而,在有些情况下XPath定位器需要被使用,因为CSS定位器根本不能削减。
执行JavaScript
一些要素需要超过简单的小鼠/键盘的相互作用由于复杂呈现进行过测试。例如,Ext.形式。CombBox是不是真的 <select>
元,但一个文本输入与一个独立的下列表中的某处在底部的文件树。为了正确地模拟一个组合框选择,这是可能的第一个模拟击下拉箭,然后点击在名单上出现。但是,将这些元素通过CSS或XPath定位器可能比较麻烦。一个选择是找到ComoBox部件本身并呼吁的方法,对它来模拟的选择:
var combo = Ext.getCmp('genderComboBox'); // returns the ComboBox components
combo.setValue('female'); // set the value
combo.fireEvent('select'); // because setValue() doesn't trigger the event
硒的 runScript
命令可用于执行上述操作更加简明的形式:
with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
应对阿贾克斯和缓慢的呈现
硒具有"*AndWait"口味的所有命令在等待页载荷时用户的行动的结果页面转换或重新加载。然而,由于阿贾克斯取不涉及实际页载荷的,这些命令不能用于同步。该方案是以使用的视线索喜欢的存在/缺乏的AJAX进展指标或外观的行网、其他组件的链接等。例如:
Command: waitForElementNotPresent
Target: css=div:contains('Loading...')
有时候,一个元件将只出现在一定量的时间,这取决于如何快速的过测试呈件后,用户的行动结果在图改变。而不是使用任意延误的 pause
命令,理想的方法是等到感兴趣的元素在我们的掌握。例如,点击一个项目之后等待着它出现:
Command: waitForElementPresent
Target: css=span:contains('Do the funky thing')
Command: click
Target: css=span:contains('Do the funky thing')
依靠任意的暂停并不是一个好主意,由于时间性差异,结果运行的试验在不同的浏览器或在不同的机会做试验的情况下片状。
不可点击的项目
一些要素不能被触发 click
命令。这是因为活动监听器实际上是在容器上,看着老鼠的事件,在其孩子的元素,这最终泡到父母。卡控制是一个例子。来击一个标签,你要模拟 mouseDown
事件在标签:
Command: mouseDownAt
Target: css=.x-tab-strip-text:contains('Options')
Value: 0,0
实地验证
形成的领域(Ext.形式。* 组件)就有关经常表达或vtypes为验证将触发的验证有一定的延迟(见的 validationDelay
财产被设定为250毫秒默认情况下),之后用户进入文本或即时的现场失去焦点--或模糊(见的 validateOnDelay
财产)。为了扳机场验证之后颁发的类型硒命令进入一些文本内的一个领域,你必须做到以下:
触发延迟验证
过测试火灾验证延时当场收到候,把事件。触发这种计时器,只需问题的一个虚拟的候,把事件(不管其关键用作过测试忽略的话),随后通过一个短暂停就长于validationDelay:
Command: keyUp Target: someTextArea Value: x Command: pause Target: 500
立即触发的验证
你可以注入一个模糊的事件进入该领域触发立即验证:
Command: runScript Target: someComponent.nameTextField.fireEvent("blur")
检查验证结果
下面的验证,你可以检查存在或不存在的错误的领域:
Command: verifyElementNotPresent
Target: //*[@id="nameTextField"]/../*[@class="x-form-invalid-msg" and not(contains(@style, "display: none"))]
Command: verifyElementPresent
Target: //*[@id="nameTextField"]/../*[@class="x-form-invalid-msg" and not(contains(@style, "display: none"))]
注意到,"显示:没有"检查是必要的,因为一旦一个错误的场所示,然后需要将它隐藏的,过测试将仅仅隐藏的错误的领域,而不是完全消除它从DOM树。
元素特定的技巧
击Ext.形式。按钮
备选案文1
命令:点击 目标:css=按钮:包含('节省')
选择按钮通过其标题
备选案文2
命令:点击 目标:css=#拯救选项的选择按钮
选择按钮通过其id
选择一个价值从一个Ext.形式。组合框
Command: runScript
Target: with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
第一套价值,然后明确火灾的选择事件的情况下有观察员。
其他提示
我一直用selenium测试我的ExtJs Web应用程序。其中一个最大的问题是在网格中选择一个项目以便用它做点什么。
为此,我编写了辅助方法(在SeleniumExtJsUtils类中,它是一组有用的方法,可以更容易地与ExtJs交互):
/**
* Javascript needed to execute in order to select row in the grid
*
* @param gridId Grid id
* @param rowIndex Index of the row to select
* @return Javascript to select row
*/
public static String selectGridRow(String gridId, int rowIndex) {
return "Ext.getCmp('" + gridId + "').getSelectionModel().selectRow(" + rowIndex + ", true)";
}
当我需要选择一行时,我只需要打电话:
selenium.runScript( SeleniumExtJsUtils.selectGridRow("<myGridId>", 5) );
为了实现这个目的,我需要在网格上设置我的id,而不是让ExtJs自己生成它。
要检测该元素是否可见,请使用以下子句:
not(contains(@style, "display: none")
最好使用它:
visible_clause = "not(ancestor::*[contains(@style,'display: none')" +
" or contains(@style, 'visibility: hidden') " +
" or contains(@class,'x-hide-display')])"
hidden_clause = "parent::*[contains(@style,'display: none')" +
" or contains(@style, 'visibility: hidden')" +
" or contains(@class,'x-hide-display')]"
您能否更深入地了解使用extjs测试时遇到的问题类型?
我觉得有用的一个Selenium扩展名是 waitForCondition 。如果您的问题似乎是Ajax事件的问题,您可以使用waitForCondition等待事件发生。
Ext JS网页可能很难测试,因为它们最终会像Ext JS网格一样生成复杂的HTML。
HTML5机器人通过使用一系列有关如何基于属性可靠地查找和交互组件的最佳实践来解决此问题和非动态的条件。然后,它提供了与您需要与之交互的所有HTML,Ext JS和Sencha Touch组件执行此操作的快捷方式。它有两种口味:
- Java - 熟悉基于Selenium和JUnit的API,内置了对所有现代浏览器的Web驱动程序支持。
- Gwen - 一种人性化的语言,可快速轻松地创建和维护浏览器测试,并附带自己的集成开发环境。所有这些都基于Java API。 醇>
例如,如果您想要找到包含文本<!>“Foo <!>”的Ext JS网格行,您可以在Java中执行以下操作:
findExtJsGridRow("Foo");
...你可以在Gwen中做以下事情:
extjsgridrow by text "Foo"
Java 和Gwen有很多关于如何工作的文档使用Ext JS特定组件。该文档还详细说明了所有这些Ext JS组件的结果HTML,您也可能会发现它们很有用。
通过网页上的网格ID获取网格的有用提示: 我认为你可以从这个API扩展更多有用的功能。
sub get_grid_row {
my ($browser, $grid, $row) = @_;
my $script = "var doc = this.browserbot.getCurrentWindow().document;\n" .
"var grid = doc.getElementById('$grid');\n" .
"var table = grid.getElementsByTagName('table');\n" .
"var result = '';\n" .
"var row = 0;\n" .
"for (var i = 0; i < table.length; i++) {\n" .
" if (table[i].className == 'x-grid3-row-table') {\n".
" row++;\n" .
" if (row == $row) {\n" .
" var cols_len = table[i].rows[0].cells.length;\n" .
" for (var j = 0; j < cols_len; j++) {\n" .
" var cell = table[i].rows[0].cells[j];\n" .
" if (result.length == 0) {\n" .
" result = getText(cell);\n" .
" } else { \n" .
" result += '|' + getText(cell);\n" .
" }\n" .
" }\n" .
" }\n" .
" }\n" .
"}\n" .
"result;\n";
my $result = $browser->get_eval($script);
my @res = split('\|', $result);
return @res;
}
通过自定义HTML数据属性轻松测试
来自 Sencha文档:
当没有对象引用可用时,itemId可用作获取组件引用的替代方法。不要使用带有Ext.getCmp的id,而是使用带有Ext.container.Container.getComponent的itemId,它将检索itemId或id。由于itemId是容器内部MixedCollection的索引,因此itemId在本地作用于容器 - 避免与需要唯一ID的Ext.ComponentManager发生潜在冲突。
重写Ext.AbstractComponent
的onBoxReady
方法,我将自定义数据属性(其名称来自我的每个组件的自定义testIdAttr
属性)设置为组件的itemId
值(如果存在)。将Testing.overrides.AbstractComponent
类添加到application.js
文件的requires
数组中。
/**
* Overrides the Ext.AbstracComponent's onBoxReady
* method to add custom data attributes to the
* component's dom structure.
*
* @author Brian Wendt
*/
Ext.define('Testing.overrides.AbstractComponent', {
override: 'Ext.AbstractComponent',
onBoxReady: function () {
var me = this,
el = me.getEl();
if (el && el.dom && me.itemId) {
el.dom.setAttribute(me.testIdAttr || 'data-selenium-id', me.itemId);
}
me.callOverridden(arguments);
}
});
此方法为开发人员提供了一种在代码中重用描述性标识符的方法,并在每次呈现页面时使这些标识符可用。不再搜索非描述性的,动态生成的ID。
我们正在开发一个使用selenium并遇到extjs问题的测试框架(因为它是客户端渲染)。我发现在DOM准备就绪后查找元素很有用。
public static boolean waitUntilDOMIsReady(WebDriver driver) {
def maxSeconds = DEFAULT_WAIT_SECONDS * 10
for (count in 1..maxSeconds) {
Thread.sleep(100)
def ready = isDOMReady(driver);
if (ready) {
break;
}
}
}
public static boolean isDOMReady(WebDriver driver){
return driver.executeScript("return document.readyState");
}
对于非正式HTML的复杂UI,xPath始终是您可以依赖的东西,但对于使用ExtJ的不同UI实现而言有点复杂。
你可以使用Firebug和Firexpath作为firefox扩展来测试某个元素的xpath,并简单地将完整的xpath作为参数传递给selenium。
例如在java代码中:
String fullXpath = "xpath=//div[@id='mainDiv']//div[contains(@class,'x-grid-row')]//table/tbody/tr[1]/td[1]//button"
selenium.click(fullXpath);
当我使用WebDriver测试ExtJS应用程序时,我使用了下一种方法:我按标签的文本查找字段,并从标签获取@for
属性。例如,我们有一个标签
<label id="dynamic_id_label" class="TextboxLabel" for="textField_which_I_am_lloking_for">
Name Of Needed Label
<label/>
我们需要为WebDriver指点一些输入://input[@id=(//label[contains(text(),'Name Of Needed Label')]/@for)]
。
因此,它将从<=>属性中选择id并进一步使用它。这可能是最简单的情况,但它为您提供了定位元素的方法。当你没有标签时会更难,但是你需要找到一些元素并编写你的xpath来寻找兄弟姐妹,下降/提升元素。