Monday, September 27, 2004

code smell: tests/production LOC ratio

disclaimer: this reasoning assumes the project is striving for 100% production code coverage by unit tests.

As noted elsewhere, optimal lines of code (LOC) ratio for production code vs unit tests is about 1:1. I wonder, does significant deviation on either part indicate a code smell?

First, consider the case when the ratio is about 5:1. This could mean two things:
  1. Code coverage is poor (a good guess -- about 20-30%). No good, obviously.
  2. If code coverage is in 80-95%% range than we most probably have some flavour of acceptance (functional) tests not a canonical unit tests. Which is no good either.
Second scenario - when the ratio is 1:3 or even 1:5. Though less common, I still got into this situation from time to time. From my experience, this is usually a sign of a code smell:
  1. Elaborate setup code and/or a lot of stubs may indicate not well factored class hierarchy.
  2. Lengthy test cases for particular production methods can indicate a heavyweight class waiting for the Extract class refactoring to be applied.
Usually this ratio for my own code varies between 2:1 and 1:2. If it grows more, I tend to pay attention to either tests or the code itself. My experience here is mostly Python-based, in more verbose language like Java these figures may be a bit more vague.

PS: May be a "design smell" is a more appropriate term here?

update: My post's arguments were completed thrashed at c2.com. I'm still trying to figure out how much I (dis-)agree with them.

Saturday, September 25, 2004

Another argument for Google browser

To support community buzz about Google making a browser, they have launched a version of the frontpage specifically for Mozilla browser. Things are getting interesting.

Friday, September 17, 2004

More about inheritance vs. composition

I was reading excellent Effective Java by Joshua Bloch, on a topic about typical pitfalls when implementing Object.equals method. One of the least obvious is related to extending equals' implementation. To quote an author:

There is simply no way to extend an instantiable class and add an aspect while preserving the equals contract.
The author ended up with advice to use composition instead of inheritance with for such cases. I mention this story now because my reflections on unit tests for class hierarchies led me to the same conclusion.

Actually, I have in mind one specific case of class hierarchy: heavy-weight base and a bunch of subclasses that override/extend a particular aspect of it. An example may be a Finder superclass to define basic code to search the database and specific subclasses for specific domain objects, like Person.

The problem lies in unit tests: if you write them both for base class and for each of subclasses you'll find a sheer amount of duplication in you test code. Moreover, it could be very difficult to eliminate because the code would be a bit different for each of the subclasses' test case. A possible way out could be to replace inheritance with composition. There are two choices:

  1. Aggregate former base class into attribute. This is usually a relatively simple and this allows you to "stub" base class for testing thus eliminating a duplication in test code. If the base class' interface was much richer than that of subclasses you may end up with a lot of delegate methods, though.
  2. Pass an instance of a former subclass to the base class in order to configure it with specialized data and code. This would also mean that all former subclasses must implement the same protocol (interface) that would be used by the base class. That's could be harder or even just not feasible, though - the hierarchy was created in the first place because you saw no other way to factor out the similarities. Additionaly, if you succeed, this refactoring could make this already heavy base class simply unmanageable.
Nice example of how TDD actually drives a design, isn't it?

update: renamed post title and improved reasoning for the two choices.

Wednesday, September 15, 2004

FireFox 1.0 PR impressions

First impressions on pre-1.0 release, in the order of their importantance to me:
  • Major flaw. Popup blocker is either broken or just fascist. It prevents windows from open when I click a link, requiring me to add each site I want to use to whitelist. That's just stupid. Moreover, even after I added gmail.google.com to that list I still can't open a "Contacts" pop-up. Sorry, it was my fault. The "Contacts" window now is working fine, so I guess this should have been a GMail bug, not FireFox.
  • Bug fix. Gmail interface for contacts management is now working (it was completely broken before). There is a possibility though, that this is a fix by Gmail team.
  • Bug fix. Individual feeds in bloglines can be opened (at last!).
  • Compatibility problem. Some of the installed extensions I happen to use were disabled as non-compatible with Firefox 0.10 (including ieview, livehttpheaders and text/plain). Hopefully their respective authors will update them soon so that I could continue to use them.
  • Minor irritation. The Find dialog is now appears as a toolbar at the bottom of the window. The problem is that there is no keyboard shortcut to close it. Admittedly, it's not really irritating because it's not clutter a browser window now. I changed my mind and I don't perceive this as an irritation anymore. Actually, it's a nice change because it allowed me to uncheck "Find as you type" option to allow Gmail's keyboard shortcuts and still have a handy search box. Nice tweak.
  • Nice tweak. Some (or may be most) windows that are shown by browser itself are now "inlined" at the top of the rendered page with a yellow substrate. I noticed this for popup blocker window, missing plugin notification and new find dialog.
  • Nice tweak. The address bar for secure sites is now colored in yellow which make them hard to overlook (compared to a small lock at the corner we have previously)
  • New feature. Live Bookmark feature is interesting, but I prefer bloglines service to read RSS channels. There is a new Feed Your Reader extension which is similar to Live Bookmark but allows for external RSS readers. Version 0.7 (due this week) is going to support bloglines as well.

My blog's PageRank

Interesting, but my blog's site do not even appear on the first page of results when I search for max ischenko. Search for max ischenko blog gives it third position which is not great either.

Have to do something about that. Hey, microsoft.com guys, please put a link to my blog on your front page! Please do or I won't ever link back to your site, improving your PageRank.

update: not sure if someone at microsoft.com really linked to my site, but now both above mentioned searches yield profile page and index page at first two positions.

Spammers move on to blogs and forums

Joel Spolsky writes:
If you think comment spam is not a big problem, you haven't moderated a discussion group lately... this is the number one priority for spammers these days, since email filters are starting to work pretty well and spamming a lot of discussion groups is perceived as a good way to trick Google into giving a site prominent placement.
I read about spam posting on one or two other sites but didn't think it was a serious problem until now. Actually, just never bothered to ponder over it. Of course, this is more of a problem for popular sites, like Joel's, with a high PageRank. I wonder, if any forum/blogging software already ships with filtering included or at least has a plug-in for this.

update: Comment Spam Manifesto

Tuesday, September 14, 2004

Testing web-based applications with FIT

I have had a need to automate testing of our web-based applications because manual testing could never be completed in a reasonable timeframe.

For the last two weeks, I've been writing a fixture for FIT specifically to test web-based applications. The idea is to use very sophisticated HtmlUnit library for actual HTTP interactions and dealing with HTML (and Javascript) and to use FIT for specifing, running and reporting on test cases.

update: project is now hosted on public subversion repository. See http://opensvn.csie.org/webfixture.

For those who have missed it, here is a short description of the FIT framework. FIT is a web-based tool for specifying and executing acceptance tests for all kinds of application, with a particular accent on simplicity of the specs (they could be understood and may be even written by a non-programmer, i.e. customer). The central role in the FIT framework is devoted to a fixture. A fixture implements a vocabulary, which is used by user to describe things he wants FIT to perform. For example, to press a button or to follow a link. Or to evaluate 2+2 and to check that result is 4. Thus, user writes these checks using vocabulary and programmer implements this vocabulary with a fixture in a meaningful way. If you're intrigued, Michael Feathers has written a more elaborate intro in his Pitching a Fit post.

Originally, I tried to write a custom ActionFixture for each web page I had to handle but soon discovered that it was a bad idea. Firstly, it was too much work -- to write a Java class for each page I need to test. Secondly, and more important, each fixture would use different vocabulary for each page which means that test writer had to be familiar with an underlying Java class. Therefore I decided it would be better to write a single class (a fixture) that could be used to exercise any web page. Luckily web languages' expressiveness is rather limited so the resulting vocabulary to describe test cases should be manageable.

Shortly after I started to work on my WebFixture, I discovered a (semi?)-official HtmlFixture, created for the same purpose and which even uses the same HtmlUnit library! Nevertheless, I decided to continue to develop my own fixture, for these reasons:
  1. To get experience with Java platform.

    One of my goals with this mini-project has been to try out a Java platform. I've been on most C++, Python, Tcl camps these years and my Java programs never went beyond the "Hello, world!" exercise. This project seems like a perfect opportunity to learn a new platform.

  2. To control fixture's development.

    I want a control over this fixture to add things I want in a way I want. While the HtmlFixture is mature, its source code is undocumented and poorly written (to me). This probably a funny thing to say from a novice Java developer, but still, the source code seems like a mess to me and don't want to dive into it.

  3. To design it differently.

    If I decided to base my work on HtmlFixture there would be still no guarantee that my changes would ever go into original codebase. Why? Because I my approach is different and therefore there is a good chance that changes I propose won't "fit" author's concepts. Don't get me wrong, HtmlFixture is a fine work, I just want to implement the same concept a bit differently.

So how my fixture does look like?

The important design goal to me is to make fixture's vocabulary as simple and as high-level as possible. It should be similar in terms to those used by a web browser metaphor. It's better to sacrifice some underlying versatility of HtmlUnit to gain in simplicity and consistency for a user. It's better to overload verbs (where appropriate) than to invent new ones.

For example, I use verb click to follow links and submit buttons and use verb enter to enter data to input boxes, text areas and select boxes. This way, the same verb can performs technically different things as long as it means one thing to the user.

There are some other features I've added so far: site configuration, Java delegates, erroneous page detection.

The site command allows you to set some site options (or preferences) which include site root, timing information, error page patterns and more. These preferences are kept in a static storage so that you could set them in SetUp page and use on test pages.

The error page patterns used to detect erroneous web pages - normal HTML pages which are returned with HTTP response code 200 but which nevertheless are a sign of some internal error in the web application. For example, some application servers (like WebKit) show crash reports in this way and fixture could be configured to detect these automatically.

Java delegates are extension point to be able to hook custom checks that are beyond normal web processing, like verifying the database state. A delegate is passed a current HtmlElement and should return a boolean result - whether a test has passed or not.

And finally, some closing words on my first impressions on Java platform.

The IDE for a statically-typed language could do amazing things and Eclipse actually does them! Moreover, it is very capable in other aspects making handling of Java verbosity almost imperceptible. With advanced browsing support and context assist I managed to grasp an essence of both FIT and HtmlUnit library very quickly. And QuickFix assist helps greatly to correct my naive syntax errors. Overall, I must say, the development process goes much more smoothly and is much more fun that I have expected, thanks to IDE.

Monday, September 13, 2004

Mozilla FireFox extensions

Flexbeta has posted a nice guide to Firefox extensions, including Target Alert for links, Adblock with a nice configuration file, Sage RSS reader and more. Definitely worth a read for anyone who uses FireFox as a primary browser.

Btw, Firefox 1.0 Preview Release is going to be release tomorrow.

Friday, September 10, 2004

Flickr services

The Flickr.com is yet another photo service site. But the distinguishing feature (at least for me) is that it provides an API with array of supported access methods (REST, SOAP, XML-RPC) to get a full programming control of your account's data and settings. Quite impressive, really. I can't agree more with Jeremy Zawodny: [Flickr is a] next generation web services.

If we add to this Google, Blogger, A9 and others it surely looks like a trend. And you (myself in the first place) don't want to miss the idea while launching your next web-based service. Sure, this kind of access is helpful only for a fraction of web-based services out there, but it could gain them a lot.

Wednesday, September 01, 2004

Blogger

While the Blogger web application is one of the most pleasing I have worked with, it seems a bit shaky. I have already seen several errors in the past two days, including NullPointerException from a Java application, a page saying "internal error has occured" and a misleading error message which said about an error deleting a comment while it was actually deleted.

Anyway, overall experience has been excellent so far. The only major thing I miss is ability to post into different categories.