代码之家  ›  专栏  ›  技术社区  ›  nils1k

与使用选择器相比,geb查找模块对象属性的性能问题

  •  1
  • nils1k  · 技术社区  · 10 年前

    问题描述

    我正在编写一个geb/spock规范,它将测试数据从DB2提取到映射中(映射变量称为“ 预填充字段 “-请参阅” 我的规范 “班级再往下)。

    然后对该映射进行迭代,对于每次迭代,我也会检查该值是否与页面上一行中的值匹配。

    当我执行上述访问模块对象属性的断言时,每个断言的平均执行时间约为5-6秒。如果我直接使用选择器执行断言,则每个断言的平均执行时间约为70-80毫秒。请参阅“ 我的页面 ”类以获取有关断言的更多详细信息。

    有人知道这是什么原因吗?糟糕的性能是我的代码造成的,还是在使用geb中的模块时存在性能方面的一般问题?

    感谢我能得到的任何帮助和意见。

    代码:

    我的“RowModule”类如下所示:

    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 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()
        }
    }
    
    1 回复  |  直到 10 年前
        1
  •  3
  •   erdi    10 年前

    在Geb中使用模块没有一般的性能问题,至少我所知道的没有。另一方面,您的选择器绝对是次优的。

    首先通过做 myPageItems.find { it.dataType == name } 您正在遍历表中的所有行,并为每一行执行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") }
    }
    

    您应该避免使用多个选择器来处理使用单个选择器可以找到的事情,或者使用不必要的选择器,因为它们总是会带来性能损失。