Blog logoMatthew Lang

TDD

A 5 post collection


To TDD Or Not To TDD

 •  Filed under By Me, TDD, Dev Life

Skipping the TDD cycle isn't always a bad thing to do. After all, sometimes you just want to write code.

Over the holidays I had some free time. An idea has been in my head for most of the year, but I never got round to scheduling anytime to work on it. I decided now was the chance to throw something together to see if this idea was worth exploring. To change things up a bit I decided to not follow my usual practice of TDD. Some might call that laziness and that might have been a minor factor, after all it was the holidays and this was just me trying something out, but the major factor in skipping TDD was that I had the knowledge to build the application quickly. Over the course of a couple of days I put together the first attempt at implementing this idea.

Aside from a couple of typos and minor bugs, the application is working fine and doing its job. The bugs were just oversights made by myself during those two days and they were easy to fix once found. I'm not surprised by the this as it is a simple application comprising of some basic CRUD operations and a single Rake task. Once everything was looking good, I deployed the application so that I could see it running for a few days. After a week it was clear that all was in working order. I've shared the idea with a couple of people who have so far been positive about it.

Now being a good developer I mostly write tests before I write code. It's the TDD way. This time though I skipped the tests in favour of getting something basic up and running. I had the knowledge and I ran with it. It was supposed to be just a prototype after all.

In the past I've stuck with using TDD when building even the smallest of products. At that point in my career however I was a less experienced developer. I was still figuring things out. The tests made sure that everything was working as I stumbled through different parts of the product. Now though, I have the knowledge and confidence to throw small web applications together without writing tests to in order to explore simple ideas for web applications.

Is it still a prototype then now that it has been shipped and is being used daily? Yes and no. The line between prototype and product is definitely blurred here. I would have to say that until the code itself was backed by a test suite, it's still just a prototype, an idea. So why not trash the code I have at the moment and start again from scratch using TDD?

I could, but I already know what code I need to write. Do I really want to scrap the whole thing knowing that I'm just going to write similar code again? In an ideal world I would probably do this but I knew it would be a while before I got free time like this again. The next obvious step then would be to add tests to the prototype and gradually refactor this code into something more stable. Something ready for the masses.

TDD is still a great practice to follow when writing software, but I think there's a time and a place for it. When writing software as part of your job, for a client, or as a contribution to an open source project, then yes, TDD should be used in these cases, especially if they are expected of you. However, when you are exploring code, ideas and simply playing around then I think it's down to yourself to decide. And if you decided not to TDD, don't sweat it.

TDD might be advantageous when learning a new language or framework but when you have the knowledge to build something quickly then why not. If it's worth pursuing further then start writing tests for the code that you have before things start to get more complicated.

Reading Redmine: Multiple Assertions Per Test

 •  Filed under By Me, TDD, Redmine

In an effort to brush up my development skills I've been reading the Redmine source code this week. I've been curious to find out about examples of Rails applications that use Minitest.

Ever since I suggested a move away from RSpec for projects with my clients, I've been curious about real world examples of using Test::Unit/Minitest to test a Rails application. It was clear from a search of Rails applications on Github that RSpec was the preferred choice for many applications. However, after reading an email newsletter from developer Eric Davis, the RedMine project sprung to mind so I decided to check it out. Sure enough, it was the sort of application I was looking for. A mature code base using Minitest as the test framework. A few interesting points stood out which I'll cover over the next few weeks, but for today I'll talk about Redmine's multiple assertions per test.

I was always led to believe that tests ahould only contain one assertion per test. It was ingrained into me from reading countless books on TDD and hundreds of blog posts on the topic. The thing is I never questioned why this was so. It was clear from seeing the RSpec syntax why it was a benefit.

before do
  get :index
end

it "must respond with a success code" do
  assert_response :success
end

it "must render the index view" do
  assert_template :index
end

it "must assign the users journal" do
  assert_not_nil assigns(:journal)
end

If your test (or 'spec' in this case) has one assertion and it fails then you know exactly what went wrong. Multiple assertions in a single test have always been frowned upon.

When I started using MiniTest as the test framework for a couple of Rails applications of my own, I started to write multiple asserts per test.

def test_index
  get :index

  assert_response :success
  assert_template 'index'
  assert_not_nil assigns(:journal)
end

It was discomforting to do but only from the view point that I had believed for so long that multiple assertions per test was wrong. However when I read the Redmine source code I was pleased to see that not only was the application not using the RSpec, it was also using multiple assertions in a single test. After an hour of reading through other tests in the code base I could see why it was done. The layout of the tests in Redmine are flat. Often there's just a single setup and teardown method and a list of tests. It makes it much easier to read.

RSpec has a number of advantages in that tests can be nested in different contexts and within each context you can define a before block to setup anything needed for the tests that follow. This can result in heavily indented code and with the practice of one assertion per test it can lead to a lot of tests relying on a number of different setup methods higher up in the test file. This can be difficult to read if a test file has a number of contexts within it.

It's re-assuring to see that while many developers might point out the benefits or reasons why we do one assertion per test, it's not a rule that is set in stone. You can include more than one assertion in a test, as long as it's a reasonable number of assertions.

Is it worth writing seperate tests for each of these or is it better to simply bundle them into a single test?

I'll leave that for you to decide. There's no right or wrong answer in my eyes. If I was still using RSpec I probably would still write one assertion per test out of habit, but having a flat layout using Minitest does make it easier to read and having multiple assertions isn't going to make it any harder for me to test my code and debug any problems.

Am I Doing This TDD Thing Right?

 •  Filed under Posts, Programming, TDD

I've been building web applications in Ruby, on a full-time basis, for a couple of years now. During this time I've been exposed to a number of different testing strategies and approaches. Test-Unit, MiniTest, RSpec, Cucumber, Steak and many more. I've used many of these test frameworks to some extent, but despite the many choices I have in this area, I'm still befuddled by the right tools to building a web application in Ruby using test driven or behaviour driven development. The Rails framework has shipped with Test-Unit for years but the most popular testing framework is probably RSpec.

In order to quell my confusion, I thought I would expand on the three approaches that I have used most often in my time using Ruby.

1. The True Agile Approach

Perceived by some as the holy grail of testing, and in some cases with an equally preachy opinion, is the true agile approach. Being part of an agile team with a customer on hand to flesh out user stories, daily stand ups, retrospectives. Just about everything that embraces an agile approach to building software.

In this approach, test driven development and behaviour driven development tools reign supreme. If your approach is TDD, you'll most likely be using RSpec or Test::Unit for testing all aspects of your web application. If your approach is BDD, then it's Cucumber all the way. This is pretty much a no brainer really. With so many hands available for development, it makes sense to always write tests first.

2. The Solo Developer Approach

The true agile approach is fine when you're part of a team, especially when that team advocates pair programming and you have a customer on hand to flesh out user stories. What if you're a developer with your own product or service though? You understand the business domain enough to eschew the behaviour driven development approach but you still want to test your product?

I had this problem with the early iterations of Journalong. I understand the business domain, so is it really necessary to use a BDD approach? Can I simply just switch to a TDD approach with Test::Unit or MiniTest?

I'm still on the fence about this.

3. The Side Project Approach

This is simple, and I embrace this approach 100%. No testing framework or just enough tests to handle the complicated stuff. Hacking on your own ideas is a good time to really explore the frameworks and languages you are doing. Getting these setup correctly with all the proper test frameworks can be a chore though. If it's just an initial idea or throwaway solution you're working on then why bother investing the time in writing tests?

I want to be a good developer and develop solutions that are thoroughly tested but when was the last time you just hacked on a bit of software to try something out? If I know enough of the framework and language to get by then I don't bother writing tests. It might take me an hour to come up with something or half a day, but if that's all it takes then why bother getting all the correct bits in place to test it.

There's definitely a time and place for testing strategies in development, where you're part of a team building a product or building a revenue generating product or service on your own, testing strategies can give us the confidence we need to ship code on a frequent basis.

For my own ideas though I would rather roll my sleeves up and get into the parts of the code I know or even try new things with a part of the language or framework I haven't used. Kind of like code exploring, filling in the blank edges of the map if you like.

The long path

 •  Filed under TDD, Programming, Posts

Test-driven development (TDD) is often seen as the long way to developing software. The misconception perceived by many is that writing tests and code is going take longer than simply writing code. While this statement is in fact true, many don't take into account the what's happens further down the development process.

Developers that practice TDD are continually writing tests to ensure that all parts of the software work. This practice reduces the chances of bugs appearing in the code in a later date. Developers that don't practice TDD are writing code that is usually handed to another team for testing. Chances of the code containing bugs at this point are quite high, and so a game of ping pong ensues with the code moving between the developers and the testers until it is working. This can ultimately take longer than the time it took a developer to produce the same code using TDD.

Selling TDD to clients is difficult because they don't see the benefit of this practice. Clients want their product and the want it now. Writing tests takes too long. It puts the developer in a difficult position. Do you take the gig and hope to squeeze in the tests as your developing and hope the client doesn't notice? Or do you take the gig and forgot about the tests knowing that future work will come back to you in the form of bugs that the client has discovered? Of course the last alternative is to not take the gig at all.

The long path that clients see when they are told about TDD isn't as long they think it is. In fact it is actually worth their while to spend the time investing in tests that ensures their code for their product or service continues to work in the future. Following the path of not writing tests might look like the short path to start with but there's no guarantee that it will stay that way.

TDD with your MVP

 •  Filed under TDD, Lean, Products, Posts

Should you TDD your MVP?

This question came up on the Hacker News website a few days ago. Reading through the comments there was a very mixed response as what people preferred to do.

First let me describe a couple of things for readers of a non-programming persuasion. TDD (or test-driven development as its more commonly known) is a way of writing code. Essentially it boils down to writing a test for the code that we are about to write. This test fails until we implement the correct code to make it pass. The MVP mentioned here is a minimum viable product. This is the simplest implementation of a product that will deliver value.Got the acronyms sorted? Okay, let's crack on.

I have built a couple of MVP's with test-driven development. I have to say that using TDD to drive the product worked well for me. It gave me the confidence to ship the product once I knew it working. And that really for me is what an MVP is all about. Shipping the simplest thing that can work. We know it is working as we have the tests to prove it and from working code we can then be confident in shipping a product that provides value.

An MVP without tests is simply a throwaway application in my eyes. It's code that serves a short term purpose such as learning something new or proving a simple technique.Others might argue that this is exactly the point of a lean startup. To test an idea. However in order to test that idea for a product we need to have something that the product can offer the customer, and that needs to be value that the customer can see. Value that you can certify is working correctly.

Each to their own really, but I'll keep TDD'ing my MVPs in the meantime.