Jon Kruger -
  • About Me
  • Blog
  • Values
  • Presentations
About Me
Blog
Values
Presentations
  • About Me
  • Blog
  • Values
  • Presentations
Jon Kruger
TDD

TDD Immersion – 1/2 day of TDD in .NET, for free!

TDD Immersion is a half-day session where we’ll cover what you need to know to do TDD on real .NET projects. We’ll go over stuff like:

  • How to write tests first
  • How to refactor your code to make it easier to test
  • Mocking frameworks like Rhino Mocks
  • Dependency injection – what it is, how it works, and how to set it up in your project
  • TDD tips and tricks

We’ll also walk through a sample ASP.NET MVC web app and show you how you might set up an actual project, work with ORMs and data access layers, set up your test projects, and make things easy to test.

This will take place on April 21 from 8:30-12 at the Microsoft office on Polaris Parkway in Columbus. We’ll have food and drinks for breakfast, so show up a little early to get something to eat. We’ll start promptly at 8:30.

If you plan on coming I need you to register so that we make sure that we have enough room and food for everyone.

We won’t be doing any hands-on coding this time, so you don’t need to bring your laptops. There is no wireless access at the Microsoft office.

February 8, 2011by Jon Kruger
TDD

Slides from my TDD in Action talk at CONDG

Since some of you asked, here are the slides from my TDD in Action talk at CONDG last week.

January 31, 2011by Jon Kruger
.NET, Speaking, TDD

I’m speaking on TDD at CONDG on 1/27

I’ll be speaking on test-driven development at CONDG on Thursday, Jan. 27 at 6pm. I’ll show you some live TDD coding and explain how TDD can help you write awesome code and eliminate defects. Hope to see you there!

January 18, 2011by Jon Kruger
BDD, Cucumber, Ruby, TDD, unit testing

Using Cucumber for unit tests… why not?

It seems that the accepted way to test in Ruby is to use Rspec for unit tests and to use Cucumber for acceptance tests (higher level functional testing). After doing a little bit of Cucumber, I’ve started to fall in love with the format of Cucumber tests.

Most Rubyists would probably agree that behavior-driven development is good (in other words, writing tests in a Given/When/Then format). We obviously do this in Cucumber (there isn’t much choice), but I’ve also written tests in this format in Rspec and in .NET.

I like BDD for two main reasons. First, I believe that software development is a series of translations. I want to translate business requirements into readable, executable specifications, then translate that into tests, then translate that into implementation code. Second, before I implement a feature and even before I write my tests, I try to write out what I want the code to do in English. If I can’t write out what I want to do in English, how and I supposed to know what I’m supposed to write in code?

Here’s my theory: if we agree that BDD is good, why don’t we write our unit tests in a format that is more amenable to BDD, that being the Cucumber format of tests? I’m not saying that we write acceptance level tests instead of unit tests, I’m saying that maybe we should write unit tests in a different format. Not only that, Cucumber tables give us a nice way to write more readable, data-driven tests. Here are a couple examples from the supermarket pricing kata (in Rspec and Cucumber).

Cucumber:

Feature: Checkout

  Scenario Outline: Checking out individual items
    Given that I have not checked anything out
    When I check out item 
    Then the total price should be the  of that item

  Examples:
    | item | unit price |
    | "A"  | 50         |
    | "B"  | 30         |
    | "C"  | 20         |
    | "D"  | 15         |

  Scenario Outline: Checking out multiple items
    Given that I have not checked anything out
    When I check out 
    Then the total price should be the  of those items

  Examples:
    | multiple items | expected total price | notes                |
    | "AAA"          | 130                  | 3 for 130            |
    | "BB"           | 45                   | 2 for 45             |
    | "CCC"          | 60                   |                      |
    | "DDD"          | 45                   |                      |
    | "BBB"          | 75                   | (2 for 45) + 30      |
    | "BABBAA"       | 205                  | order doesn't matter |
    | ""             | 0                    |                      |

  Scenario Outline: Rounding money
    When rounding "" to the nearest penny
    Then it should round it using midpoint rounding to ""

    Examples:
      | amount | rounded amount |
      | 1      | 1              |
      | 1.225  | 1.23           |
      | 1.2251 | 1.23           |
      | 1.2249 | 1.22           |
      | 1.22   | 1.22           |

Rspec:

require 'spec_helper'

describe "Given that I have not checked anything out" do
  before :each do
    @check_out = CheckOut.new
  end

  [["A", 50], ["B", 30], ["C", 20], ["D", 15]].each do |item, unit_price|
  describe "When I check out an invididual item" do
    it "The total price should be the unit price of that item" do
      @check_out.scan(item)
      @check_out.total.should == unit_price
    end
  end
end

  [["AAA", 130], # 3 for 130
    ["BB", 45],  # 2 for 45
    ["CCC", 60],
    ["DDD", 45],
    ["BBB", 75], # (2 for 45) + 30
    ["BABBAA", 205], # order doesn't matter
    ["", 0]].each do |items, expected_total_price|
    describe "When I check out multiple items" do
      it "The total price should be the expected total price of those items" do
        individual_items = items.split(//)
        individual_items.each { |item| @check_out.scan(item) }
        @check_out.total.should == expected_total_price
      end
    end
  end
end

class RoundingTester
  include Rounding
end

[[1, 1],
  [1.225, 1.23],
  [1.2251, 1.23],
  [1.2249, 1.22],
  [1.22, 1.22]].each do |amount, rounded_amount|
  describe "When rounding an amount of money to the nearest penny" do
    it "Should round the amount using midpoint rounding" do
      RoundingTester.new.round_money(amount).should == rounded_amount
    end
  end
end

A couple things stand out to me when you compare these two. First, if I want to run data-driven tests with different values, the Cucumber syntax is so much cleaner and more descriptive. Second, the “Given I have not checked anything out” section in the Rspec version is really long and contains two nested “describe” sections (many times you end up with many more than this). When you nest sections like this, it’s really hard to see the context of things or read the tests because the “Given” text is nowhere near the nested “When” sections in the code.

Rspec follows in the footsteps of previous unit testing frameworks that write test methods in test classes (or in the case of Rspec, something that resembles test classes and methods. But is this the best way, or just the way that we’re used to? We have been writing unit tests this way for years and years because we had no other choice. But that doesn’t mean that it’s the best way.

Here are the benefits I see of using the Cucumber syntax over Rspec:

  • The tests are much easier to read (especially when doing data-driven “scenario outline” tests).
  • The Given/When/Then text is all in one place (as opposed to spread out and mixed in with code).
  • It forces me to be able to write out in English what I want the code to do.
  • Any step definition that I write can easily be reused anywhere in any other Cucumber test.
  • The code just looks cleaner. I’ve seen a lot of messy Rspec tests.
  • Rspec doesn’t have a method that corresponds to the “When” step (unless I’m missing something), so you have to shoehorn it into before(:each) or the “it” method. (I’m not sure why this is, we figured this out in the .NET world long ago.)

To be fair, there are more BDD-friendly flavors of Rspec (like rspec-given). This helps you write tests in Given/When/Then format, but I still feel like all of the underscores and symbols and syntax is getting in the way of the actual test verbiage.

Favoring Cucumber is my personal preference and I know that there are some people that would probably disagree with my opinion on this, and that’s fine. But I’m really enjoying what Cucumber brings to the table, both in terms of functionality and the syntax.

December 13, 2010by Jon Kruger
JavaScript, TDD

JSView: Readable, object-oriented JavaScript TDD

UPDATE: this was written before the advent of the new wave of JavaScript frameworks (Angular, Backbone, Ember, etc.). While I have moved on from using my home grown framework to these other more robust frameworks, I still agree with the concepts here, specifically that I should be able to test as much of the behavior of my UI by having a thin layer between my code and the DOM.

If you’ve tried to write JavaScript using TDD and your JavaScript deals with DOM elements, I’m guessing you’ve felt some pain. The toughest thing about writing tests against JavaScript is separating the HTML elements and the page from the JavaScript code. In the past when I’ve done this, I’ve created JavaScript classes and either passed UI elements into the constructor or by calling a method. So in the real page, I’ll have code that looks like this:

$(document).ready(function()
{
    var myClass = new MyClass(document.getElementById('blah'));
});

Then in my test class, I do something like this:

module("MyClass tests");

test("Test something", function()
{
    var element = new Object();
    var myClass = new MyClass(element);
});

This works fine since JavaScript is a dynamic language, I can put any property on the “element” variable and then write tests against it, checking various properties that I know will get set on the real element (like “innerHTML”, for example).

Here’s the problem with this: if you’re writing tests first, you’re not sure what kind of elements you are going to have in the UI. Maybe “innerHTML” will get set on my element, or maybe “value”, or maybe something else. I just don’t know because I haven’t written the UI yet.

What I need it something that wraps the HTML element so that I can just call a function like getValue() and get the value, which may come from “value” in some cases, “innerHTML” in other cases, etc., depending on what kind of UI element I have.

jQuery to the rescue!

It turns out that we already have something that will wrap UI elements — jQuery. Using jQuery, we can search for elements by type (e.g. DIV, A, TR, etc.), class, or id. This works something like this:

var elements = $(‘.MyCssClass’);

This returns all elements that have the MyCssClass class applied to them. But it doesn’t return the actual elements, it returns a wrapper around the HTML element. It also turns out that said wrapper has functions like val(), html(), and text() that I can use to get the values! Just what I needed.

But I still have a problem. If I’m trying to test code that deals with 20 different UI elements, that means that I am going to have to inject 20 UI elements or test doubles into my JavaScript code. This is both ugly and painful.

A simpler abstraction

JSView is an abstraction layer that sits between your JavaScript code and jQuery/HTML so that you can write tests for your JavaScript code without having the actual page and the DOM available in a test. Instead of calling jQuery methods directly, you will call methods that will interact with jQuery in your app, but will interact with a fake replacement for jQuery in your tests. Not only that, JSView will generate methods for you so that you can easily access values and events in a readable fashion. This will allow you to truly TDD your object-oriented JavaScript before the actual page even exists!

Now I can write object-oriented JavaScript classes that look something like this:

function Calculator(element, view)
{
    if (view == null)
        view = new jQueryView('Calculator', element);

    registerObjectProperties(this, view, ['FirstValue', 'SecondValue', 'Result', 'AddButton']);

    this.whenAddButtonIsClicked(function()
    {
        this.addValues();
    });

    this.addValues = function()
    {
        this.setResult(Number(this.getFirstValue()) + Number(this.getSecondValue()));
    }
}

Now I can write JavaScript unit tests that look like this (and without the DOM in place!):

module('When the Add button is clicked',
{
    setup: function()
    {
        calculator = new Calculator(null, new ViewTestDouble());
        calculator.setFirstValue(2);
        calculator.setSecondValue(3.5);
        calculator.clickAddButton();
    }
});

test('Then it should add the values in the first two textboxes and put the result in the third textbox', function()
{
    equals(calculator.getResult(), 5.5);
});

More details can be found here. The source code is up on github. I’ve been using and refining this for two years and I’m really liking how it’s turned out. I’m very interested in any feedback that you all might have, I’ve done a lot of JavaScript over the years but I’m not quite the JavaScript ninja that some other people are.

So get busy and write some tests!

October 25, 2010by Jon Kruger
Speaking, TDD

I’m speaking on TDD tomorrow at Agile Lunchbox

I’m speaking on test-driven development at Agile Lunchbox Wednesday afternoon. The meeting is at the Quick Solutions office (440 Polaris Pkwy, Suite 500, Westerville) at 11:45pm and food is provided.

This will be a more business-focused version of the talk. There will be some code, but this is more about why we do TDD and behavior-driven development, the benefits of TDD, the theory behind it, etc. So bring your managers and PMs along too!

September 28, 2010by Jon Kruger
Agile, TDD

A TDD success story

In a month or so, my co-worker and I will be wrapping up the project that we have been working on for the last 15 months. It’s a website for a company in the construction industry that bids on jobs and then tracks the progress of the jobs, purchase orders, billing, and everything else they need to run their business. We used ASP.NET MVC, Fluent NHibernate, AutoMapper, and SQL Server 2008.

We practiced test-driven development from day one. We wrote tests for our .NET code, tests for our JavaScript code, and tests for our SQL code. Right now we have over 14,000 tests, and I think we can break the 15,000 test barrier in the next month. I can run them all in about 5 minutes.

I cannot tell you how invaluable these tests have been. First of all, our application deals with money. The users will input a bunch of data about a job and then our application will tell them how much to bid on the job. We cannot afford to have bugs in our code that would miscalculate the amount to bid on a job, because that would lead either to over-bidding (in which case they would win very few) or underbidding (in which case they would win jobs and take a big hit). It just has to work.

Second, we did not have a QA team on this project, it was just the two of us developers. Frankly, I don’t have time to go back and manually test stuff in the app or regression test it when we need to make a change and deploy something. We do have bugs from time to time, but we haven’t had any critical bugs.

Because of our tests, we have been able to get as close to continuous deployment as I would feel comfortable with. On average, we deploy 2-3 times a week. When we go to do a deployment, I usually go through the site and manually test the new features that we are about to release. If I don’t find any problems, I run our deployment (which is all automated), and 5 minutes later, the changes have been deployed. I never go back and regression test old features or stuff in areas that we didn’t change.

Since the whole test and deploy process takes only about 15 minutes, users get their changes quickly. They don’t have to wait until later in the week, or until our next scheduled release. We have reduced the cost of change to pretty much just the time that it takes to code the changes.

All of this is possible because we were diligent about test-driven development and writing good unit tests for everything. The reason that we don’t spend time regression testing is that we don’t expect anything to be broken, and it very rarely ever is. This means that we can spend more time delivering business value and less time ensuring that we didn’t break something we wrote a year ago.

I’m not writing this to say how awesome we are as developers, because anyone can write tests and have the same kind of success. Also, we could’ve cheated and not written tests and ended up with potentially costly bugs and more time spent regression testing.

This is why I practice test-driven development. You end up with well-designed code, you drastically reduce bug counts, you can release more often, your codebase stays under control, and you have a lot less stress.

August 1, 2010by Jon Kruger
Agile, TDD

Reducing the cost of change

If there’s one constant in software development, it is change. Our entire workday is spent changing things and responding to change.

Every time you write a line of code, you are changing it. You might add new features, fix bugs, or make changes to existing code. However you put it, you’ll be changing the code.

Requirements will change. You often find this out after you’ve coded a feature, and now the business either changes their mind or you find out that you made some wrong assumptions.

Business priorities will change. What was important yesterday may not be important today, and six months from now, all kinds of things might change. There could be new, more important projects on the horizon, new people in charge, or new business opportunities.

Software development teams change too. You might stay at your company for many years, but during that time, you might get moved from project to project. Developers will leave the company, and others will join. The end result is that many different people will end up working on the code that you’re writing today.

Since we know that we are going to have a lot of change, it would therefore make sense to reduce the cost of change so that we can respond to change as quickly and easily as possible. So how can we reduce the cost of change?

Automated Testing

Every time I add a line of code, I risk breaking my application. Breaking the application is just not acceptable. We’ve come to accept bugs as a part of the process, but that doesn’t mean that it’s OK to write bugs. If you’re not striving to write bug-free code, then maybe you need to raise your standards.

Nevertheless, the fact is that we all screw up and we all have the capability to create bugs. Knowing that, I want a way that I can easily test my application so that I can ensure that I find out if I broke something once I change it.

On my current project, I’m writing an application that helps my client bid on construction projects. They can’t afford to have bugs in their system that will cause them to incorrectly bid on these jobs or they could be out a lot of money. The bottom line is that it has to work because their entire business is now running on the application that I’m writing. They also come to me on a regular basis with new feature requests and things they need changed. They don’t want to wait months to get this functionality, and they also don’t want me to break any existing code.

Thankfully I have a large suite of automated tests that I can run to ensure that I didn’t break anything. This isn’t foolproof and things sneak through, but it’s usually little stuff that isn’t critical. But it’s good enough proof for me that I didn’t break the existing functionality. As a result, I can release to production daily and I spend virtually no time manually regression testing my application when I deploy. My unit test suite has reduced my cost of change to pretty much just the time it takes me to code the changes, so now I can react quickly to changes, release all the time, and I can do it without breaking existing code.

Clean Code

Sometimes people will write their unit tests, write the code to make the tests pass, and then assume that that is good enough. That’s great that you wrote tests, but how easy is it for someone to make a change in your code?

I feel that clean, readable code is very underrated these days. When you write code, are you thinking of the person that is going to need to understand what you did once you’re not around anymore? That scenario is very likely to play out at some point. So when you write code, create methods, variables, and classes that are very descriptive. Place a priority in making your code easy for someone else to read.

“Clever code” is the opposite of clean code. I’m talking about using complex algorithms to solve simple problems, trying to using a complicated LINQ statement to do an operation that would be more readable in a foreach loop, or trying to implement something in the fewest lines of code as possible. There are times where you might want to do things like this, but usually it’s more important to write code that is easier for someone else to read and understand. Again, remember that someday someone else is going to have to change your code, so write descriptive code that makes it easier for that other someone to know what to do.

Tests Are Documentation

Your unit tests are documentation of what your code is supposed to do. I practice behavior driven development, which means that my unit test methods describe some business functionality that my code is in charge of executing. This way, if someone needs to know what my code does, they can look at the test classes and methods and see what it is supposed to do.

Lately I’ve started adding a lot more comments in my test methods. The class names and methods names may describe what the code is supposed to do, but it doesn’t always explain why. I’ve found that sometimes it helps to write down the why because that is also important information. Since people can look at my tests as documentation of what my code does, I figured that this would be the best place to put the whys, because if someone has to change my tests, they’ll immediately know why I did what I did and they’ll have a reminder that they need to update my comment.

Build Iteratively

Since business priorities and requirements are going to change, we want to reduce the cost of this change too. If the business comes to you and drastically changes the requirements or certain assumptions that you might’ve made, it might be really costly and painful to change, and you can only do so much about that. What we can do is make sure that we’re constantly checking back with the business to see what they want now so that we have as few surprises and as little rework as possible.

This is one reason why Agile projects often run on iterations. As a part of this process, meet with your business sponsor every week or two and talk about what you’re going to do next. Show them what you’ve done in the last week or two, and make sure you’re on the right track. This way, if they’re going to change their minds, you’re giving them permission to do so and you can adjust what you’re doing as soon as possible so that you have the least amount of rework.

Always Be Aware of Change

Quit thinking short-term and quit shoving code in just to get it done as fast as you can. You may think you’ve done something good by getting it done faster, but if you create more work and pain in the future, it’s a net loss. Instead, always think about what the effects of what you are doing now will be two years from now. Your goal is to create business value without creating technical debt. A home builder can do shoddy construction and put nice looking paint and siding on the house, but 10 years from now when the problems arise, people won’t be thinking very highly of that builder. Don’t make the same mistake. Take pride in your work and strive to always leave your code base cleaner than you found it.

July 30, 2010by Jon Kruger
TDD, unit testing

Specs2Tests: turn those acceptance criteria into BDD tests

I had a simple problem today. I had to turn this:

When depositing money into an account
– should add the specified amount into the account

When withdrawing money from an account
– should withdraw the specified amount from the account
– should specify that the withdrawal was successful

… into this:


[TestFixture]
public class When_depositing_money_into_an_account : Specification
{
    [Test]
    public void should_add_the_specified_amount_into_the_account()
    {

    }
}

[TestFixture]
public class When_withdrawing_money_from_an_account : Specification
{
    [Test]
    public void should_withdraw_the_specified_amount_from_the_account()
    {

    }

    [Test]
    public void should_specify_that_the_withdrawal_was_successful()
    {

    }
}

I really didn’t want to do all of this typing every time, so I wrote code to do it for me. It works like this:

1) Copy the acceptance criteria text onto the clipboard
2) Run Specs2Tests.exe (will put the code onto the clipboard for you)
3) Paste the code into your code file

Now I can get all of my acceptance criteria nailed down in a text file where I don’t have the ceremony of a programming language, then let something convert them into tests. Since I just cranked this out today, I’m guessing that it doesn’t handle every scenario that you might think of, and it only writes out C# code. There is no reason that it couldn’t spit out VB.NET, RSpec, or anything else. If it doesn’t do what you want, get on github, create a fork, and send me a patch!

The code is here: http://github.com/jonkruger/specs2tests. Have fun.

May 10, 2010by Jon Kruger
TDD

TDD Boot Camp upcoming events – coming to a city near you

If you read my blog at all, you know that I’m passionate about test-driven development. A few months ago, I announced that I was developing a TDD training course called TDD Boot Camp that will teach you everything that you need to know to do test-driven development on real world .NET projects.

I currently have two upcoming events scheduled: July 13-15 in Columbus and August 18-20 in Detroit. You can find out more details on what we’ll cover and how to register at the TDD Boot Camp website. If you can’t make any the events or if you would like me to come to your company, send me an email and we can work something out where I can come to you.

If the whole idea of test-driven development is new to you, or you’re not sure why you should care, come to the Path to Agility conference in Columbus on May 27, where I’m doing a talk on Test-Driven Development In Action. I’ll show you how TDD works and how it can help you deliver IT projects with higher quality, lower maintenance costs, and more peace of mind. Actually, you should go to the conference either way, because there is an excellent lineup of sessions for anyone involved in IT.

April 28, 2010by Jon Kruger
Page 2 of 5«1234»...Last »

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...