donderdag 12 april 2012

Testing Better than the TSA

Yesterday I came across a posting titled “Testing like the TSA” by David at 37signals. He makes a case against over-testing, and argues that developers who fall in love with TDD have a tendency to do that in the beginning. Of course, when somebody learns or discovers a new tool, there's always the danger that he or she uses it too much – in fact, I'd say it's part of the learning process to find out where the new tool is applicable and where not. But judging from the seven don'ts of testing David lists in his posting, my impression is that he should rather try to do more testing than less. Here are my comments:

1. Don’t aim for 100% coverage.
Sure, but then again, what's 100% test coverage? In any system there will be places where it doesn't make sense to write tests because the code is trivial or writing the tests will require more energy than you'll ever be able to save if one of the tests would find a bug. Typical examples of the latter include interfaces, like the GUI or the main entry method from the command-line. But at other times, 100% line coverage isn't enough, and even 100% branch coverage won't do it because it leaves some important paths through your system untested. And to be honest, I've found myself writing unit tests to check logging messages because they were a vital part of the system.

I know something is wrong when a system has 100% test coverage, but the core classes should be pretty close to 100%. As a consequence, I do aim for 100% test coverage, even though I know I won't reach it. It's just like aiming for the bull's eye, even when you're not good at darts. If you're not aiming for 100% (or the bull's eye), then what are you aiming for, and what will the result be?

2. Code-to-test ratios above 1:2 is a smell, above 1:3 is a stink.
That just doesn't make sense. I'd say a code-to-test ratio below 1:2 sounds very wrong. Just think of a single function point, like e.g. a condition: you'll need at least one positive and one negative case to be able to say your code does what it's supposed to do. And this is really just the minimum. I think that if you're doing unit testing right, you should probably have something between two and five unit tests per function point.

3. You’re probably doing it wrong if testing is taking more than 1/3 of your time.
4. You’re definitely doing it wrong if it’s taking up more than half.
That's probably right, but only because your test code should be much simpler than the system you're trying to implement.

5. Don’t test standard Active Record associations, validations, or scopes. Reserve integration testing for issues arising from the integration of separate elements (aka don’t integration test things that can be unit tested instead). 
I don't know about those Active Records (I'm a Java programmer), but I agree that integration testing should be about integration testing.

6. Don’t use Cucumber unless you live in the magic kingdom of non-programmers-writing-tests (and send me a bottle of fairy dust if you’re there!)
I agree on this one. I like the idea of Cucumber, and I've seen some great talks about it at conferences, but I've never seen it used in a real system and have no idea how I would ever be able to use it in any system at all.

7. Don’t force yourself to test-first every controller, model, and view (my ratio is typically 20% test-first, 80% test-after).
I do force myself, and I know it works for me, but I also know it doesn't work for everybody. I can live with that (some can't). But as a consequence, my ratio is pretty different. In a typical project, where I can write code exactly the way I want, I break the TDD rule about writing tests first in a different way than David: I often find myself writing up two or three unit tests before I start programming, especially when I start working on a new component or on a new feature. Sometimes I have to write a second or a third unit test to get the first one right, e.g. in order to be able to decide how the component's interface should look like. I find that easier than getting it wrong the first time, and then having to start refactoring everything five minutes later. But I guess this makes my ratio something like 40% multiple tests first, 40% single tests first, and 20% tests after. The reason why I still have a number of unit tests that I write after the code, is that test coverage reports and mutation testing often point me to branches and paths in my code that haven't been tested well enough.

I don't like testing TSA-style either, i.e. writing lots of tests just to get a high test coverage. That's coverage theater, like Davids puts it, and usually leads only to a large number of brittle tests that break down after the first refactoring. But we should aim high when we write unit tests, and try to do better than the TSA. I'd rather put in another five minutes to get the tests right, than having to spend an hour four months later trying to find out where the bug is hidden…

zaterdag 30 april 2011

Class A, B and C Speakers at Conferences

The ROOTS 2011 poster just reminded me of a comment Allan Kelly had at the beginning of his talk at the ACCU 2011 conference in Oxford a couple of weeks ago. He said every conference has class A, B and C speakers. What follows is more or less what he said, mixed with some of my own thoughts.
  • The class A speakers are the big names, the ones that sell the tickets for the conference. On the ROOTS 2011 poster, there are four of them (Michael Feathers, Dan North, Jim Webber and Jurgen Appelo), and you recognize them by the huge font for their names. Often they are the keynote speakers.
  • The class B speakers are the not so big names, but still regular speakers at conferences. Allan Kelly is one of them. Sometimes they're the local stars, as opposed to the international stars above, or they're the stars in a smaller niche. They provide good content –otherwise they wouldn't be class B speakers– and deliver the bulk of the material at the conference, but often they're a bit predictable too. Their names are on the ROOTS 2011 poster too, but in the smaller font.
  • The class C speakers are all the others, including the speakers that will have a talk but didn't make it to the ROOTS 2011 poster. (I'm one of them, hoping that one day, I'll become a class B speaker.)
Allan Kelly's point was that when you go to a conference, you should not just go to the class A and class B speakers. You should go through the list of class C speakers, and pick some of them too, because that's where you'll find the really interesting stuff.

I wouldn't call this a revolutionary insight, but I've never heard it expressed before. In his particular case, it was his excuse for not having attended Tom Gilb's talk earlier that day, because he had gone to Emily Winch's talk instead. This evening, I was reminded of his comment again, because the ROOTS 2011 poster illustrates so well who the class A, B and C speakers at the conference.

donderdag 28 april 2011

Upgrading to Ubuntu 11.04

Half a year has passed since the release of Ubuntu 10.11, so this evening it was time to upgrade to Ubuntu 11.04. It took some time to download all the components, and then to install them and clean up the system, but as far as the upgrading process is concerned, I had no problems to report.

I'm not sure yet whether I like the new user interface (Unity), or whether I'll switch back to GNOME. I'll probably give it a try for a couple of days, just to get some experience with it, and decide then on what I will do.

Even though there were no problems during the upgrading process itself, there are/were a few issues on my laptop once Ubuntu 11.04 was installed. Here's an overview:
  • I use SeaMonkey to edit blog articles, and it seems that spell check is badly broken. I'm probably suffering from bug #762905.
  • Some plug-ins are missing in Firefox because of some compatibility issues. I suppose I'll be able to pick them up over the next couple of days.

dinsdag 12 oktober 2010

Upgrading to Ubuntu 10.10

One of the tings I like the best about Ubuntu, is its six month release cycle. If there's a problem with an application, chances are it will be fixed within a matter of days. However, if things are so bad that they can't be fixed with a simple update, six months isn't such a long period to wait. Often that's just what I do too, instead of trying to install another application.

What's an even bigger joy with the six month release cycle, is that you always have a lot of new and better functionality to long for, but without being as disruptive as e.g. a Windows update tends to be. Compared to the hassle it was every time I had to upgrade to a newer Windows version, upgrading to another Ubuntu release is as easy as eating cake. That doesn't you don't need to make back-ups before you start to upgrade, but you won't need to spend a lot of time trying to find applications that are compatible with your new OS and at the same time can handle your old files.

There are, however, always small things that have to be done once you've upgraded to a new release of Ubuntu. Most of them are simple reconfigurations. Here's a list of things I had to do after upgrading to Ubuntu 10.10:

  • For one reason or another, the GLText screensaver configuration has been set back to a default text showing the name of my computer and the version number of the kernel in every single release. As a consequence, I'm getting good at setting its configuration file /usr/share/applications/screensavers/gltext.desktop back to include the line Exec=/usr/lib/xscreensaver/gltext -root -no-wander -no-spin -program "<my-custom-script.sh>"

  • Adding all accounts to Gwibber again. I was of course expecting having to reauthenticate, but erasing all information about all accounts just seems very clumsy. Besides from that, the new version of Gwibber seems to be a big improvement.

  • I had to change the default proportional font in Thunderbird back to serif. For one reason or another, it had fallen back to sanserif.

zaterdag 1 mei 2010

Customizing Your Keyboard Layout in Ubuntu 10.04

In Ubuntu, it is possible to customize your keyboard layout in a very simply way. In fact, all you have to do is find the right configuration file, make a few changes, and you're done. Here's how you can customize your keyboard layout:

First, you'll have to find the file that defines your keyboard layout. In Ubuntu 10.04, these files are located in a directory called /usr/share/X11/xkb/symbols. Most files use a land code as a name, with the exception of some vendor specific definition files, and a few more generic ones.

The format of these files is pretty self-explanatory. Most files define a basic layout, which is the default one, and some variations. Each layout can include another layout from the same file, or from another file. Keys are defined by their row and column name, and can contain up to four values (in the simple case). The first value is the character you'll get when you just press the key, the second one when you combine the key with the Shift key, the third one when you combine it with the Alt Gr key, and the fourth one when you combine the key with both the Shift and the Alt Gr key.

In my particular case, I use a standard Norwegian keyboard, i.e. the basic layout in the file called no. Since I have to write mails in Esperanto from time to time, I need access to characters like «ŝ» (s with circumflex) and «ĉ» (c with circumflex). They are easy to produce on a standard Norwegian keyboard in Ubuntu: just press the dead circumflex key («^») first, and s or c afterwards. The circumflex key is called “dead” since it doesn't produce a character until another key is pressed. It's more difficult to produce «ŭ» (u with a breve)—in fact, as far as I know, it's impossible to produce it directly from a Norwegian keyboard.

For me, it makes the most sense to put the dead breve key («˘») together with the dead diaeresis key («"»), the circumflex and the tilde («~»). There is however no definition for the dead diaeresis key in the Norwegian keyboard layout file, so that's not where we have to make our change. In fact, since the basic Norwegian keyboard layout uses latin(type2) as its basis, we'll have to look in the latin file and see whether we can find the definition of the diaeresis key there. In fact, it's right the in the type2 definition, at the following line:

key <AD12> { [dead_diaeresis, dead_circumflex, dead_tilde, dead_caron ] };

Indeed, the dead diaeresis key is on the fourth row (encoded as AD), and the 12th key from the left. Now how can we change this definition to produce a breve instead of a caron («ˇ») when we combine the key with Alt Gr and Shift? In order to do that, we'll have to change the definition as follows:

key <AD12> { [dead_diaeresis, dead_circumflex, dead_tilde, dead_breve ] };

In order to keep the dead caron key, we could also change the definition for the AD11, the key that normally produces the Norwegian letter å, as follows:

key <AD11>{ [ aring, Aring, dead_abovering, dead_caron ] };


Once you've made the changes, save the file, and reboot your computer in order for the changes to take effect. When the system comes back up, you should be able to produce the character «ŭ» using the diaeresis key in combination with Alt Gr and Shift, and typing u afterwards.

zondag 28 maart 2010

The Moment I Realized I Had Become a Senior Developer

The following story dates back from a couple of years ago. A colleague of mine was experiencing a problem with a system we were working on. Most of the time, things were right, but from time to time, the system gave the wrong answer to a query. A quick investigation revealed that the method to calculate the result was right, but sometimes the wrong result seemed to come out anyway. The strange thing was that when the system replied with the wrong answer, it was in fact the correct answer for another query sent to the system. My colleague really didn't understand what was going on, so she called me to investigate the problem.

The little detail that the system returned the correct answer to another query, was in fact a important clue to solve the mystery. After browsing through the code for a few minutes, I found out that one of the attributes in a class was marked static. As a result, the system returned the result for the last query that entered the system, even if you asked for the result of a previous query. And that was the kind of bug I was expecting from the beginning: to me, the problem had the smell of static confusion all over it, even though I couldn't say exactly why.

My colleague was impressed, and literally asked me how I could know such a thing. The only answer I could come up with was that many years of creating many bugs had given me much experience in finding out why something was wrong. I guess that's the essence of being a senior developer too...

vrijdag 5 februari 2010

So Once Again Somebody Is Predicting the Death of Microsoft

Former vice president of the company Dick Brass wrote in an op-ed titled “Microsoft's Creative Destruction” in The New York Times yesterday why he thinks Microsoft hasn't much of a future. His analysis is that the company isn't on the innovating edge anymore, and is therefore failing. He attributes this failure to the internal competition in the company, which kills innovation whenever it comes from another department, and concludes that unless the company changes its internal company culture, it will lead the same faith as G.M.

I don't think Microsoft is going to disappear any time soon, even though I put in some effort in 2009 to get it out of my house and wouldn't shed a tear on its death. Microsoft is just too big to disappear over night – but not in the same sense as how some banks were too big to fail. Just imagine what would happen if Microsoft would shut down all its R&D activities, stop any further development of its Office product, not work on a new version of the Windows operating system to replace Windows 7, etc… Even if something like that would happen, people will still want to buy computers using Windows, because that's what they're used to. Similarly, people will continue to use and buy Office, both at home and in the office, because that's what they're used to. Moreover, they have lots of documents that were created in its formats, and don't want to bother to convert them to another format. And many new software products based on the .Net framework will still be developed for many years to come.

We now know that the Titanic could sink after all. But we also know that the sinking process took almost three hours, not just a few minutes or seconds. Therefore, I expect that Microsoft will still be around by the end of this year, and the next years. Maybe it won't be a monopolist any more, but at the very least it will still be one of the dominant players in the software business, whether you like it or not.