Tuesday, December 4, 2012

By now you've probably read and heard a lot warning you off testing through the UI and testing the user interface generally. Those still holds true for Javascript so you may be wondering if there is anything left to test. Time for some code!

Now we have a testable function isFormValid. It’s an example of separating the logic from the UI and the DOM interaction. There is still a DOM element being used but that’s fine as it is easy to create or perhaps mock in writing the test.

This code is still testable despite using some jquery magic. It’s easy to mock out jquery or fake events and DOM enough to test it. Do not test this code. There is no real logic in there and it’s heavily tied to the UI interaction. This may mean a lot of the Javascript you’re writing does not have tests and that’s okay. Interactions like this are still best tested manually and if they fail in a harmful way will be obvious to anyone using the system. Logic errors however can be much harder to spot through manual testing.

I love closures and closures like this are still really easy to test. Just as I would still expect you to create private methods and properties when doing TDD in C++ or Java. In Javascript I would still expect you to write closures to help build your code into clear abstract interfaces. But as with private methods and constructors you need to avoid hiding everything in closures.

This may seem harder to test. We've introduced expections that we’re using jquery and put everything within a function that does not return anything. But it’s actually very testable since we can easily mock out all the objects that we send in and trigger and test those actions through those mocks. Because objects are cheap and easy to construct that means it’s cheap and easy to mock things out.

Next timeRunning tests with Jasmine and your web browserThis is part of a series I'm writing for Agile+ on Google+ so you can follow as I post them there

Monday, November 26, 2012

I've had a few opportunities to put my TDD skills to use in this brave new frontier. So I wanted to share what I've learned, what pitfalls to avoid and where the low hanging fruit is.

Why use TDD in Javascript?We've reached a point where few people can develop an application without there being a web interface included. And now it's not enough to build a website with a few forms and buttons it has to be a "web application" with the detailed user interface and responsiveness we would expect of a desktop application. Javascript is serious business. Clients are not going to compliment you on your stable and fully tested backend if the UI is painful.

When should you not use TDD in Javascript?Javascript has a strange distinction. It is the most widely used programming language in the world. It is also the most disliked programming language in the world. It can be hard to get programmers to learn Javascript before they dive into writing Javascript. So you cannot expect unit tests in that environment. It may be that your programmers are just copying the latest jquery plugins and performing wonders while writing very little Javascript If there’s very little Javascript being written then there’s no point trying to automate the testing.

Okay. So do I test in Selenium or Watir?Wait just a minute now! Those are not unit testing frameworks. They can be great for integration testing to see the behaviour with the DOM and a backend. But TDD requires unit tests that are fast to write and fast to run. I’m going to use Jasmine but there’s lots of other unit test frameworks to pick from and I’ll walk through the ways to run it on a console, through a browser and distributed through many browsers.

Next timeWriting testable javascript and what not to testThis is part of a series I'm writing for Agile+ on Google+ so you can follow as I post them there

Wednesday, September 12, 2012

I haven't been completely idle. Appart from my rambings on twitter and google+ I've also been making regular posts to a new facebook group on Agile Software Development.
I will return to talk about RestScriptFixture, fun with NodeJS and are games (like movies) out of new ideas?

Friday, May 25, 2012

So most of the tests I'm writing now in Fitnesse are using RestFixture. Being able to do all this black box style testing has helped me get a lot of tests up and running without having to change the existing code base. Now I've taken a step future with my own little fork so I can use scenarios and build nice BDD style scripts. But first I want to give me own quick guide to using RestFixture

Step 1: Installing
You can dive straight in by grabbing the latest jar files for RestFixture here https://github.com/smartrics/RestFixture/downloads
If you know what you're doing can get the nodep version to work nicely along side other libraries you may be including in Fitnesse. But I grabbed the 'full' version and unzipped it into a RestFixture folder alongside my FitNesseRoot folder.Step 2: Write your first test
I took advantage of the built in Fitnesse api as a basic test and wrote a page called RestFixture with the following contents

If that runs and passes then congratulations! You've got a working RestFixture install!
Step 3: Profit!

Pitfall 1: &
Stuff like /loadpreferences?session=9999&user=admin&module=config would fail and I was scratching my head. Now any good RESTful api designer will tell you that's a stupid url to be using and they'd be write. But it's someone's old mistake and I can either tell them how stupid they are or appreciate the fact it works and move on trying to get everything that's broken working too.
Why did this fail? Well because Fitnesse was turning my & into &amp; and messing up the url with nothing to parse it back. Solution: Surround the url with !- -! to stop Fitnesse doing any parsing on it and it'll work just fine.Pitfall 2: json + xpath
I was trying to figure out how to handle json that didn't confirm nicely to use xpath commands. Unless your json is wrapped in something like {node: stuff} then the xpath stuff just doesn't work. Something I will try and fix at some point. So i used a lot of the javascript parsing in there to access the jsonbody variable that would work just fine. So I got lots of things like this:

Pitfall 3: Posting form like data
It's documented in later versions but not in 2.0 beta that you can use set body with url encoded data to behave like posted form data. Very handy. Although I'm still trying to figure out how this can work if combined with a file upload.

So it's pretty straight forward. If you're already familiar with script tables you'll know how you can drop switch between check and show for when you just want to see the result vs when you want to validate it. There are probably lots of statements you'll want to run without looking at the number returned (number of rows modified or -1 if there is an error). My fixuture is hard coded to use a local postgres database (and the postgres jdbc jar is in my lib folder). But it's easy enough to change that for your own version

Sunday, May 13, 2012

I was thinking of writing a short bit on writing tests in Fitnesse. But instead I'm going to recommend the tutorials by Brett L. Schuchert http://schuchert.wikispaces.com/FitNesse.Tutorials as they skip straight into using SLIM. The guides on fitnesse.org (and with the install) are good but explain everything with FIT first before racing though what is different with SLIM. That's just the nature of how Fitnesse was developed but it's worth skipping straight to SLIM as it has less requirements and can be more flexable.

Saturday, May 12, 2012

Some pretty basic steps but just to make sure it's here for everyone to see. Setting up fitnesse and running the jar is easy enough. Just go to http://fitnesse.org/ and get started and do it on your desktop just to see it in action. But for me that wasn't good enough I wanted it to run as service on ubuntu.

I stole a few tricks from how ubuntu runs jenkins and setup fitnesse a similar way.
1. Create a user and group for fitnesse (optional)
I didn't do this because I wanted tomcat, jenkins and fitnesse all running as the same user. Call it laziness to avoid any permissions classing but it doesn't change the process that you need to create or choose what user you're going to make it run as. Don't make it run as your user or root!2. Download the jar file and place it in /usr/share/fitnesse
Make the folder too of course. It can belong to root as long as the fitnesse user has read access3. Create the folder to run in at /var/lib/fitnesse
Fitnesse user needs write permissions here so may as well make it the owner. This is where FitNesseRoot is going to end up and also where you're going to want any libraries and classes it can include. I found fitnesse isn't very good at using absolute paths when doing includes and also doesn't handle spaces. Something to look out for!4. Create the folder to store fitnesse logs /var/log/fitnesse
Make sure the fitnesse user can write
5. Create the below file as /etc/init/fitnesse.conf

nearly there now7. Setup run levels for fitnesse to run with
I used sudo sysv-rc-conf -P to see the run levels and turned on 2, 3, 4 & 5. Could probably have dropped 2 but whatever, that's what most use. There seems to be lots of other ways to do this but this is what I did.

That's it! I'm probably forgetting something and I'm sure there's better ways to do some of the steps. There's lots of guides out there if you search 'ubuntu daemon' but knowing the quirks of fitnesse (spaces in folder names? where do you want files?) is still relevant.

Thursday, May 3, 2012

Anyone who has worked with me in the last 3 years knows I have a programmer crush on Uncle Bob and I got most of my initial training on Agile development from James Grenning. So it was just a matter of time until I started using Fitnesse. Now fitnesse (and fit originally) is an interesting tool to try and get acceptance tests OUT of code. After all why should programmers (or programmer-ish testers) be the only ones to write, read and review these tests? Acceptance testing is about making sure you deliver what the customer wanted so shouldn't the customer and other management people be reading them too? So fitnesse meets them in a middle ground. A wiki.

A wiki is a good place to go because you can get a manager or customer to read a wiki. You can, with a bit of a push, even get them to start contributing to a wiki. Good luck trying to get them using jmeter or read what you created in cucumber! Those are great tools but they don't scratch the itch that fitnesse was written for.

So I've been writing fixtures and playing around with scenarios and scripts. But what has me really excited is combining all that with RestFixture. I'm currently dealing with a lot of java code with all the front end piped through a RESTful service. It's a pretty common way to develop any distributed service these days and works pretty well. So I've been able to build up detailed tests that push all kinds of scenarios through the rest api without touching any UI code. And I've been able to condense it down to user stories that read like English so I can get the business analysts types to read and review them. With a bit of training I might even get them writing the first drafts of new areas to test.

But it hasn't been without challenges. So I want to document exactly what I've done and the kind of tests I'm able to now write. More post will come later but first I need to clean up my fork of RestFixture so I can get my changes accepted back into the original!

Saturday, March 17, 2012

Have you seen a build flag that states "no tests". What's the point building code without running all your tests? What's the harm in running them one last time? Tests are there to be run. A LOT! Settings that allow you to run tests every time you save a file in your IDE help ensure your unit tests are fast and passing all the time. Unit tests are there to catch you when you break something unexpected. You may think your fixing a bug with a date-time object but maybe that fix breaks something else down the line. The tests are there to tell you. If you never run your tests then why bother having them? Why not just delete them all?

Saturday, February 25, 2012

Do you do any of these? Do you see these habits in others. Clean code is when you look at code and think "of course you would do it that way". It's simple, elegant, and straight forward. Once you look at it you can't think of a better way to do it. It seems 'obvious' but only with the power of hindsight. But it's not something you'll get much of from these programmers

The Hoarder - "I’ll add/leave this function because it may come in useful" litters your code with commented code and unused functions that rot and bloat your code

Over-Complicator - "I've built an xml like nested config value loader to read in my three values instead of using a constant" yeah thanks. And when it turns out to have a bug we'll spend weeks trying to figure out how it all works and why you wasted company time (and money) writing it.

Rewriter - "This 3D library doesn't quite fit my needs. I think I'll write my own and call it DirectY" and you waste weeks on it, it turns out buggy, has very little hardware support but by the time we find out the entire company is building on it and feels committed to keeping it.

Obscurer - "CMiscValues init function runs ReadStream to setup the CoreFactory" this is not abstract this is waffle

The Secret Recipe - "Oh it crashed because you have to call unloadAllSettings before you let the class run the deconstructor. But make sure you call close first" so basically no one can use your code without mysterious and random crashes. Thanks for your contribution.

Tuesday, February 21, 2012

Have you ever had to work with that guy. The one who hates going to meetings. Ridicules the other developers. Sits by themselves rarely talking with anyone while "working". Sometimes they swear a lot, sometimes they often show up late to work and often they have little interest in showing someone else how their code works.

Have I been that guy? Honestly I can't say for sure I never have been. My programming idol Uncle Bob admits to being that guy once in his book Clean Coder.

There's a lot of old stereotypes around programming and computers in general. I've been told once to put up with a grumpy programmer on the promise he would work twice as fast as any other (if not faster). Turned out he was pretty clever but he wasn't any faster than the average for the team. And when he got really grumpy he got sloppy and produced some of the worst programming I've ever seen. So I've since resolved to never endure such behaviour and that any anti-social behaviour is potentially a problem.

A lot of programming issues are resolved through communication. Don't be the grumpy programmer. Don't ever think it's worth just "enduring" one.

Thursday, February 9, 2012

I've been thinking a lot about TDD, agile training and the long term behaviour of teams after such training. I've met far more programmers who have had training in TDD than I know programmers who practice TDD. And I've heard all the excuses

You can't do TDD with this language

You can't do TDD with this framework

You can't do TDD with this database

You can't do TDD with this hardware

You can't do TDD with this schedule

All bullshit, believe me. I may have said some of those myself once

But once you get past all that you get programmers who will give you a lucid agreement that TDD is good and they should use it more. You train them and show them how it's done as well as push past the issues above.

And then they don't use it.

But why? They agreed it's a good idea and they should do more. We solved all the serious issues that were stopping them from trying. Why wont they even try and put it into their routine?

Routine. That's part of the problem. They still follow the old patterns all programmers learn. "I need to make something to do X. Not sure how to do it"... write write write "still not there"... write write write "okay it works. oh wait! I forgot to write any tests"

I want to delete that programmer's code and make him write it again. Seriously! You're so focused on writing code you forget how important it's function, adaptability and readability is. And the tools that help you get there are tests. Yes you solved X but I can't test it, can't easily change it and can't easily extend it. At least if I deleted his/her files that programmer would get some more practice at TDD.

Practice. That's part of it too. Do your TDD homework! Spend each working day after training with "what can I apply TDD to today?" Consider it incidental exercise to help improve your TDD muscles.

Is learning TDD like learning an exercise routine? Making part of it your daily routine. Setting achievable goals. Measuring your progress. And talk to others for encouragement and support. And if you get really stuck call in a personal trainer!