Quick Tip: Quick and Easy JavaScript Testing with “Assert”
videos

Quick Tip: Quick and Easy JavaScript Testing with “Assert”

Tutorial Details
  • Subject: JavaScript Testing
  • Difficulty: Beginner - Intermediate
  • Tutorial Format: 9 Minute Screencast
Download Source Files

Years ago, I learned a deceptively simple “assert” function from John Resig, for testing your JavaScript. Amazingly, at barely five or six lines, this code provides a great level of power and control over your code, when testing. I’ll show you how to use it in today’s video quick tip.


Screencast


“Assert” Code

<!DOCTYPE HTML>
<html lang="en-US">
<head>
	<meta charset="UTF-8">
	<title>Easy JavaScript Testing </title>
	<style>
		.pass:before {
			content: 'PASS: ';
			color:  blue;
			font-weight: bold;
		}
		
		.fail:before {
			content: 'FAIL: ';
			color: red;
			font-weight: bold;
			
		}
	</style>
</head>
<body>

<ul id="output"></ul>
	
<script>
var output = document.getElementById('output');

function assert( outcome, description ) {
	var li = document.createElement('li');
	li.className = outcome ? 'pass' : 'fail';
	li.appendChild( document.createTextNode( description ) );
	
	output.appendChild(li);
};
</script>

That’s all you need for most basic testing! The assert function accepts two parameters:

  1. outcome: A boolean, which references whether your test passed or failed
  2. description: A short description of your test.

The assert function then simply creates a list item, applies a class of either “pass” or “fail,” dependent upon whether your test returned true or false, and then appends the description to the list item. Finally, that block of coded is added to the page. It’s crazy simple, but works perfectly.


Test 1: Your First Example

function add(num1, num2) {
	return num1 + num2;
}

var result = add(5, 20);
assert( result == 24, 'Checking the add function');

// OR
assert( add( 5, 20 ) == 24, 'Checking the add function');
JavaScript Testing Example

Test 2: Closures

var someArray = [1,2,3,4,5],
	len = someArray.length,
	i = 0;
	
var count = 0;

for ( ; i < len; i++ ) {
	setTimeout(function() {
		assert( count++ === i, 'Checking the value of: ' + i );
	}, i * 300);
}
JavaScript Testing Example

Uh oh! What happened?

This is a common issue, and the answer is to implement a closure, so that we can remember the value of "i." Otherwise, as we noticed above, the code will only render the final value in the sequence: 5.

var someArray = [1,2,3,4,5],
	len = someArray.length,
	i = 0;
	
var count = 0;

for ( ; i < len; i++ ) (function(i) {
	setTimeout(function() {
		assert( count++ === i, 'Checking the value of: ' + i );
	}, i * 300);
})(i);
JavaScript Testing Example

Conclusion

At first, it might appear as if only huge JavaScript libraries and such require some form of testing; however, that's far from the truth. As we've demonstrated, even a simple function, like Resig's "assert", can potentially save us from hours of debugging! So what do you personally use to test your code?

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • Andrew

    I still haven’t found a project that requires any testing bigger than the typical plug-n-chuck.

    • http://dmitry-scriptin.blogspot.com/ Scriptin

      Must be you had never seen a serious projects. It’s fun then you test some application in your favorite browser and when you launch it on the web, it doesn’t work.

      Quick example you write such code:
      > return
      > {
      > someProperty: value
      > }
      It returns nothing (implicit semicolon after ‘return’). When you compress it and launch your project:
      > return{someProperty:value}

      Now it returns an object. Gotcha! Not a very real-world example, but…

  • http://laroouse.com edurup

    thanks for tips very good

  • Luis

    Nice tut.

    What is that theme for espresso ? can you share it ? :)

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      I believe it’s the Cappuccino theme. You can download it from Espresso’s site.

  • http://brianegan.com Brian Egan

    Hey Jeffrey,

    Nice, simple little function! I usually prefer JSpec (http://visionmedia.github.com/jspec/) for my testing suite, because it’s got a really nice command-line interface for quickly getting a new project setup, and because I really like the Behavior Driven Development philosophy in general.

    Brian

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Hey Brian – cool. Checking it out now.

    • Rich

      I’d recommend checking out Google’s JsTestDriver. It’s similar to jspec in that it runs via the command line, but it has much much better support for testing multiple browsers and continuous integration.

      It’s native assertions are xUnit-like, but they encourage developers to produce their own libraries that work on top of the runner. Last time I checked there are plugins for Qunit and Jasmine (which uses a similar BDD philosophy to jspec).

      Yeti has just been announced by YUI, which seems to follow a similar approach but is at a very early stage – 0.10.

      • http://brianegan.com Brian Egan

        Wow, JSTestDriver is awesome! Although I like the “init” function and jQuery hooks that are provided by JSpec, the Eclipse integration is friggin awesome with JSTestDriver.

        Also, the fact that it’s built to work with a CI tool is really helpful as well. Thanks for the heads up!

      • Rich

        Have a look at the Jasmine api, it’s very similar to jspec in lots of ways, but is more javascript like as it doesn’t use a DSL. I personally quite liked that about jspec but I know a lot of people didn’t.

        http://pivotal.github.com/jasmine/

        It also has great support for creating custom assertions to make your tests more readable. Someone’s already created a set of jquery matchers.

        http://github.com/velesin/jasmine-jquery

      • http://brianegan.com Brian Egan

        Thanks again… I’ve checked out Jasmine, but it looked so similar to JSpec that I didn’t give it too much of a look over, as I’m like you — I find the DSL of JSpec very easy to read, and you can always program it the “normal way” as well.

        I’d love a combination of JStestDriver’s awesome command-line integration + Jasmine/JSpec syntax… the readability of the JSTestDriver specs is far worse than JSpec.

        Great links, thanks a ton man!

  • http://www.jennamolby.com Jenna Molby

    Thanks for the great tips!

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Thanks, Jenna!

  • João Lopes

    Really nice. Thanks once more Jeffrey.
    Keep it up.

  • http://www.jsxtech.com Jaspal Singh

    Great, Thanks for sharing.

  • Joao Lopes

    I’m sorry for the wrong section, but how do you change the avatar? —>
    I have a premium membership and can’t seem to find where to change it.

    • http://www.rflab.co.za/ Q_the_novice
      • http://www.rflab.co.za/ Q_the_novice

        mayb not , dont know its supported

    • Nick

      I believe its a gravatar which you can change at http://gravatar.com/

    • Joao Lopes

      All right, thanks, i’ll test it :)
      Sorry for the wrong section.

  • http://Byte-News.com Ahmed CZ

    Hi Jeff is there any JS noob to ninja tuts?? cuz JS is the next thing for me to learn after CSS HTML and little bit of PHP :)
    and thanks a lot for being a great web developer and tuter :)

    • Joao Lopes
      • http://www.jeffrey-way.com Jeffrey Way
        Author

        Hey Ahmed –

        Check out the “JavaScript from Null” on Nettuts.

      • http://Byte-News.com Ahmed CZ

        @Joao: first i like to thank you for trying to help me ,but this is a jqurey lesson and i think that jquery needs a little bit of JS and i don’t that much of :) ,thanks again

        @Jeffrey: thanks a lot that exactly what i was looking for :)
        this course didn’t finished yet i see did it ??
        i only found 5 lessons is there any more ??

        and thanks again Joao and Jeffrey

  • http://www.khantony.com khantony

    hey jeffrey, check out the loading page of my website. A lot of people think that it is made by using flash or any javascript library. But the thing is it’s made by pure javascript and css. I know you can do it easily using jquery or any other javascript library but the first two page is just raw javascript. :)

    • http://Byte-News.com Ahmed CZ

      Really nice :) :)

      • http://www.khantony.com khantony

        Thanks Ahmed

  • scott

    Hey Jeffrey,

    Great tutorial as always. Is there a tutorial just on closures? If not, can you please add a closure tutorial?

    Thanks,
    Scott

  • Bogaert Dieter

    I almost always use simple alert box’es to test any variables or functions… I know that it’s probably not the professional way to do this but it seems to work fine for me. Probably for bigger projects this function would be more suited but then again why not just use the console.debug?

    I always wonder what big projects the people here on nettuts are making. personally I hardly ever have to write javascript that’s longer than 300lines of code within 1 project… Can anyone show me some of there bigger projects please? I don’t need to see the code I just wonder what type of things keeps you busy…

    • Rich

      Have a look through some of the featured javascript projects on github to get an idea of larger scale projects.

      http://github.com/languages/JavaScript

      In general, I’d say whatever the size of the project testing is a good idea, especially with a dynamic language like javascript because you can’t rely on a compiler to catch your mistakes.

  • cem

    Hi all,thnx for this nice tut. Jeff Can u send your color theme to me ? PLS :) For Netbeans

  • http://www.tamilq.com Tamil Songs

    I was searching for it .Found here. thanks.

  • http://mimwow.info/portfolio mimwow

    nice tut, thanks :)

  • kkatusic

    Great tut, I always want to build some JS for testing my code, now you give me the way to do this.

    Thx.

  • w1sh

    JS and RegEx confuse the hell out of me. I’ve watched all the screencasts and followed along, but I suppose I don’t learn unless I have some problem to work out.

    Maybe you could start providing ‘Homework’ for us like, “Create a list of animals in an array. Then use assert to test if each is a mammal or not.”

    I might be alone on this.

  • http://emeehan.com Edward Meehan

    I use the console in Firebug to do my testing… I add a bunch of console.log ()

  • someone

    Hi Jeff great JS screencast
    i have a simple question to you and it is about CSS ,if i have to divs (the ids is”a b”) and i want to make the div witch id is “b” to turn it back round color to red after i hover the “a”id div
    is there anyway to do this with only CSS ???
    and thanks

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      So, when you hover over Div A, you want the color of Div B to change? Is that your question? There really isn’t an easy way (if any) to do that with CSS. You can instead do it with JavaScript.

      • someone

        Yes that’s exactly what i want, i know i can do it with JS but i really want to do it with CSS :(
        i hope CSS3 make this happen easily, and if i can not do it with CSS3 i Hope to do it with CSS4 :) :) :)
        thanks Jeffrey that was helpful even if you didn’t give me a way to do it with CSS
        thanks again XD :)

      • w1sh
      • http://www.jeffrey-way.com Jeffrey Way
        Author

        There are tricks you can use, where, for example, Div B is a child of Div A. In those cases, you can hack a CSS method. If you need JavaScript, use something like:

        <!DOCTYPE HTML>
        <html lang="en-US">
        <head>
        	<meta charset="UTF-8">
        	<title></title>
        	<style>
        		div {
        			cursor:  pointer;
        		}
        		.hover {
        			color:  red;
        		}
        	</style>
        </head>
        <body>
        	<div id="a">A</div>
        	<div id="b">B</div>
        	
        	<script>
        		(function() {
        			var a = document.getElementById('a');
        		
        			a.onmouseover = function() {
        				var elem = next( this );
        				elem.className = 'hover';
        				
        				// OR document.getElementById('b').className = 'hover';
        			};
        		
        			a.onmouseout = function() {
        				var elem = next ( this );
        				elem.className = '';
        				
        				// OR document.getElementById('b').className = '';
        			};
        
        			// Find next sibling that isn't
        			// a text node. 
        			var next = function( elem ) {
        				do {
        					elem = elem.nextSibling;
        				} while ( elem.nodeType !== 1 );
        				return elem;
        			};	
        			
        		})();
        	</script>
        	
        	
        </body>
        </html>
        
      • http://www.jeffrey-way.com Jeffrey Way
        Author

        Right – like I said, there are “hacks” you can use — but most of the time, they aren’t real-world applicable, and can force you into writing poor markup.

      • w1sh

        JW. That markup is horrible. :)

      • someone

        @w1sh thanks that was helpful but i only hope to do it without using a child div
        @Jeffery thanks another time for helping me, well i know the child trick, but i only hoped that i can do it without using this trick because if i used a position:relative on the parent div the child div wont display :(
        i hope W3 develop CSS to be some thing like this :
        #a:hover{
        background-color: blue
        #b{
        background-color: red
        }
        }

        and that code will make #a blue when hovering on it, and make #b red when hovering on #a,what do you think isn’t this such a great idea :)
        i really hope W3 make it that will make CSS more flexible and easy :)
        thanks again w1sh and JW that was really helpful

    • Nikolai

      Hello there :)
      You don’t really need css3 to do this, try this:

      #a, #b {
      width: 100px;
      height: 100px;
      background-color: black;
      cursor: pointer;
      color: white;
      font: bold 20px/100px Arial;
      text-align:center;
      }
      #a {
      position:relative;
      }
      #b {
      position:absolute;
      top: 0;
      left: 120px
      }
      #a:hover #b {
      background-color: red;
      }
      #a:hover #b:hover {
      background-color: black;
      }

      A
      B

      • Niolai

        my markup isn’t there :),
        but the idea is you put div#b into div#a, and it should do it

      • someone

        Hi Nikolai,
        that well work but the html need to be like this :

        and that’s mean that “b” is “a”child and i don’t want that
        double check the previous comments and you well get it ^_^
        Note:
        #a:hover #b:hover {
        background-color: black;
        }
        is useless because you can’t hover on both of “a” and “b” in the same time (you may do it if you have a parent div for both “a” and “b” and sitting it position for relative, but seems that you didn’t do that XD) thanks anyway :)

  • w1sh

    Totally irrelevant to this post but I thought everyone should know what’s going on in my life right now so…

    I ffffinally splurged a whooping $9 on a Premium membership.

    There is a ton of content there. Like.. it’s reeeally nice. Instantly have access to hundreds upon hundreds of tutorials and screencasts… I don’t even… so… jeez.

    Few things I wish were different:
    - Videos and tut .zips had some sort of naming convention. screencast.flv and tut_fe2.pocketemail.zip make it hard to just download everything and shove it in a folder for later viewing.
    - Wish there was a way to just download everything in the above mentioned formatted way, in one huge .zip that was broken up into 3 or 4 .zips.

    Valid complaint:
    - When I view the videos in your inline FlowPlayer, it automatically expands the video to a fixed height that is taller than my viewport, and I’m on 1440×900! This denies me use of any controls and cuts off a portion of the video. Something needs to be fixed with that.

    Overall opinion:
    I can’t believe how much stuff is on there. A tut or two every week really adds up. There are literally hundreds of tutorials and screencasts.

    Thanks a lot guys for making Nettuts.

    Oh, and MOAR PYTHON TOOTS!!!

    • me

      I second that: more Python tutorials would be great!!

  • http://c10mediasolutions.com doctor carter

    nice tutorial, I’ve been looking for something like this forever

  • Pipps

    This is great, I like firebug but sometimes console.log doesn’t seem to work for me. This seems much nicer than using alerts, which is what I would normally do.

    In your example, I understood why it was necessary to pass “i” to the function you created at the end, but why is “(i)” also needed at the end of the loop? I’m not familiar with using a function and a for loop this way, am I missing something?

  • https://gist.github.com/3773871 Keith

    Hey! Thanks for the article! I modified your example a bit and Gisted an assert helper that creates a fixed viewing pane over the browser window, so it won’t intrude on your content.

    https://gist.github.com/3773871

  • Stacey Tipton Reiman

    Great article! I just wanted a quick way to turn my current console.log and toastr alerts into real tests, as extracting all of these out and creating real unit tests would be a huge pain, and since this is an app, not a web app, I really do need an integrated test to see if the app is failing as a whole. For me this article showed me how to create my own embedded testing system, which will be easy to comment out later. Grazie!