grails - 使用 NonEmptyNavigator.metaClass.invokeMethod { ... } 在字段设置后引入短暂的暂停

标签 grails groovy spock geb

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

我想为此测试一个简单的解决方案,该解决方案(正确或错误,我们不在这里讨论这个争论......)是在设置每个字段后引入一个短暂的 100 毫秒左右的暂停,所以我开始考虑我如何以及在哪里可以实现这一点。

看起来我需要在调用 NonEmptyNavigator.setInputValueNonEmptyNavigator.setSelectValue 方法之后添加 Thread.sleep 。我创建了 GebSpec 的子类,并在其中添加了静态初始化 block :

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
    }
}

但是,我添加了一些调试日志记录,并且我注意到,当我执行规范时,我从未遇到过此代码。我在这里做错了什么......?

最佳答案

我知道您要求不要在设置表单元素值时陷入有关放置 sleep 的争论,但我只是想向您保证,这确实是您不想做的事情。原因有二:

  • 这会使您的测试速度明显变慢,从长远来看,这将是痛苦的,因为浏览器测试通常很慢
  • 在某些情况下(例如慢速 CI),100 毫秒是不够的,因此本质上您并没有消除不稳定,只是以某种方式限制了它

如果你真的坚持这样做,那么 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 block 中。这意味着您只在必要时等待并且尽可能少地等待。我不知道你的套件有多大,但随着它的增长,这 100 毫秒将变成几分钟,你会对你的测试有多慢感到不安。相信我,我去过那里。

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

相关文章:

spring - 尝试连接到MongoLab时URL格式的MongoException

grails - 从Intellij启动Geb测试

mysql - Groovy - 找不到类

javascript - 如何从服务器保留空值? (Groovy 和 JavaScript)

grails - 如何使用 spock 在 Grails 应用程序中测试具有真实事务的服务?

grails - 在 Intellij Idea : Bizarre error in Spock test: Cannot add Domain class [class x. y.Z] 中运行 grails 2.1.3 测试。它不是域

java - 无法在 Spring 中配置用于集成测试的模块 - 没有可用的任务

mongodb - GMongo 中可以进行身份​​验证吗?

java - 包装 JUnit 测试(在 Eclipse 中)

grails 错误 : grails. 验证。Validateable 不是 @grails.validation.Validateable 中的注释