HTMLUnit's village idiots
Monday, August 15th, 2005It’s been a while since a village idiot hat has been awarded. While this is by no means a promise of regular hat givings, in this particular instance the recipient is gagging for it.
The winner is HTMLUnit. HTMLUnit, for those who are unaware, is basically a piddly little framework that lets you create web requests, and parses back the resultant html/javascript and lets you click on things programatically to simulate actual users. It’s great (in theory) for end to end acceptance testing.
Thankfully, the name is a total misnomer. For one thing, it’s not about unit testing at all. Therefore, has nothing to do with JUnit. It wisely avoids the spastic route taken by things like xmlunit, which provides classes tightly coupled to JUnit.
The premise is a pretty decent one, it’s the implementation, as usual, which makes the baby jesus cry hot tears of rage and anger while biting off the nearest nipple.
It all started innocently enough. I have a rather complex page that the current version of htmlunit fails on. Knowing how the oss thing works, I knew I’d just be told to try the cvs version if I reported the problem. Thusly I went off to cvs (sourceforge, the first sin), and grabbed the festering pile of goatpoo.
First problem, I see maven crud splattered all over. My heart sinks as I see the 3 tongued kisses of death; maven.xml, project.xml, and project.properties. This cannot possibly go well. Amazingly, there’s a build.xml there too, so I might be spared. I’m not hopeful mind you.
My dismay was in fact well placed. The ant file is nothing more than the year old solidified wankstain that maven squirts out. It manages to die before compiling a single line (it tries to specify an output dir for javac that doesn’t exist).
As an aside, I’d like to know who wrote the maven to ant plugin. I have never, in all these years, seen such badly written buildfiles. Now I know maven guys are fuckwitted rumpranging ADD-ridden gizmowhores, but surely they can’t know so little of how ant works or of how it should be used. Even their callous disregard for users and the real world doesn’t go the whole way towards explaining the mindboggling incompetence of this build.xml.
To cut a long story short, the file is a herring sporting a horrific red hue. Making this thing work would require an impressive collection of miracles from all major religions.
So we’re onto maven. Running maven, of course, is always a great excuse for a day out, maybe catch a movie or two, and a nice dinner, while it figures out what day it is, what it should do about it, and how to calculate the worst and slowest way of running a few thousand tests.
Eventually, a feeble jar is farted out. Plopping said jar in my tests reveals a rather dismal result. Cookies no longer work across invocations.
Ohdear. Nevermind, I’m a java guy, I can debug this sort of thing. Armed with nothing more than an abiding hatred for java developers and a trusty debugger, I sally forth into the brackish waters that are the htmlunit source code.
Hrm, here we go. At some point, one of these gurus of incompetence decides that we should internally store a map of HttpClients, keyed by host url. Thusly can clients be reused and state preserved across invocations, for a given site.
Said guru however didn’t actually bother fix the thing that gets stuff out of said map. So while the key is now host + port, the blocks that attempts to retrieve things from the map does not include the port. These days, every url has a port, thusly, much wailing and gnashing of teeth ensues.
Apparently, this problem has trickled down to other lost souls who use htmlunit cvs, such as the canoo people, who also have the odd user bleating about cookies being ignored.
So the fix is simple. A few lines of code later and I’m ready to attempt the Herculean task of convincing maven to give me a jar. An outing, couple of movies, and dinner later, maven proclaims that some tests have failed. Hilariously enough, the ‘helpful information’ it gives me about this build failure is line and column information of the jelly script junit plugin that failed. Highly relevant I’m sure, just not to anyone except the halfwit author of said plugin.
So after a few days of pointlessly scrolling around, I find the culprit. It’s at this point that I completely lose it and start laughing hysterically. I can’t quite believe the test I’m looking at.
The test for http state works thusly: It gets at the class that holds the map. It uses reflection to access the (private) map, makes it accessible, and manually puts a value in it. Having done so, it then calls a method which basically just reads from the map, and then compares the two.
It’s mind boggling to me that someone would write such a complex and awkward test to basically test that HashMap functions as a….map. Of course, this test and a dozen other just like it now fail, since the keys they use to do the manual insertion cannot exists anymore. The change to the internals of the class being tested generate keys of a different format, so the test is testing a state that cannot ever, ever happen.
It’s sad and pitiful that things like this happen. It’s even sadder and even more traumatising that it’s not that rare, and is even more common than not. The collaborative effort of so much incompetence should not happen, it should be a freak accident that only happens very rarely, instead of daily, over and over again.