使用Velocity和Jasmine测试Meteor时需要超时 [英] Requiring timeouts when testing Meteor with Velocity and Jasmine

查看:105
本文介绍了使用Velocity和Jasmine测试Meteor时需要超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对流星,速度和茉莉很新,所以不确定我做错了什么,使用Jasmine作为它不适合的东西,或者这只是它的工作方式。

Pretty new to meteor, velocity and jasmine so not sure if I am doing something wrong, using Jasmine for something it's not designed for, or this is just the way it works.

我发现我需要为我的几乎所有测试设置超时才能让它们通过。应该是这种情况还是我做错了什么?

I am finding I need to set timeouts for pretty much all of my tests in order to get them to pass. Should this be the case or am I doing something incorrectly?

例如我正在运行的一些测试来检查验证消息:

For example some tests I am running to check validation messages:

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


解决方案

好的,我们遇到了同样的问题并设计了一个非常优雅的解决方案,它不需要超时,是运行测试的最快方法。基本上,我们使用两种策略中的一种,具体取决于您正在等待的屏幕元素。

OK, we've had this exact same problem and devised a pretty elegant solution to it, that doesn't require timeouts and is the fastest way to run your tests. Basically, we use one of two strategies, depending on what screen elements you're waiting for.

所有代码都进入tests / mocha / client / lib.coffee,而不是相当于Jasmine的100%,但它应该可用于所有客户端测试代码。我把它留在了Coffeescript中,但你可以在coffeescript.org上将它编译成Javascript,它也可以正常工作。

All code goes into tests/mocha/client/lib.coffee, not 100% what the Jasmine equivalent is, but it should be available to all client test code. I've left it in Coffeescript, but you can compile it on coffeescript.org into Javascript, it should work fine as well.

如果你做了什么(路由或其他东西)或者更改一个反应变量)导致模板进行(重新)渲染,你可以使用模板。< your_template> .rendered hook来检测完成渲染的时间。所以,我们在lib.coffee中添加了以下函数:

If whatever you do (routing or something else like changing a reactive variable) causes a Template to (re)render, you can use the Template.<your_template>.rendered hook to detect when it is finished rendering. So, we've added the following function in lib.coffee:

@afterRendered = (template,f)->
    cb = template.rendered
    template.rendered = ->
      cb?()
      template.rendered = cb
      f?()
      return
    return

它做什么?它基本上记住原始呈现的回调,暂时将其替换为在之后调用额外函数渲染code> template 并调用原始回调。它需要做这种内务管理,以避免破坏任何可能依赖于呈现的回调的代码,因为你基本上是在直接搞乱Meteor代码。

What does it do? It basically "remembers" the original rendered callback and temporarily replaces it with one that calls an extra function after the template is rendered and the original callback is called. It needs to do this sort of housekeeping to avoid breaking any code that may have depended on the rendered callback, as you're basically messing with the Meteor code directly.

在测试中,您可以执行以下操作:

In your test, you can then do something like this:

 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,因为我注意到异步错误并不总能进入速度系统,只是给你一个超时失败。

I'd recommend the try-catch as well, as I've noticed asynchronous errors don't always make it into the velocity system, merely giving you a timeout failure.

好的,然后有些东西实际上没有重新渲染,而是用JS或某种显示/隐藏机制生成的。为此,您确实需要某种超时,但可以通过使用轮询机制来减少超时的时间成本。

OK, then there are things that don't actually re-render, but are generated with JS or by some kind of "show/hide" mechanism. For that, you do need some kind of timeout, but you can reduce the "time cost" of the timeout by using a polling mechanism.

# 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 迭代器函数,它们并不重要。这允许你在测试中做这样的事情:

You can remove the console logging and secondary it iterator function if you like, they're not important. This allows you to do something like this in your test:

$('#modalId').onVisible (el)->
  <tests here>
  done()
, (el)->
  console.log "Waiting for #{el.selector}"

你可以删除如果你想要的第二个函数,它是上面提到的 it 迭代器函数。但请注意,此特定代码使用display:hidden作为隐身标记(Bootstrap执行此操作)。如果您的代码使用其他机制来隐藏/显示部件,请更改它。

You can remove the second function if you want, it is the it iterator function mentioned above. However, do note that this particular code works with "display: hidden" as the marker for invisibility (Bootstrap does this). Change it if your code uses another mechanism to hide/show parts.

对我们来说就像一个魅力!

Works like a charm for us!

这篇关于使用Velocity和Jasmine测试Meteor时需要超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆