如何可靠地执行通过 phantomjs 使用 requirejs 的 Jasmine 测试?

我正在使用 phantomjs 运行 jasmine 测试.我的 jasmine 测试在 describe 块周围使用 require 以确保加载所有正确的模块.

I am using phantomjs to run jasmine test. My jasmine tests are using require around the describe blocks to ensure all the right modules are loaded.

我的测试无法运行,因为 page.evaluate ->jasmine.getEnv().execute(); 在 requirejs 完成加载模块之前运行.

My tests would not run because page.evaluate -> jasmine.getEnv().execute(); runs BEFORE requirejs finishes loading the modules.

我想知道是否有人知道解决此问题的真正好方法.我有一个答案,我将在下面发布,但很想通过其他答案比较笔记.如果你的更好,我会明确选择它作为答案:)

I was wondering if anyone knows a real good way around this. I have an answer I'm going to post below but would love to compare notes via other answers. If yours is better, I will def pick it as answer obviously :)

推荐答案

我的解决方案,使用 jQuery,是这样的:

My solution, with jQuery available, is this:

在您的任何测试运行之前加载配置文件.

Load a config file before any of your tests run.

var jasmine_deferreds = [];

// Setup an event to fire on the document
// I actually did this with native code rather than jquery because
// I wanted to minimize jquery usage

// ....

// setTimeout so all files loaded after this will finish registering their requires
setTimeout( function() {

  $.when.apply( null, jasmine_deferreds ).then( function() {

    // Fire event that was created

  });

}, 5 );

如何构建延迟数组然后解决它们取决于您.我基本上推到了数组,然后在要求完成后解决.我用我自己的版本包装了 require ,它知道在完成后自动解决它 - 所以我不需要在每个测试中手动推送和解决.

It's up to you how you want to build up the array of deferreds and then resolve them. I essentially pushed to the array and then resolved when the require was done. I wrapped require with my own version that would know to resolve it upon completion automatically - so I don't need to push and resolve manually in each test.

然后在我的幻像文件中我这样做:

Then in my phantom file I do this:

page.evaluate ->
    mylistener = ( document ) -> jasmine.getEnv().execute();
    document.addEventListener( 'test_ready_event', mylistener, false);

这使得我知道我所有的 require 模块都被加载了,而没有一些任意的 setTimeout 一旦我加载太多文件就可能太短了.我正在使用的 setTimeout 是安全的,因为它仅用于在主调用堆栈完成后触发.它并不关心时间.

This makes it so I know all my require modules are loaded without having some arbitrary setTimeout that could be too short once I am loading too many files. The one setTimeout I'm using is safe because it's only being used to fire after main callstack is done. It doesn't really care about the time.

相关文章