对 meteor ,速度和 Jasmine 来说是很新的东西,所以不确定我是否做错了什么,将 Jasmine 用于不是为它设计的东西,或者这只是它的工作方式。
我发现我几乎需要为所有测试设置超时时间,以使它们通过。是这种情况还是我做错了什么?
例如,我正在运行一些测试来检查验证消息:
describe("add quote validation", function() {
beforeEach(function (done) {
Router.go('addQuote');
Tracker.afterFlush(function(){
done();
});
});
beforeEach(waitForRouter);
it("should show validation when Quote is missing", function(done) {
$('#quote').val('');
$('#author').val('Some author');
Meteor.setTimeout(function(){
$('#addQuoteBtn').click();
}, 500);
Meteor.setTimeout(function(){
expect($('.parsley-custom-error-message').text()).toEqual("Quote can't be empty.");
done();
}, 500);
});
}
最佳答案
好的,我们遇到了同样的问题,并为它设计了一个非常优雅的解决方案,它不需要超时,是运行测试最快的方法。基本上,我们使用两种策略之一,具体取决于您正在等待什么屏幕元素。
所有代码都放入tests / mocha / client / lib.coffee中,而不是Jasmine等效代码的100%,但是所有客户端测试代码都可以使用它。我已经将它留在Coffeescript中,但是您可以在coffeescript.org上将其编译为Javascript,它也应该可以正常工作。
如果您所做的任何事情(路由或更改反应变量等操作)导致Template
都(重新)渲染,则可以使用Template.<your_template>.rendered
挂钩来检测渲染完成的时间。因此,我们在lib.coffee中添加了以下功能:
@afterRendered = (template,f)->
cb = template.rendered
template.rendered = ->
cb?()
template.rendered = cb
f?()
return
return
它有什么作用?它基本上可以“记住”原始的
rendered
回调,并在呈现template
并调用原始回调后,将其临时替换为一个调用额外功能的函数。它需要做这种整理工作,以避免破坏任何可能依赖rendered
回调的代码,因为您基本上是在直接弄混Meteor代码。在测试中,您可以执行以下操作:
it.only "should check stuff after routing", (done)->
try
Router.go "<somewhere>"
afterRendered Template.<expected_template>, ->
<your tests here>
done()
catch e
done(e)
我也建议使用try-catch,因为我注意到异步错误并不总是使它进入速度系统,而只是给您超时失败。
好的,然后有些事情实际上并没有重新渲染,而是通过JS或某种“显示/隐藏”机制生成的。为此,您确实需要某种超时,但是可以通过使用轮询机制来减少超时的“时间成本”。
# evaluates if a JQuery element is visible or not
$.fn.visible = -> this.length > 0 and this.css('display') isnt 'none'
# This superduper JQuery helper function will trigger a function when an element becomes visible (display != none). If the element is already visible, it triggers immediately.
$.fn.onVisible = (fn,it)->
sel = this.selector
if this.visible()
console.log "Found immediately"
fn?(this)
else
counter = 0
timer = setInterval ->
counter++
el = $(sel)
if el.visible()
fn?(el)
clearInterval timer
console.log "Found on iteration #{counter}"
else
it?(el)
, 50
如果愿意,可以删除控制台日志记录和辅助
it
迭代器函数,它们并不重要。这使您可以在测试中执行以下操作:$('#modalId').onVisible (el)->
<tests here>
done()
, (el)->
console.log "Waiting for #{el.selector}"
您可以根据需要删除第二个函数,它是上面提到的
it
迭代器函数。但是,请注意,此特定代码将“display:hidden”用作不可见标记(Bootstrap会这样做)。如果您的代码使用其他机制隐藏/显示部件,请更改它。对我们来说就像一个魅力!