【问题标题】:How do I reliably execute Jasmine tests that utilize requirejs via phantomjs?如何可靠地执行通过 phantomjs 使用 requirejs 的 Jasmine 测试?
【发布时间】:2012-08-29 23:02:26
【问题描述】:

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

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

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

【问题讨论】:

  • 我现在不应该为没有人发表评论而我有一个好的答案而感到高兴,或者为没有人有更好的替代方案感到难过。接受了我的回答,希望有一天它对某人有用:)

标签: javascript unit-testing jasmine phantomjs


【解决方案1】:

我做了一些不同的事情——我的 HTML 页面有一个函数,封装在一个 require() 调用中:

var run_tests = function (specfiles) {
    require(specfiles, function () {
        jasmine.getEnv().execute();
    });
};

那我page.evaluate( function (test_specs) { run_tests(test_specs) }, ['test1.spec', 'test2.spec']);

【讨论】:

  • 我认为这对大多数人来说是一个很好的答案。问题是,如果你有一个巨大的应用程序,你现在已经在一个真正的大列表中定义了所有可能的模块,你必须维护这些模块,而不是模块自己维护。
  • 实际上,我正在使用文件系统walker 来发现测试模块。我不清楚测试如何发现自己。你必须在某个地方有清单,不是吗?然后你可以让 require 做这项工作。它已经在管理代码何时可以执行。我完全可以相信我错过了你的观点,这就是我费心回复的原因。 :)
  • 感谢您的回复 - 本来可以早点回来的,但我出国了。我将不得不研究步行者的想法。现在我有一个“顶级”模块的列表,其中包括下面的所有模块,而不是使用助行器。那么,walker 提供的是作为“规范文件”传入的信息吗?
  • 才半年左右吧?但是,是的,walker 被设置为在 PhantomJS 下运行,它使用 fs 模块来遍历树并查找测试文件。测试运行器有点长(约 200 行),并且充满了令人尴尬的 hack,它没有被公开,但它与现有的解决方案相似——它存在的主要原因是生成一个 xunit 样式的报告以供 Jenkins 使用-- 现有的解决方案没有做到这一点。
【解决方案2】:

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

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

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,它知道在完成后自动解决它 - 所以我不需要在每个测试中手动推送和解决。

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

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

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

【讨论】:

    猜你喜欢
    • 2012-11-16
    • 1970-01-01
    • 2016-01-14
    • 1970-01-01
    • 1970-01-01
    • 2016-04-25
    • 1970-01-01
    • 2013-06-29
    • 1970-01-01
    相关资源
    最近更新 更多