Jon Kruger -
  • About Me
  • Blog
  • Values
  • Presentations
About Me
Blog
Values
Presentations
  • About Me
  • Blog
  • Values
  • Presentations
Jon Kruger
JavaScript, TDD, unit testing

Unit Testing JavaScript – Introduction, JavaScript basics

JavaScript and unit testing — two things that you don’t hear about in the same sentence too often.

Why is that? There are all kinds of test frameworks, mocking frameworks, etc. for .NET, and lots of emphasis is placed on the value of testing .NET code. How come you don’t hear the same about JavaScript?

Now I certainly don’t know everyone in the .NET world, but I work with lots of really smart people and talk with lots of others on a daily basis. And yet the following disturbing statements are true:

  • I had never written a line of code to test JavaScript (up until a month ago).
  • I’ve never had anyone I know tell me that they have written a line of code to test JavaScript.
  • Most people I asked didn’t know anything about what JavaScript test frameworks are out there.

How did this happen? Isn’t JavaScript code too? And isn’t it even easier to have bugs in JavaScript since we don’t have the benefit of a compiler?

The same behavior driven development concepts that apply to .NET code can also apply to testing JavaScript. It’s really not that much harder or different than testing .NET code. And since JavaScript is a dynamic language, it some ways it’s even easier.

JavaScript class syntax

Before I dive into testing JavaScript, I suppose I should go over the basics of “classes” in JavaScript.


// JavaScript class
function MyClass()
{
// private variable
var somethingPrivate = null;

// public variable
this.somethingPublic = null;

// private method
function privateMethod()
{
}

// public method
this.publicMethod = function()
{
}
}

// adds a method called doSomething to the definition of MyClass
MyClass.prototype.doSomething = function()
{
}

var instance = new MyClass();

// redefine a public method on an instance of an object
instance.publicMethod = new function()
{
}

Some comments/thoughts:

  • I like to make classes instead of using global variables and functions. Global functions work fine for really simple tasks (e.g. when a button is clicked, open another window), but if you do anything complicated, your code will be much cleaner, well-structured, and easier to test if you create classes just like you would in .NET code.
  • Don’t expose public variables. You wouldn’t expose a private field in a .NET class, so don’t expose a variable in JavaScript either. Instead, create a private variable and then create public methods to get and set the value. Exposing a public variable will open you up to all kinds of odd possibilities (such as someone assigning a function to your variable when you were expecting it to be an integer).

Next up: JavaScript test frameworks.

November 25, 2008by Jon Kruger
Quality, TDD, unit testing

The relative cost of fixing defects

I saw a very interesting chart today…

The Relative Cost of Fixing DefectsSource: http://www.riceconsulting.com/public_pdf/STBC-WM.pdf

If this doesn’t convince you of the value of unit tests, I don’t know what will. The cost to fix bugs in production could be dramatically higher than the cost to fix them in development, which is why having a suite of unit tests that you can run when you make changes is invaluable because it will prevent you from getting into these costly scenarios where you have to fix nasty bugs in production.

November 20, 2008by Jon Kruger
TDD, unit testing

Why Behavior Driven Development is good

On my current project I was introduced to Behavior Driven Development. When I first heard of BDD, I thought, “Is BDD any more than a new way to name your test methods? What’s the big deal?”

Here’s a simple unit test class that I might have written in the past:

[TestClass]
public class EmployeeTests
{
   [TestMethod]
   public void LastNameRequiredTest()
   {
   }

   [TestMethod]
   public void BirthDateCannotBeInFutureTest()
   {
   }

   [TestMethod]
   public void LastWidgetDateTest()
   {
   }
}

When I would write a test like this, the goal was to make sure that the code that I had written was working (I normally wasn’t doing TDD when writing these tests). Now there’s nothing wrong with that, let’s say that my code coverage was good, and things are good.

A BDD-style set of tests would look more like this:

[TestClass]
public class Given_an_Employee
{
   [Setup]
   protected override void Before_each_test()
   {
   }
}

[TestClass]
public class When_validating_an_Employee : Given_an_Employee
{
   [TestMethod]
   public void Then_the_LastName_is_required()
   {
   }

   [TestMethod]
   public void Then_the_BirthDate_cannot_be_in_the_future()
   {
   }
}

[TestClass] 
public void When_an_Employee_makes_a_widget : Given_an_Employee
{
   [TestMethod]
   public void Then_the_LastWidgetDate_should_be_set_to_today()
   {
   }
}

Whoa, what’s with all the classes and underscores and all that! Put your preconceived notions aside and let me explain. :)

First, let me explain why TDD is good. I think that these points illustrate this best.

1. The developer starts writing unit tests around their code using a test framework like JUnit or NUnit.
2. As the body of tests increases the developer begins to enjoy a strongly increased sense of confidence in their work.
3. At some point the developer has the insight (or is shown) that writing the tests before writing the code, helps them to focus on writing only the code that they need.
4. The developer also notices that when they return to some code that they haven’t seen for a while, the tests serve to document how the code works.
5. A point of revelation occurs when the developer realises that writing tests in this way helps them to “discover” the API to their code. TDD has now become a design process.
6. Expertise in TDD begins to dawn at the point where the developer realizes that TDD is about defining behaviour rather than testing.
7. Behaviour is about the interactions between components of the system and so the use of mocking is fundamental to advanced TDD.

First you begin to write tests because you want to make sure your code works. But as you get into TDD, you realize that TDD really can be more about design than testing. If you can define acceptance criteria up front, you will be forced to think about what your code is going to need to do and design it accordingly.

BDD takes the next step. First your tests were just testing your code, then they were designing your code, and now they are describing what the code is doing. This is where the weird class and method names come in. Let me write out those tests again, translating it from C# into real world language.

Given an Employee, when validating an Employee, then the LastName is required and the BirthDate cannot be in the future. When an Employee makes a widget, then the LastWidgetDate should be set to today.

Here is where the light bulbs clicked on for me. My tests aren’t just testing my code, they are telling a story. Imagine if you were taking this code over from me and you wondered, “What is important about an Employee?” You could look at my tests and you would know exactly what is important about an Employee. You would immediately know what all of the acceptance criteria were for working with an Employee. So now you can go and change my code and have a good sense of what I was trying to make my code do!

I think by now you can see how TDD and BDD will go hand in hand. It should go something like this:

1) You get your requirements. In the requirements are a list of business rules or acceptance criteria.
2) You write your tests (or at least the classes and methods). Now you’ve translated those business rules and acceptance criteria into tests.
3) You write your code. You already have a suite of tests that you can run to know if you succeeded!

Of course, you may go back after the fact and write even more unit tests that focus on testing more granular parts of your implementation than just the overall business rules.

If you don’t like all the funky underscores that I put in the class and method names, then that’s fine. That’s just how we did it on our project (it’s all this guy’s fault). I like them because it really does help the names to read more like normal human sentences, which is much more valuable that I had originally thought.

TDD and BDD are a definite paradigm shift for a lot of people. But once you get used to it, you will never go back.

July 25, 2008by Jon Kruger
Page 5 of 5« First...«2345

About Me

I am a technical leader and software developer in Columbus, OH. Find out more here...

I am a technical leader and software developer in Columbus, OH, currently working as a Senior Engineering Manager at Upstart. Find out more here...