在javascript测试中避免误报

问题描述:

我正在开发一个jQuery插件,它可以循环使用多个图像。我正在编写一些测试,并且想要测试src属性在应该时总是被更改。麻烦的是,在javascript测试中避免误报

  • 原始图像通过
  • 图像包括在图像周期的列表以在页面中使用是随机选择
  • 的周期由setInterval的控制其由于对系统性能等有点不可预知

所以有时候有可能测试会失败,因为原始图像是从那些可用的随机选择,因此看起来像没有发生变化。

如何避免像这样的误报?

+0

做一个简单的文件名(当前加载的图像)比较? – moey 2012-01-10 00:37:20

您可以使用jquery toggle()在您进行更改时添加一个类,然后搜索您添加的类。调用切换会添加一个类,如果它不存在,则删除它,所以如果你应该有一个新的图像,它会被设置,而不是如果你应该有原始的。

+0

问题是,这会为插件添加一些不需要的功能。 – wheresrhys 2012-01-10 00:55:00

+0

作为测试和调试工具很有用。如果您担心与其他代码的相互关系,则可以使用前缀数据属性。 http://api.jquery.com/data/ – amccausl 2012-01-10 01:02:58

在这样的情况下,我特别注意使我的设计尽可能模块化,因此我可以分别测试所有零件。听起来你应该这样做。这样,像setInterval这样的行为对您的测试影响较小或没有影响。

例如,您应该有专门的方法来选择下一个URL,您可以独立于代码的其余部分进行测试。就该方法而言,您不关心原始图像是否在列表中,因为对于测试,您将图像列表设置为任何您想要的。在测试中,我会多次调用该方法,存储每个调用的结果,然后我会断言相同的字符串不在每个结果中。

+0

我不确定这种方法适用于此。我确实有一个改变url的函数,但它不是通过设计的公共方法(如果我认为用户可能想定制它,通常不包括核心功能,我只会公开插件的方法)。 – wheresrhys 2012-01-10 00:57:44

+0

它的JavaScript ...你真的把事情做成'私人'吗? – hvgotcodes 2012-01-10 01:10:17

+0

是...为什么不呢? – wheresrhys 2012-01-10 01:14:02

由于我们在JavaScript中可以覆盖的Math.random这样的:

describe('some suite', function() { 

    it('Math.random should equal 1', function() { 
     var origRandom = Math.prototype.random; 
     Math.prototype.random = function(){return 1}; 
     expect(Math.random()).toEqual(1); 
     Math.prototype..random = origRandom; 
    }); 

it('Math.random should equal 1 using jasmine', function() { 
     spyOn(Math, 'random').andReturn(1) 
     expect(Math.random()).toEqual(1); 
    }); 
}); 

另一种方式是随机数传递给你渲染功能,而不是在函数内部建立有你想测试

+0

我喜欢这个想法,但是在使用它的时候有点紧张,因为我测试的方法调用的方法调用Math.random太 – wheresrhys 2012-01-11 16:36:02

+0

在测试中使用随机不是一件好事无论如何。看看这篇文章:http://blog.tuxychandru.com/2009/11/mocking-mathrandom-using-powermock.html。它的Java,但他们做同样的'EasyMock.expect(Math.random())。和返回(0.50).anyTimes();' – 2012-01-11 16:45:51

您可以使用jasmine Spy behaviour来检查您的方法是否被调用。尤其是spyMethod.callcount,您可以使用它来检查调用方法的次数。

例如。是这样的:

var cycleMethod = SpyOn(jQPlugin.theCycleMethod).andCallThrough(); 

waits(1000); 

runs(function() { 

    expect(cycleMethod.callCount).toEqual(2); 

});