在我的应用程序中,某些Geb测试有些不稳定,因为我们在每个表单字段更改后都会触发ajax验证http请求。如果ajax调用返回的速度不够快,则测试会失败。

我想为此测试一个简单的解决方案,(正确或错误,让我们不要在这里进行辩论……)是在设置每个字段之后引入100ms左右的短暂停顿,所以我开始研究如何以及在何处我可以做到这一点。

看来我需要在调用Thread.sleepNonEmptyNavigator.setInputValue方法之后添加一个NonEmptyNavigator.setSelectValue。我创建了GebSpec的子类,在其中添加了一个静态初始化程序块:

static {
    NonEmptyNavigator.metaClass.invokeMethod = { String name, args ->
        def m = delegate.metaClass.getMetaMethod(name, *args)
        def result = (m ? m.invoke(delegate, *args) : delegate.metaClass.invokeMissingMethod(delegate, name, args))
        if ("setInputValue".equals(name) || "setSelectValue".equals(name)) {
            Thread.sleep(100)
        }
        return result
    }
}

但是,我添加了一些调试日志记录,并且发现执行我的规范时,我从未触及过此代码。我在这里做错了什么...?

最佳答案

我知道您要求不要在设置表单元素值时就进行睡眠辩论,但我只是想向您保证,这确实是您不想做的事情。有两个原因:

  • ,它将使您的测试速度明显降低,并且从长远来看,这将使您痛苦不堪,因为一般
  • 的浏览器测试速度都很慢
  • 在某些情况下(例如,慢CI),100ms不够用,因此从本质上讲,您并没有消除片状现象,而只是在某种程度上限制了它。

  • 如果您真的坚持要这样做,那么Geb允许您使用custom Navigator implementations。您的自定义非空Navigator实现将如下所示:
    class ValueSettingWaitingNonEmptyNavigator extends NonEmptyNavigator {
        Navigator value(value) {
            super.value(value)
            Thread.sleep(100)
            this
        }
    }
    

    这样,就不需要猴子打补丁NonEmptyNavigator,您将避免可能引起的任何奇怪问题。

    适当的解决方案是拥有一个自定义Module实现,该实现将覆盖Navigator value(value)方法,并使用waitFor()检查验证是否已完成。最后,您将所有已验证的表单元素包装在此模块中的页面和模块content块中。这意味着您仅在需要的地方等待,并尽可能少地等待。我不知道您的套件有多大,但是随着它的增长,这100毫秒将变成几分钟,您将对测试的速度感到不安。相信我,我去过那里。

    关于grails - 使用NonEmptyNavigator.metaClass.invokeMethod {…}在字段设置后引入短暂的暂停,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26344830/

    10-09 10:10