geb 查找模块对象属性与使用选择器的性能问题
Performance issue with geb lookup on module object attributes vs. using selectors
问题描述
我正在编写一个 geb/spock 规范,它将测试数据从 DB2 提取到映射中(映射变量称为“preFilledFields” - 请参阅“MySpec" class 再往下)。
然后迭代此地图,对于每次迭代,我也会检查该值是否与页面上的一行中的值匹配。
当我执行上述访问模块对象属性的断言时,每个断言的平均执行时间约为。 5-6 秒。如果我直接使用选择器执行断言,那么每个断言的平均执行时间约为。 70-80 毫秒。有关断言的更多详细信息,请参阅“MyPage”class。
有谁知道这可能是什么原因造成的?性能不佳是我的代码造成的,还是在 geb 中使用模块时存在性能方面的普遍问题?
感谢我能得到的任何帮助和意见。
代码:
我的 "RowModule" class 看起来像这样:
class RowModule extends Module {
static final PREDEFINED_ATTR = "data-predefined-amount"
static content = {
cell { $("td", it) }
description { cell(0).text() }
rubrikNum { cell(1).text().toInteger() }
preDefinedAmount { cell(0).parent("tr").$("td[$PREDEFINED_ATTR]").attr("$PREDEFINED_ATTR") }
inputField { cell(0).parent("tr").$("td input") ?: false }
dataType{ cell(0).parent("tr").attr("data-type") }
}
}
我的页面 class 看起来像这样:
class MyPage extends Page {
static url = "<some_url>"
static at = { $("h1").text() == "<some_text>" }
static content = {
submitButton { $("input", name:"<some_name>") }
myPageItems {
$("table tr").collect { it.module(RowModule) }
}
}
void verifyPrePopulatedFields(name, amount) {
long now = System.currentTimeMillis();
assert amount == selvangivelseItems.find { it.dataType== name}.preDefinedAmount.toInteger()
//assert amount == $("tr[data-type='" + name+ "']").$(".skts-tooltip-holder").text().toInteger()
println "Execution time" + (System.currentTimeMillis() - now) + " ms"
}
void submit() { submitTaxReturnButton.click() }
}
我的规范文件如下所示:
class MySpec extends GebReportingSpec {
@Unroll
def "field #name is pre-populated with amount #amount from the database"() {
expect:
page(MyPage) verifyPrePopulatedFields(name, amount)
where:
name << preFilledFields.keySet()
amount << preFilledFields.values()
}
}
在 Geb 中使用模块没有一般的性能问题,至少 none 据我所知是这样。另一方面,您的选择器肯定不是最优的。
首先,通过执行 myPageItems.find { it.dataType == name }
,您将遍历 table 中的所有行,并为每个行执行 3 个 WebDriver 命令(即您的测试和正在驱动的浏览器之间的 http 请求)他们。您可以将 dataType
的选择器改进为 dataType { attr("data-type") }
(这里不是 100% 确定,因为我没有看到您的 DOM 结构,但这是逻辑建议的)但它仍然意味着潜在提出很多要求。您应该改为添加这样的网站内容定义:
myItem { dataType ->
$("table tr[data-type='$dataType']").module(RowModule)
}
然后像这样使用它:
assert amount == myPageItem(name).preDefinedAmount.toInteger()
其次,您可以在模块中简化和改进选择器的性能(如果我对您的 DOM 的假设是正确的):
static content = {
cell { $("td", it) }
description { cell(0).text() }
rubrikNum { cell(1).text().toInteger() }
preDefinedAmount { $("td[$PREDEFINED_ATTR]").attr("$PREDEFINED_ATTR") }
inputField { $("td input") ?: false }
dataType{ attr("data-type") }
}
对于使用单个选择器或使用不必要的选择器可以找到的内容,您应该避免使用多个选择器,因为它们总是会带来性能损失。
问题描述
我正在编写一个 geb/spock 规范,它将测试数据从 DB2 提取到映射中(映射变量称为“preFilledFields” - 请参阅“MySpec" class 再往下)。
然后迭代此地图,对于每次迭代,我也会检查该值是否与页面上的一行中的值匹配。
当我执行上述访问模块对象属性的断言时,每个断言的平均执行时间约为。 5-6 秒。如果我直接使用选择器执行断言,那么每个断言的平均执行时间约为。 70-80 毫秒。有关断言的更多详细信息,请参阅“MyPage”class。
有谁知道这可能是什么原因造成的?性能不佳是我的代码造成的,还是在 geb 中使用模块时存在性能方面的普遍问题?
感谢我能得到的任何帮助和意见。
代码:
我的 "RowModule" class 看起来像这样:
class RowModule extends Module {
static final PREDEFINED_ATTR = "data-predefined-amount"
static content = {
cell { $("td", it) }
description { cell(0).text() }
rubrikNum { cell(1).text().toInteger() }
preDefinedAmount { cell(0).parent("tr").$("td[$PREDEFINED_ATTR]").attr("$PREDEFINED_ATTR") }
inputField { cell(0).parent("tr").$("td input") ?: false }
dataType{ cell(0).parent("tr").attr("data-type") }
}
}
我的页面 class 看起来像这样:
class MyPage extends Page {
static url = "<some_url>"
static at = { $("h1").text() == "<some_text>" }
static content = {
submitButton { $("input", name:"<some_name>") }
myPageItems {
$("table tr").collect { it.module(RowModule) }
}
}
void verifyPrePopulatedFields(name, amount) {
long now = System.currentTimeMillis();
assert amount == selvangivelseItems.find { it.dataType== name}.preDefinedAmount.toInteger()
//assert amount == $("tr[data-type='" + name+ "']").$(".skts-tooltip-holder").text().toInteger()
println "Execution time" + (System.currentTimeMillis() - now) + " ms"
}
void submit() { submitTaxReturnButton.click() }
}
我的规范文件如下所示:
class MySpec extends GebReportingSpec {
@Unroll
def "field #name is pre-populated with amount #amount from the database"() {
expect:
page(MyPage) verifyPrePopulatedFields(name, amount)
where:
name << preFilledFields.keySet()
amount << preFilledFields.values()
}
}
在 Geb 中使用模块没有一般的性能问题,至少 none 据我所知是这样。另一方面,您的选择器肯定不是最优的。
首先,通过执行 myPageItems.find { it.dataType == name }
,您将遍历 table 中的所有行,并为每个行执行 3 个 WebDriver 命令(即您的测试和正在驱动的浏览器之间的 http 请求)他们。您可以将 dataType
的选择器改进为 dataType { attr("data-type") }
(这里不是 100% 确定,因为我没有看到您的 DOM 结构,但这是逻辑建议的)但它仍然意味着潜在提出很多要求。您应该改为添加这样的网站内容定义:
myItem { dataType ->
$("table tr[data-type='$dataType']").module(RowModule)
}
然后像这样使用它:
assert amount == myPageItem(name).preDefinedAmount.toInteger()
其次,您可以在模块中简化和改进选择器的性能(如果我对您的 DOM 的假设是正确的):
static content = {
cell { $("td", it) }
description { cell(0).text() }
rubrikNum { cell(1).text().toInteger() }
preDefinedAmount { $("td[$PREDEFINED_ATTR]").attr("$PREDEFINED_ATTR") }
inputField { $("td input") ?: false }
dataType{ attr("data-type") }
}
对于使用单个选择器或使用不必要的选择器可以找到的内容,您应该避免使用多个选择器,因为它们总是会带来性能损失。