Nicola Peluchetti
Nicola Peluchetti

Reputation: 76890

Is it wrong to put iterations and logic inside tests?

As in the question, should my tests be as simple as possible or should they contain some logic that mimics the logic of the function i'm testing?
To give you an example, i'm testing this function:

$( '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 );
};

My test should be plain dumb like this:

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();
    } );
} );

or have some iteration / logic so that i do all the tests at once?

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();
    } );
} );

Upvotes: 1

Views: 105

Answers (1)

piotrek
piotrek

Reputation: 14550

more complicated test:

  1. is harder to maintain
  2. can't be used as a documentation
  3. is harder to read and software is being read much often than it's written
  4. has higher probability to be written wrongly (who will test our tests?)
  5. may disrupt your api design during TDD

on the other hand it's easier and faster to write a single test that cover whole functionality then writing 12 small tests. that's why this way usually wins. to sum it up: if your project is planned to live long i would write smallest and simplest possible tests. it's more demanding but will profit in future

Upvotes: 2

Related Questions