Also on twitter ( twitter.com/nutrun )

Archive for December, 2006

Fragile Tests

Tuesday, December 19th, 2006

Those of us who have fire alarm(s) installed at home must have gotten ourselves in situations where we open the oven to get the sizzling-hot-double-mozzarella-pizza out, ready to slice it and transport ourselves in front of the TV. Then the smoke detector goes off announcing to everyone in the building that this guy’s having pizza again and forgot to close the kitchen door before taking it out of the oven.

Every time I see/hear the term Fragile Tests, I can’t help but think of my smoke detector at home, which, either doesn’t like pizza that much, or is really devoted to performing its duty of detecting smoke and preventing hazards.

There are a million derogatory descriptions tests can be decorated with. They can have their intent buried, they can be badly named, they can be testing too many things at a time, they might be irrelevant, and on and on, but one thing tests cannot be is fragile. Unless, that is intended to mean good fragile.

Alongside a few other things they must do, tests are really supposed to break. Whenever a tests breaks, that’s a good thing. A breaking test is trying to communicate one of two messages: It’s either complaining that we’ve broken something during our effort to make things work, or that we’re not providing it with the correct fail conditions. Either one must be fixed, because tests, like all things robot, when acting inappropriately, it’s because we told them so.

Tests are there to embarrass us to our neighbors for forgetting to close the kitchen door when taking the pizza out of the oven and be the first ones to start shouting at the slightest signs of smoke.

Words I can’t type

Monday, December 18th, 2006

I can imagine why, but I always type admin instead of admit, type localhost even though I only wanted to type local, every word that starts with str becomes string and a whitespace always follows the three letters def.

I also do ctrl+space or hit the tab key a lot, even though I’m not in IntelliJ Idea or a Bash Shell. Strangely enough, I never hit tab in IntelliJ or ctrl+space on the Shell.

Hmm…

What I’m missing from Java

Monday, December 18th, 2006

A standard JDBC driver for SQLite.

A proper, fully working implementation of Textile. Note the emphasis on fully working, because the couple that I’ve seen don’t implement the whole thing and (or) have not been active for some time now.

Groovy has gotten me coding in Java on my spare time again after a lengthy absence and I admit that I’m having fun, but I’d really rather use SQLite instead of HSQLDB and Textile instead of not using Textile.

Fixing corrupt WordPress MySQL tables

Monday, December 11th, 2006

The blog was up and down today, and WordPress was complaining about low memory and database lookup failures. This is not a common situation on a nicely laid out Debian server and thankfully it wasn’t that difficult to fix either (3 minutes).

I did a massive apt-get update the other day, so I suspected it must’ve been something to do with that. A mysqladmin shutdown -p followed by a myisamchk --silent --force */*.MYI inside /var/lib/mysql revealed the problem – and promptly fixed it:

myisamchk: MyISAM file wordpress_db_dir/wp_sitemeta.MYI
myisamchk: warning: 1 client is using or hasn't closed the table properly
myisamchk: MyISAM file wordpress_db_dir/wp_comments.MYI
myisamchk: warning: 3 clients are using or haven't closed the table properly
myisamchk: MyISAM file wordpress_db_dir/wp_options.MYI
myisamchk: warning: 1 client is using or hasn't closed the table properly

That is not what bugs me, though. I think – although I don’t know – this might be a problem with WordPress, as I’ve had the exact same issue in the past and, again, it was WordPress tables that were causing it. Maybe I ought to start bringing down the site when upgrading, although I don’t want to miss out on my zero downtime Debian upgrades. Also, if you google “WordPress database error: [Out of memory” you get about 584,000 results. And boxes don’t run out of memory just like that…

I think the guys at WordPress need to look into handling server shutdowns more gracefully and a nice way of dealing with corrupt tables when that occurs which, by the looks of it, is quite often.

From Mocks to Expando

Thursday, December 7th, 2006

Revised example test with added assertions to verify methods are being called. Thanks to Nat and Geert Baeyaert for spotting this.

Up until recently (a few hours ago, that is…), I lived with the notion that Mock Objects are a necessary evil. You don’t exactly like them, but you can’t really do without them. They have obvious advantages, but something about them never felt quite right.

So I spent my little recent while attempting to figure out the most likely among a number of potential candidates for the Mock Object API of my liking in Groovy, and, believe you me, there are plenty of options. The answer – with the help from a bunch of nice people on the Groovy dev mailing list:

No Mocks.

The technique does not have to be Groovy specific, I’m pretty sure it can be achieved with most non-statically typed languages that support closures and the ability to dynamically attach behavior (methods) to Objects.

Groovy’ s (relatively) secret weapon for the task is the Expando class. Oversimplified, instances of Expando are expandable Objects to which you can add methods in the form of closures.

Here’s an example of my mock-less unit test:

package aerie.response

class ForwardResponderTest extends GroovyTestCase {

  void testShouldForwardResponse() {

    def getRequestDispatcherCalled = false
    def forwardCalled = false

    def dispatcher = new Expando()
    def request = new Expando()
    def response = new Object()

    request.getRequestDispatcher = { location ->
      assert "/location" == location
      getRequestDispatcherCalled = true
      dispatcher
    }

    dispatcher.forward = { req, resp ->
      assert request == req
      assert response == resp
      forwardCalled = true
    }

    new ForwardResponder(request, response, "/location").respond()

    assert getRequestDispatcherCalled
    assert forwardCalled
  }
}

… for the following class:

package aerie.response

class ForwardResponder implements Responder {

  def request
  def response
  def location

  def ForwardResponder(request, response, location) {
    this.request = request
    this.response = response
    this.location = location
  }

  def respond() {
    request.getRequestDispatcher(location).forward(request, response)
  }
}

It’s worth noting that here we’re dealing with testing contents of the javax.servlet API, one of the most notorious in terms of its un-testability packages in Java.

For starters, if we considered the test in question in traditional Mock Object terms, we’d find ourselves in a situation where we’d have to write a Mock for HttpServletRequest on which we would expect a call to getRequestDispatcher(String location), which would in turn return another Mock – RequestDispatcher, on which we’d expect forward(HttpServletRequest request, HttpServletResponse response) to be called. In “I like my code compact and concise and the intent of my tests clear” terms: insane.

What Expando does for us here is Stubs with an attitude. Done right.
This test is all down to language level – assert is a Java keyword. We’re nowhere near importing a Mock library or having to understand the mechanics of a paradigm that is not native to the core language. We are asserting on what and only what we want to be asserting on. The class under test is tested completely in isolation and there is zero clutter in the form of stubbed interface implementations of the shunt collaborators that interact with it.

Of course none of these would be possible if the language, or design concerns, disallow or discourage duck typing. But even if we’re worried about whatever problems might arise from the lack of statically typed parameters or strongly typed objects, I would suggest that the absence of it is quite OK and manageable at package level where everything is under our control and outsiders cannot really go too creative – as in dangerous – with it.

Making SPAM more Human

Monday, December 4th, 2006

Up until about two months ago, I was sleeping easy, knowing that I wouldn’t have to wake up the next day and moderate unhealthy dozes of spam from the comments on the weblog. But that was then and is no more.

For the past two months I’ve been rejecting the idea of giving spammers any value by blogging about them, but some of the posts are so out there that I can’t hold it in any more. Take this one from earlier today, for instance:

Viagra

Don’t delete. Help homeless children.

This one doesn’t even have the decency to make some sense. I mean, as far as homeless children go, promoting Viagra probably contributes in increasing their numbers rather than the opposite.

What’s getting real scary is how some of those comments are by humans, as in not bots. You can tell, because those guys take the time to go through the article they’re going to spam-enable and start their messages with something along the context of what’s being blogged about:

Hey guys, we use XhtmlValidator in our projects and it’s great. Thanks. Here’s some useful links [...]

… followed by some useful links about the best deals in pharmaceuticals.

And I’m getting a nasty feeling, because this new found spam explosion smells like Mechanical Turk… Think about it. From the Turk website: Complete simple tasks that people do better than computers. And, get paid for it. This is way sad, because the idea, the technology and the intentions behind Mechanical Turk are great to say the least.

It would be interesting to watch, however, after seeing what the spam industry is doing with cutting edge technologies, what that other driving force behind the internet is going to make of services like Mechanical Turk…