Archive for February, 2007
The most common excuse I have heard for the failure to write automated tests is that there is no time. People have a deadline to hit, and it seems there is no time to waste writing test code when there are features that need implementing. To me, this is a terrible excuse. Not because I think that code without automated tests can’t provide your customers with valuable features. Rather, it is because you are going to have to test the features somehow, and if you can’t do it automatically you are going to have to do it by hand. As I mentioned in a previous post, I think that in the majority of cases this will be slower than just writing the automated tests.
The crux of the argument is that features never work the first time that you try them. I don’t know about you, but when my new code works the first time I try it I’m not happy, I’m suspicious. This suspicion comes from years of getting things wrong. Typically, each feature will take several testing iterations to get right. This is trivial with an automated test, and time consuming with a manual one. I have not measured the typical time for each alternative, but I would say that most of us naturally assume the manual testing treadmill is less time consuming than it turns out to be1. So, when we have that short term deadline to hit, automating the tests can be a lot more effective at saving time than we realise.
Over the longer term, the fact that automated testing saves time is pretty much a no-brainer. In fact, I would say that this is just one case of a general principle:
Over the long term, the right way is also the fastest way.
Cutting corners is at best a near-term win, and cannot be sustained. Over the long term, automated testing continues to pay dividends, with only the (hopefully) small cost of maintaining the test suite. The most dramatic time savings come when your automated test suite finds a new bug as it is introduced by a developer. With the right process in place2, this bug can be fixed before it breaks the stride of the development team, and long before it reaches a customer and leads to a costly support incident.
1 Perhaps a specific case of the general optimism that makes most of us terrible at estimating software schedules.
2 And tools!
For this second entry in the “Testing Is …” series, I decided to mention an advantage of testing that is widely known. The idea is not original, but its importance to you as a developer cannot be overstated. Perhaps the single greatest advantage of writing tests is the freedom you feel to change the code under test. All software grows cruft over time, and left unchecked the code will become an unmaintainable mess. Most developers would agree that maintaining code is not the greatest part of the job, and maintaining crufty code is about as bad as it gets. The answer is to refactor to remove the cruft over time. However, we also know from bitter experience that changing working code, no matter how crufty, will introduce new bugs1.
That is where the tests come in. If you have maintained a comprehensive test suite over time2, you need not fear nasty new surprises. You can refactor as required, and keep your code base much healthier. Now, test suites are not perfect and new bugs are still bound to happen. However, this is mitigated by two factors:
- The difficulty in maintenance of the crufty code itself will lead to bugs.
- A well-written test suite will cover those dark corners where bugs have been found to lurk. In particular, regression tests written to reproduce bugs as they are found are priceless at refactor time.
The logic is quite simple. Beyond that, there is also a powerful emotional difference. When the tests aren’t in place, we fear change. When we have the testing safety net, the fear is replaced with a sense of freedom. A freedom to change, and improve over time. A freedom which itself can be motivating.
1 If the cruft has grown due to the underlying complexity of the problem domain it is certain there are some nasty new bugs waiting for you!
2 Maintaining the tests as you write the code is important in itself. It is much more difficult to add tests later, not least because the problem is not fresh in your mind.
Somewhat inspired by Alberto Savoia’s article Testivus – Test For The Rest Of Us, I have been thinking about ways to motivate more developers to write more tests. Holier than thou style arguments (“your code is useless if it isn’t tested…”) are no motivation. But there is a much simpler way to approach the topic: testing has many tangible benefits for the developer. Perhaps looking at the ways in which testing can directly benefit us will motivate us all to test more. So I’ll be writing a few posts with perspectives of testing that highlight the benefits I get from my own tests. Here it goes:
Testing Is … Instant Gratification
One of the most frustrating parts of the development cycle is the start of a new major release. This is an exciting time, where big new things are planned and frontiers are explored. However, given the size of the problems that are tackled in this phase, roadblocks are always found along the way. Even when things are sailing along smoothly, the finish line is a long way in the distance. Thus it is easy to get the feeling that you are going nowhere: as you have no concrete features to show for your efforts. That’s where testing can help. By isolating and exercising a smaller piece of the puzzle, you can demonstrate progress. And I don’t mean that you can prove to your manager that you haven’t just been surfing the web all day. Rather, you can demonstrate to yourself that things are heading the right direction. I find that even this small sense of achievement can be really motivating. Once the most basic things are working, you can’t help but add that next incremental step. Before you know it, you’re in the zone and things are really beginning to gel.
So, next time you feel stuck: write some tests!
Thread dumps are an invaluable form of debugging, especially something running at a remote site. When you have no idea what is going on inside your application, a thread dump can be a life saver. However, depending on the operating system and method of launching the application, it can be difficult to get a thread dump by the traditional method (SIGQUIT on Unix and Control+Break in the console on Windows). Either it is difficult to find the right Java process (pre-NPTL Linux), it is difficult to find where stdout is going (when running as a service) or it is impossible to hit Control-Break (no console!).
Well, a couple of tools that first arrived in Unix 1.5 JDKs solve this problem. And now, in Java 1.6, they are available on Windows too. Those tools are jps (a ps for Java processes) and jstack (a tool to dump the threads of a specified Java process). Shipped with the JDK, these tools make getting a thread dump child’s play:
There you have the PIDs for all Java processes running as the current user, with the name of the main class. To dump the threads, pass the PID to jstack:
Attaching to process ID 8328, please wait…
Debugger attached successfully.
Client compiler detected.
JVM version is 1.5.0_08-b03
Thread 8581: (state = BLOCKED)
– sun.misc.Unsafe.park(boolean, long) @bci=0 (Interpreted frame)
Voila! Of course, if you have a graphical environment available, you can get all the goodness of jconsole too.
One of the challenges when starting out with OSGi is finding information on the basics. The official site offers a few articles on specific topics, but no real tutorials. Probably the best resources on that site are the technology overview and the technical whitepaper, but neither document helps you to get your hands dirty. However, there are some other tutorials and presentations about that dig into more detail:
- The OSGi and Gravity Service Binder Tutorial on the Oscar site starts with the simplest bundle and works up. A good starting point, even though the service binder is Oscar-specific (the concept is still useful, however, and explained from first principles).
- The Knopflerfish tutorial, which again starts from the very basics. Some of the content is specific to Knopflerfish, but the OSGi basics are also covered in a hands-on fashion.
- The aQute OSGi Tutorial, which is a detailed presentation with accompanying source code. Uses Eclipse/Equinox as a basis to develop some simple OSGi-based applications. A good next step once you know how to make the simplest bundles.
These links should help you get over the initial hump with OSGi.
As programmers we tend to get attached to code we have written. After all, we spent all that effort dreaming it up, typing it in, and (sometimes) making it work. Many of us also like to look over how much we have churned out, to see that lines of code metric crack the 500,000 (or whatever) mark. These sorts of things make us loathe to delete code we have written. But we forget these important points:
- Maintenance: someone has to maintain all of that code, and I’m sorry, but it’s you! The less code you have to maintain, the better. So next time you try and crack the million LOC, think about how fun it is going to be to maintain it all :).
- Dead code rots: leaving unused code around “just in case” is a particularly bad idea. If it isn’t exercised, it will become broken very soon. Its very presence distracts the reader from their real task.
- Source control: think you might need that dead code again? Think that a bad refactor may bring you unstuck? That’s what source control is for: it has got your back.
- Efficiency: every little bit of code slows everything down just that little bit. More disk space. Longer compile times. Slower IDE performance. Larger reports. Over time, all these little things add up.
- Elegance: verbose code is often a sign of a non-optimal solution. When refactoring, you should be able to use your superior knowledge of the problem to simplify. Cutting back code in this way removes the cruft that builds up over time.
So, stop being so happy that you’ve produced so much code. You should be much happier to achieve the same result with a smaller codebase, even if it means throwing away yesterday’s hard work!
As Jason mentioned previously, we are in the process of introducing OSGi into the core of Pulse to handle our plugin support. Since OSGi is also the core of Eclipse, we decided to that a trip to EclipseCon 2007 would be a great way to introduce ourselves into the community and see how people are using OSGi.
It promises to be a very interesting trip, not least for the fact that both Jason and I use IDEA for our development. I have not used Eclipse for quite some time, and last time Jason tried, it killed his mouse. But just maybe it is time to give Eclipse another try? With its support for developing plugins, it will certainly help with developing extensions for Pulse.
If anyone is interested in catching up with us while we are state side, send us an email. We are looking forward to talking to Pulse users and a little madness readers alike.
Fresh out of a Computer Science degree at uni, I hit the job market looking, naturally, for the best job I could find. I immediately ruled out moving into big business (think banking, insurance) and the consulting roles that tend to take you to such places. I wanted to work with technology I could enjoy, on new projects, churning out interesting “stuff”. That is what led me to the wonderful world of the VC-funded startup.
There are many great things about startups:
- New projects: by their very nature, startups have brand new projects to work on. We all know that starting from scratch is much more stimulating and fun than maintaining a 30-year-old COBOL codebase.
- Great people: because they have interesting projects and questionable job security, startups tend to attract people with a real interest in technology. You don’t get people who moved into “IT” as a career strategy, you get people who love what they do.
- Great atmosphere: partly because of 1. and 2., but also because of their small size and youth, startups often have a great feel. They haven’t had time to develop the painful politics and beuraucracy of older, larger companies. Hopefully they never will!
- No customers: when you’re just starting out, there are none of those annoying end-users to pester you with support questions and Real World problems. You can just code away in your own little world.
So I jumped aboard the VC-funded startup roller-coaster, and I had a great time. I lost my job a couple of times, but there were always new ventures to start on. I had a ton of fun and I learned heaps.
But something did start to bug me. I poured my efforts into these ventures and their projects, and even though the technology was fun, there was somewhat of a hollow feeling. The problem was that all of this effort was going to waste: without customers everything I created was consigned to obscurity. Of course the startups planned to get customers, and lots of them, but the business model was the classic boom-or-bust strategy. Either we would “disrupt” the world, or we would fade into oblivion. Of course, the odds lean heavily towards the latter.
So this supposed advantage of not having to worry about customers turned out to be the one great drawback of working for startup ventures. Jeff Atwood touches on it in his post Shipping Isn’t Enough:
How many users actually use your application? Now that’s the ultimate metric of success.
I achieved plenty in terms of development as a programmer, and I even managed to do some pretty good work (I hope!). But at the end of the day, I didn’t have the sense of achievement that only comes from creating something that other people use.
However, I have not given the startup game away :). I realised that you can have all the advantages, just with a different strategy. So at Zutubi we’re not planning to “disrupt” anyone. We just make software that people love to use, and grow organically off the back of that. And for once, I have Real Customers that use my software, and I interact with them closely. Who would have thought it: I love dealing with customers! Not because they pay (though I thank them for that ;)), but because every time I learn of someone new using our software, I get that sense of achievement I had been looking for.
Even while I wrote this entry, an email landed from a customer commenting on how they loved the user experience of Pulse. Honestly, it does not get any better than that!
You are currently browsing the a little madness blog archives for February, 2007.