【问题标题】:Requiring timeouts when testing Meteor with Velocity and Jasmine使用 Velocity 和 Jasmine 测试 Meteor 时需要超时
【发布时间】:2015-04-04 18:54:18
【问题描述】:

对流星、速度和茉莉花很陌生,所以不确定我是否做错了什么,将茉莉花用于非设计用途,或者这就是它的工作方式。

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

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

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

【问题讨论】:

  • 只是一个 +1,我认为这不是 Jasmine 特有的。我在 mike:mocha 包中看到了同样的问题,它使用 mocha 和流星和速度。设置超时似乎是使测试可靠通过的唯一方法。我正在使用链接到 velocity.meteor.com 的文档。如果我找到更好的方法,我会更新!

标签: javascript meteor jasmine meteor-velocity meteor-jasmine


【解决方案1】:

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

所有代码都进入 tests/mocha/client/lib.coffee,而不是 100% 的 Jasmine 等效代码,但它应该可用于所有客户端测试代码。我把它留在 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 迭代器函数。但是,请注意,此特定代码使用“显示:隐藏”作为不可见标记(Bootstrap 执行此操作)。如果您的代码使用其他机制来隐藏/显示部分,请更改它。

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

【讨论】:

  • 感谢您的详细回复,我已经搞砸了一点,它似乎工作得很好,而且肯定比坚持超时更干净!
  • 好主意!这应该进入包本身:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-02
  • 2022-01-13
  • 2015-06-05
相关资源
最近更新 更多