在我的应用程序中,一些Geb测试有点不稳定,因为我们在每个表单字段更改后触发了ajax验证http请求。如果ajax调用没有足够快地返回,测试就会爆炸。
我想为此测试一个简单的解决方案,(正确或错误,让我们不在这里讨论...)是在每个字段设置后引入短暂的100ms左右暂停,所以我开始关注怎么&我可以在哪里实现这一目标。
看起来我需要在调用Thread.sleep
和NonEmptyNavigator.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
}
}
但是我添加了一些调试日志记录,我注意到当我执行我的规范时,我从来没有点过这段代码。我在这做错了什么......?
答案 0 :(得分:3)
我知道你曾经要求不要在设置表单元素值时进行关于放置睡眠的辩论,但我只是想向你保证这确实是你不想做的事情。有两个原因:
如果你真的坚持这样做,那么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毫秒会变成几分钟,你会对你的测试速度感到不安。相信我,我去过那里。