Docs: http://docs.jquery.com/Qunit
Code: https://github.com/jquery/qunit
A software development process that relies on the repetition of a very short development cycle: first the developer writes a failing automated test case that defines a desired improvement or new function, then produces code to pass that test and finally refactors the new code to acceptable standards.
Introducing BDD : http://blog.dannorth.net/introducing-bdd/
"...where to start, what to test and what not to test, how much to test in one go, what to call their tests, and how to understand why a test fails."
Basically use language/terminology that everyone on the project understands; using a pattern (e.g. Given, When, Then.) to test expected behavior.
"Developers discovered it could do at least some of their documentation for them, so they started to write test methods that were real sentences."
"Test-driven development constantly repeats the steps of adding test cases that fail, passing them, and refactoring. Receiving the expected test results at each stage reinforces the programmer's mental model of the code, boosts confidence and increases productivity."
From marketForce : For weekend traffic, the one word difference had a +17.58% RPV Lift (98.01% Confidence) and a +16.15% Conversion Lift (97.53% Confidence) So, I think it’s worth...
– this forecasts to an incremental $300K in annual revenues.
Could have used…
var today = new Date();
if (today.getDay() == 0 || today.getDay() == 6) {
$('#dr_billingContainer h3:eq(0)').html('Billing Information');
}
…Instead chose to make a jQuery plugin that acts as a utility method that can easily be reused for other sites
/**
* $.fn.isWeekend() plugin to test if browsing on Sat./Sun.
* checks a date object to see if the day is a weekend day, Saturday / Sunday
* requires Date object as argument and jQuery
* dr.isWeekend alias for plugin to use as utility function
* @return true/false
*/
What's Needed? What behavior will we test for?
<!DoCtYpE html>
<html>
<head>
<!-- QUnit CSS, JS, etc. -->
</head>
<body>
<h1 id="qunit-header">QUnit Tests for ...</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">test markup</div>
</body>
</html>
/* namespace */
module('namespace check');
test('is dr a global variable.',function(){
expect(1);
ok( window.dr, 'dr namespace is present');
});
if (!window.dr) { var dr = {}; } // using dr as namespace
module("dr.isWeekend() utility fn uses jQuery", {
setup: function() {
dr.date = new Date();
dr.weekdays = [1,2,3,4,5];
dr.weekends = [0,6];
},
teardown: function() {
delete dr.date;
delete dr.weekdays;
delete dr.weekends;
}
});
test("dr.isWeekend() expects argument of object type Date", function(){
// Arrange - use setup() for dr.date
var testPluginDefault;
// Act
testPluginDefault = dr.isWeekend();
// Assert
expect(1);
notStrictEqual( testPluginDefault, 'error', "Plugin does not return 'error' comparing with notStrictEqual");
});
(function($) {
$.fn.isWeekend = function(options) {
var defaults = {};
opts = $.extend({},defaults, options);
// return this.each(function() {
// code plugin here ...
// });
};
dr.isWeekend = $.fn.isWeekend;
})(jQuery);
test("dr.isWeekend() expects argument of object type Date", function(){
// Arrange - use setup() for dr.date
var testPluginDefault;
// Act
testPluginDefault = dr.isWeekend();
// Assert
expect(1);
notStrictEqual( testPluginDefault, 'error', "Plugin does not return 'error' comparing with notStrictEqual");
});
$.fn.isWeekend = function(options) {
var defaults, opts;
defaults = { date: new Date() };
opts = $.extend({},defaults, options);
if (Object.prototype.toString.call(opts.date) === '[object Date]') {
opts.dateOk = true;
} else {
return 'invalid';
}
};
// Act
// ...
testPluginTrue = dr.isWeekend({ date: dr.date });
// Assert
expect(3);
// ...
notStrictEqual( testPluginTrue, 'invalid', "Plugin does not return 'invalid' comparing with notStrictEqual");
test("dr.isWeekend() plugin returns true or false for each day of the week", function(){
// Arrange - use setup() for dr.date, dr.weekdays, dr.weekends
var n, weekday, weekend;
// Act
n = 0;
weekend = $.inArray(n, dr.weekends);
n = 1;
weekday = $.inArray(n, dr.weekdays);
// Assert
expect(2);
equal(weekend, 0, "testing a weekend value");
equal(weekday, 0, "testing a weekday value");
});
// Assert
expect(11);
equal(weekend, 0, "testing a weekend value");
equal(weekday, 0, "testing a weekday value");
equal(isSunday, true, "Yes, 11/28/2010 is Sunday a weekend" );
equal(isMonday, false, "Yes, 11/29/2010 is Monday a weekday" );
equal(isTuesday, false, "Yes, Tuesday a weekday" );
equal(isWednesday, false, "Yes, Wednesday a weekday" );
equal(isThursday, false, "Yes, Thursday a weekday" );
equal(isFriday, false, "Yes, Friday a weekday" );
equal(isSaturday, true, "Yes, Saturday a weekday" );
equal(isTodayAWeekend, true, "Is today a weekend: true if today is a weekend" );
equal(isTodayAWeekend, false, "Is today a weekend: false if today is a weekday" );
// ...
weekdays = [1,2,3,4,5];
weekends = [0,6];
if (Object.prototype.toString.call(opts.date) === '[object Date]') {
// check if weekend using getDay() -> returns number 0-6 for day of week
opts.n = opts.date.getDay();
if ( $.inArray(opts.n , weekends) > -1 ) {
return true;
} else if ( $.inArray(opts.n , weekdays) > -1 ) {
return false;
}
return 'error';
} else {
return 'invalid';
}