Writing Testable JavaScript

by Rebecca Murphey

30 Reader Comments

Back to the Article
  1. Another great article with perfect timing, when “Write Unit Tests” just so happens to be near the top of my TODO list.  Thanks ALA!
    Copy & paste the code below to embed this comment.
  2. Great article.  I think its important to note that a lot of the success in this kind of testing is by partitioning the web page into small, independently operating ‘modules’ of functionality.  Doing so not only makes the code small, removes complexity and reduces the cost of testing that ‘module’ but also affords the necessary isolation…  isolation for the purposes of integration testing yes but also for the purposes of design, QA, user testing, and delivery (really the full life cycle can be completed on each) of that ‘module’ independent of the other ‘modules’ of the application.  For example, its common practice to want to design all the ‘modules’ up front to see how they’ll layout and interact but there is value in building the ‘modules’ independently.  The completion of each doesn’t just mature the app incrementally but also the understanding and long term success of the steps involved in the creation of each ‘module’.  The great thing is that the ‘modules’ can be in various stages in the life cycle and you can correct course as necessary, and if you do not much lost.  We’ve had a lot of success with developing, testing and delivering like this.  And while the app, not be entirely complete at any given stage, its always operational and IMHO shippable.
    Copy & paste the code below to embed this comment.
  3. Andrew, so glad to hear that this was timely! I think a whole lot of people are finding that tests are going to be an important part of their workflow going forward, so hopefully this helps you get started. You may also want to check out the talk I gave about this at the 2012 Full Frontal conference.
    Copy & paste the code below to embed this comment.
  4. Schon, I can’t agree enough with what you said. The key to successful applications, no matter the language or whether it’s in the browser or somewhere else, is to solve lots of small problems, rather than one enormous, tangled problem. For client-side applications, the smallest unit of functionality is often something that you can draw a box around in the visual presentation of the application. I’ve found that when I approach client-side apps in terms of lots of tiny boxes that operate independently, glued together by application code that knows very little about how any given tiny box works, then life is simpler indeed :)
    Copy & paste the code below to embed this comment.
  5. Outro artigo muito bom do A List Apart! Vale a pena pra quem gosta ou trabalha com javascript.
    Copy & paste the code below to embed this comment.
  6. I agree that the second coding style presented in the article is a huge improvement. For complex Web Apps however, you might consider a client-side MVC framework like AngularJS, which incidentally has built-in support for unit tests.
    Copy & paste the code below to embed this comment.
  7. mb21, agree that moving to an MV* framework such as Angular, Ember, Backbone, etc. will really help with the testability of an application. What I have found, though, is that a lot of people can’t make that leap from day 1, and figuring out what the “baby step” is to start incorporating testing proves difficult. Writing code in the style I presented is the first step, I think, and a much more realistic one for entrenched projects that can’t easily have some Angular sprinkled on them. Once you’ve written code in this style, though, it becomes much easier to see how a more robust tool could be incorporated. What I hate to see is people who dive into Backbone, Angular, or another more complex tool without understanding *how* it will help them solve their problem, or without understanding why or whether it’s even the right tool for the job. Learning a new coding style can help smooth that process.
    Copy & paste the code below to embed this comment.
  8. @Rebecca, I see :)
    Copy & paste the code below to embed this comment.
  9. I don’t understand what the colored bars that appear under the heading “Organizing our code” refer to?
    Copy & paste the code below to embed this comment.
  10. Great article and fantastic ideology! The only thing that bugged me was that the code samples don’t have syntax highlighting, which makes for a terrible reading experience. Of course that’s a A List Apart bug and not related directly to this article - just thought I should put it out there.
    Copy & paste the code below to embed this comment.
  11. Thank you for a fantastic article! Have used QUnit quite a bit and just this week trying out Mocha/Chai with Grunt. Seeing a practical example of how to refactor/approach unit testing and not just write unit tests themselves is incredibly helpful!
    Copy & paste the code below to embed this comment.
  12. Bob, apologies for the confusion regarding the colored bars. The idea was to show how different pieces of the original code were responsible for different things, and how all of those responsibilities were intermingled with each other.
    Copy & paste the code below to embed this comment.
  13. It’s very rare to see articles that discuss testing (particularly browser JavaScript) in such an approachable way. I think this often happens because example code is written in a testable way, however provides no bridge to help fix existing problems. It is refreshing to see an article that makes this connection. Great post, Rebecca!
    Copy & paste the code below to embed this comment.
  14. Aw thanks Nate :) When I started thinking about my presentation last Fall, I realized that if I started with the tests themselves, a lot of people would go home thinking “that’s nice, but my code doesn’t look like that and I can’t imagine how to get there.” On my personal path of learning to be good at JavaScript, I found that once *I* understood the stuff I explained in this article, thinking about testing—and writing JavaScript in general—just got vastly easier. I wanted to write it down in hopes that others might have some of the same “ah ha!” moments that I did.
    Copy & paste the code below to embed this comment.
  15. Cool. Very cool. I love the mocha/chai/sinon combo. Do you have any advice for testing RequireJS / AMD?
    Copy & paste the code below to embed this comment.
  16. Craig, there’s not a whole lot that’s different about testing with RequireJS/AMD. If you take a look at the repo for the project in this post, you’ll see that it makes use of RequireJS. Generally it’s just a matter of having a test-specific config that points to the test files and the core files, and the rest is pretty straightforward. For cases where you need to mock dependencies, Squire.js is a very useful and actively developed tool.
    Copy & paste the code below to embed this comment.
  17. Any chance you could publish the code? I’ve tried to follow along with this and Mocha just isn’t playing. Their site doesn’t particularly help because its favoured “describe” syntax seems unintuitive, is explained badly, and doesn’t match your test construction. When I try running mocha using “setup” and “test” it just complains that they’re not defined…
    Copy & paste the code below to embed this comment.
  18. Great article. Biggest problem I’ve had with searching on Javascript testing is they are lots of examples on how tests work, various frameworks, assertions with trivial examples etc etc which is all easy but non seem to go further in to the real world on how to design frontend components as you described in a testable way.
    Copy & paste the code below to embed this comment.
  19. Performance is typically the reason I segregate “unit” tests from “functional” tests
    - by melissa from LionLeaf
    Copy & paste the code below to embed this comment.
  20. Jo Pearce: There’s a link in the paragraph right before the last code sample to a repo that contains a finished version of the project :)
    Copy & paste the code below to embed this comment.
  21. great article!
    one remark though, in snippet#11 you use deferred.pipe() which is deprecated as of jQuery 1.8 - should use .then() instead.
    http://api.jquery.com/deferred.pipe/
    cheers
    Copy & paste the code below to embed this comment.
  22. Good read!
    Here’s my remix of your post, test driven style. Please share your thoughts about it! http://davidvujic.blogspot.se/2013/06/from-streets-of-test-driven-development.html
    Copy & paste the code below to embed this comment.
  23. Love the article! LOVE IT!! That is probably the best piece on JavaScript I have read in recent months. I also totally agree with your comments that people jump into Backbone etc without understanding, not a good idea. IMO this article is a must read for someone with (lower) intermediate JS knowledge like myself. also love the colored bars explanation. I had no problems understanding but maybe small “legend” would help as I understand if someone reads it in a hurry might get confused with colors
    Copy & paste the code below to embed this comment.
  24. Gianna. I agree that Clifford`s st0rry is shocking… on sunday I got a great new Acura since I been making $7686 this-past/month an would you believe 10-k last-munth. it’s by-far the most-financially rewarding Ive had. I actually started five months/ago and right away began to earn minimum $84 per/hr. I follow instructions here,, http://m3mi.com/3621CHECK IT OUT
    Copy & paste the code below to embed this comment.
  25. Beautifully articlated! Recently, I have been authoring a light weight Dependency Injection framework called WinterJS with the primary objective to allow developers to author testable code. It would be great to get some feedback on this.
    Copy & paste the code below to embed this comment.
  26. Perfect! To be honest, I’m not good with JavaScript, but after reading I can’t also say that I’m good. You just give me a picture of how does it works. Thank so much! http://www.launchevity.com/home
    Copy & paste the code below to embed this comment.
  27. This is a well written article, but I feel that if you are going to write an article about javascript you should write the examples in javascript. Not everyone is going to be using the same framework/library as you, so for universal understanding it would be best to write examples in vanilla javascript.
    Copy & paste the code below to embed this comment.
  28. I like the event sharing across $document part, have event handle delegate is the key to js component decoupling.
    Copy & paste the code below to embed this comment.
  29. How to distinguish the private methods or public methods?  Although some methods have ‘_’ underline tag, but in fact, all of these are public method. For example “SearchResults.prototype._handleClick = function (evt) {**}”. Can you give some suggestions, thank very much!
    Copy & paste the code below to embed this comment.
  30. I think what has been demonstrated here is something pragmatic and practial not entirely elegant. Because, the test codes here are kinda unit & integration test married together. I prefer to write my unit tests without DOM and CSS selectors; this needs dom/css isolated code, **mostly**. But, I still could not find a great way to do that. If any of you already did that please let me know.
    Copy & paste the code below to embed this comment.