Javascript 将迭代和逻辑放在测试中是错误的吗?
如问题所述,我的测试应该尽可能简单,还是应该包含一些模仿我正在测试的函数逻辑的逻辑?Javascript 将迭代和逻辑放在测试中是错误的吗?,javascript,unit-testing,Javascript,Unit Testing,如问题所述,我的测试应该尽可能简单,还是应该包含一些模仿我正在测试的函数逻辑的逻辑? 举个例子,我正在测试这个函数: $( 'ul.nav-tabs a' ).click( event_handlers.handle_set_tab_cookie ); var handle_set_tab_cookie = function( e ) { var active = $( this ).attr( 'href' ); $.cookie( 'feeds_active_tab', a
举个例子,我正在测试这个函数:
$( 'ul.nav-tabs a' ).click( event_handlers.handle_set_tab_cookie );
var handle_set_tab_cookie = function( e ) {
var active = $( this ).attr( 'href' );
$.cookie( 'feeds_active_tab', active );
};
我的测试应该是这样的:
describe( "Facebook Feeds page", function() {
beforeEach( function() {
$( 'ul.nav' ).remove();
var html = $('<ul class="nav nav-tabs"><li class="active"><a data-toggle="tab" href="#facebook">Facebook Feeds</a></li><li class=""><a data-toggle="tab" href="#ics">ICS</a></li></ul>');
$('body').append( html );
} )
it( "Should call jQuery cookie to save the href ", function() {
// Set up the listeners
page.start();
// Set up spies
spyOn($, 'cookie');
// Start the test
var a = $( 'a[href=#facebook]' );
a.trigger( 'click' );
// verify that it has been called with the correct parameter
expect($.cookie).toHaveBeenCalled();
expect($.cookie).toHaveBeenCalledWith('feeds_active_tab', '#facebook');
} );
afterEach( function() {
$( 'ul.nav' ).remove();
} );
} );
description(“Facebook提要页面”,函数(){
beforeach(函数(){
$('ul.nav').remove();
var html=$(“
”);
$('body').append(html);
} )
它(“应该调用jQuery cookie来保存href”,function(){
//安排听众
page.start();
//设置间谍
spyOn($,'cookie');
//开始测试
var a=$('a[href=#facebook]');
a、 触发器(‘点击’);
//验证是否已使用正确的参数调用它
期望($.cookie).toHaveBeenCalled();
期望($.cookie).toHaveBeenCalledWith('feeds_active_tab','facebook');
} );
之后(函数(){
$('ul.nav').remove();
} );
} );
或者进行一些迭代/逻辑,以便我一次完成所有测试
describe( "Facebook Feeds page", function() {
beforeEach( function() {
$( 'ul.nav' ).remove();
var html = $('<ul class="nav nav-tabs"><li class="active"><a data-toggle="tab" href="#facebook">Facebook Feeds</a></li><li class=""><a data-toggle="tab" href="#ics">ICS</a></li></ul>');
$('body').append( html );
} )
it( "Should call jQuery cookie to save the href ", function() {
// Set up the listeners
page.start();
// Set up spies
spyOn($, 'cookie');
// Start the test and iterate over all the links
$( 'ul.nav a' ).each( function(i, el) {;
$(el).trigger( 'click' );
// verify that it has been called with the correct parameter
expect($.cookie).toHaveBeenCalled();
expect($.cookie).toHaveBeenCalledWith('feeds_active_tab', $(el).attr('href');
} );
} );
afterEach( function() {
$( 'ul.nav' ).remove();
} );
} );
description(“Facebook提要页面”,函数(){
beforeach(函数(){
$('ul.nav').remove();
var html=$(“
”);
$('body').append(html);
} )
它(“应该调用jQuery cookie来保存href”,function(){
//安排听众
page.start();
//设置间谍
spyOn($,'cookie');
//开始测试并迭代所有链接
$('ul.nava')。每个(函数(i,el){;
$(el).触发器('单击');
//验证是否已使用正确的参数调用它
期望($.cookie).toHaveBeenCalled();
expect($.cookie).toHaveBeenCalledWith('feeds\u active\u tab',$(el.attr('href');
} );
} );
之后(函数(){
$('ul.nav').remove();
} );
} );
更复杂的测试:
另一方面,编写一个涵盖整个功能的测试比编写12个小测试更容易、更快。这就是为什么这种方式通常会获胜。总而言之,如果你的项目计划寿命长,我会编写尽可能最小和最简单的测试。这要求更高,但将来会有所收益我不会否决一个24K的老手-但这个问题可能会引起意见;)这可能更多地出现在programmers.stackexchange.com上,因为它更多的是一个概念性问题,而不是一个客观问题。@madflow如果你不同意,你应该投反对票并解释原因!我不熟悉单元测试,我希望有一个正确的方法,因此我向更有经验的用户寻求帮助,我在更实际的任务上提供帮助:)@Brisbe42如果更多的人认为它更适合程序员,我会移动它,无论如何,我会标记它attention@NicolaPeluchetti很公平:)+1的明确解释。但是干什么呢?我需要复制/粘贴并用“#ics”替换“#facebook”?然后是“#myspace”、“#google+”等等?我知道如果测试错误,我可能会有问题,但如果测试逻辑正确,如果我在添加新选项卡时实现错误,我可能会节省明天的时间。你还必须对测试代码应用干。你会复制粘贴你的生产代码吗?您必须重构您的测试,提取公共过程、夹具等,但我仍然认为每个测试都应该关注单个功能。我也不相信“如果测试代码正确,我会节省时间”的说法。这样,您可以说:“如果我的生产代码是正确的,我将通过不编写测试来节省时间”。与初始开发相比,更多的时间和金钱花在维护、更改和错误修复上,因此代码应该是可维护和可读的。测试是你系统的一部分,同样的规则也适用于它们。我的一位朋友在twitter上告诉我,“第一个测试实际上并不“愚蠢”,但我认为它涵盖了与第二个测试相同的代码和执行路径。”这是真的,我想也许我不需要测试所有可能的点击,但只需要测试代码是否有效,对于这一点,第一个测试是我同意的。还有一件事是有用的。当然,每个执行路径一次测试就足以检查代码是否工作。但是,如果您认为在阅读了测试之后,仍有人会想知道其他参数(null、小于0、空字符串、不同货币等)的代码(应该)表现如何,那么最好添加另一个测试作为文档。当然,如果执行路径相同,那么提取公共测试夹具应该没有问题。它干吗?不是真的。这有助于理解您的代码吗?明显地