【问题标题】:QUnit fails tests inconsistently/alternatelyQUnit 不一致/交替地失败测试
【发布时间】:2013-05-08 15:28:50
【问题描述】:

我有一个简化的 QUnit 测试,它由 2 个简单的测试组成,这些测试无缘无故地随机/交替失败(它们都是原子的,这意味着一个测试不会改变另一个元素的任何内容)

请参阅this jsFiddle尝试运行多次

module("Basic actionBind");
//two simple tests
test("action1", function() {
    ok(ele2.trigger("click").hasClass("clicked"), "basic click action");
});

test("action2", function() {
    ok(ele1.click().hasClass("clicked"), "basic click action");
});

【问题讨论】:

  • 第二个测试做什么?我不确定click 函数在没有任何参数的情况下会做什么。
  • 不带参数的点击函数本身trigger是一次点击
  • 很奇怪。我已经更新两次以包含这两个测试,并通过随机暂停使它们异步,但只运行一个测试。就像单击/触发在第一次之后放弃一样。 jsfiddle.net/bAbNd/1.
  • dispatchEvent 也一样? jsfiddle.net/bAbNd/2
  • 发生这种情况是因为第一个失败的测试将在下一次运行。

标签: javascript jquery unit-testing qunit


【解决方案1】:

问题在于运行时全局上下文中的 jQuery 对象缓存。这是您的代码 中的两个 sn-ps(来自您问题中的链接:http://jsfiddle.net/adardesign/aZRK7/12/):

HTML:

<div id="qunit-fixture">
    <span id="ele1" class="action" data-action="action1"></span>
    <span id="ele2" class="action" data-action="action2" ></span>
</div>

JS:

// caching elements
var $ele1 = $('#ele1'),
    $ele2 = $('#ele2');

test('action1', function() {
    ok($ele2.trigger('click') ....


test('action2', function () {
    ok($ele1.trigger('click') ....

实际元素在#qunit-fixture 内,每个测试都会重置并重新解析它,因此您从测试内触发的点击事件是在现在不再在document 中的元素上触发的。相反,这些元素已被分离,#qunit-fixture 已从原始 html 文本中重新解析,从而创建了新的 DOM 元素。

我已经分叉了你的 jsFiddle 并相应地对其进行了修改:http://jsfiddle.net/aZRK7/15/

虽然我在注意到之前清理了各个部分,但本质的变化是将元素的查询移动到测试内部:

test('foo', function() {
    var $foo = $('#ele1');
    ok($foo.trigger('click') ....


test('bar', function () {
    var $bar = $('#bar');
    ok($bar.trigger('click') ....

【讨论】:

  • +1 非常感谢!我希望这应该在花费数小时之前在文档中......再次感谢。
  • @adardesign: "QUnit 将在每次测试后重置 #qunit-fixture 元素内的元素,删除可能存在的任何事件。只要您仅在此夹具中使用元素,您就不会’测试后不必手动清理以保持它们的原子性。” qunitjs.com/cookbook
  • 问题不仅在于缓存全局范围内的元素,还在于通过其他地方的脚本连接事件。我有一个按钮,我在脚本 ($("#equalsButton").click(...);) 中附加了一个 click 处理程序。由于清理了夹具,但是 没有在 default.js 中重新运行我的事件接线,处理程序交替地连接到或未连接到按钮,因此导致测试失败或相应地成功。解决问题的方法是在每次测试运行之前(或在测试设置例程中)连接click 事件。
【解决方案2】:

编辑:看起来 OP 去掉了代码的异步部分,留下答案以防万一,但它现在不回答问题。

好吧,我不确定您在进行测试时可能会遇到什么问题,但任何 AsyncTest 都必须在某处调用 start();。所以从你的小提琴:

asyncTest("action1", delay.bind(null, function() {
  console.log("test1");
  ok(ele2.trigger("click").hasClass("clicked"), "basic click action");

  start();

}, 2000*Math.random()));

来自QUnit asyncTest documentation,查看他们的示例。

【讨论】:

  • 谢谢,这不是异步操作,是吗?除此之外,我也尝试了您的代码,但仍然失败jsfiddle.net/adardesign/bAbNd/3
  • 好吧,在你的小提琴中你使用asynTest(),这样做需要你告诉QUnit测试的异步部分何时完成并继续(对start();的调用) .正如我所提到的,我不是 100% 确定你为什么会失败,更多的是回答另一部分。我会试着看看我能不能想出别的办法。
猜你喜欢
  • 1970-01-01
  • 2013-05-23
  • 1970-01-01
  • 2010-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多