Python unittests and subclasses

While working on one of my projects, I discovered one of those things about a programming language/module that forms a smile on your face as you are coding.

I have been creating unittests for some code that is using a class from the standard Python library, which means that my unittests can only see the result of a process, not the state of the process while my code is running. This was becoming problematic because I needed to test the state of my code at a particular part in the overall process.

So I have a parser which is using sgmllib.SGMLParser as it’s superclass. So once, I pass data to the feed() method I can only see the state of my parser after it has parsed the data. I need to see the state of some internal representations of the data during the parsing, though, so this was becoming problematic. Debug messages, while helpful, are difficult to decipher when the number of messages goes beyond as human readable number.

So here’s where the joy came in. I remembered seeing a test (somewhere) that used a new subclass of the class that was being tested. This (happily) means that your class can test itself by overwriting some of the superclass’s methods. While I was happy to find a testable solution, the real joy came when I was worried about how my subclass was going to tell the unittest module that something failed.

Enough babble, here’s an “example” of testing a fake BlackBox class (one that I can’t see into):

class TestableClass(BlackBox):
def blackbox_method(self):
super(TestableClass, self).blackbox_method()
assert self.internal == 1

Running my test which uses TestableClass yielded the failure I was after. But it also caused a failed test, rather than the exception that I expected. This makes perfect sense because the unittest module is just looking for an AssertionError to count as a failure and does not mind where that comes from.

And that’s it. You can suddenly run assert something and test the state at a given moment. In my case, I used it to test when a certain element in the HTML is closed or open. Works wonders!

Team RSD rolls into the Castlewood 8 Hour

On December 6th, I took place in my first adventure race with Matt, Scott, and my sister.


At six o'clock, we're loaded onto school buses prepared for "three to seven hours of paddling and trekking" (at this point we know that we have a mountain biking leg not accounted for in the time estimate above). As we drive, we try to guess where we'll get dropped off -- the adventure race takes place in Castlewood State Park, but there are several parks in "striking distance". But eventually I just give up trying to guess after we've crossed the Meramec River.

The team is all green except for my sister, who is used to these racess. We arrive at a field with an open sided barn. Soon after, Matt took off for the prologue, returning with the first clue sheet and a supplemental map (which reveals where we are starting the race from).

Over the next few hours, we have paddle and trek to Route 66 State Park and eventually on to Sherman Beach (Route 66 State Park was the only time we saw the lead teams). At this point we've been going for five or six hours and we still haven't seen the Castlewood. After a few minutes where a teammate was separated, we slug up two different hills for "hilltop" CP's. This trekking is notably more difficult than the orienteering at Route 66 State Park as we basically traverse straight up and straight down hill. Several times Scott nearly collided, uncomfortably with trees as we made our descent.

When we get back to the park we transitioned to the bike leg, finding that they have sent us up all three major hills in Castlewood (Lone Wolf, Cardiac, and Midway). Cardiac and Midway in particular were long lines of people pushing their bikes upward to get to the CPs. Having done much of our bike training in the park, these points are pretty straight forward for us (aided by also having done the Castlewood Orienteering meet a month prior), but we're over the eight hour mark with the 5 PM cutoff looming. We decide to nail down the final two points on the bike (which is tough because our legs feel like lead and both require us to ride up another hill).

Finishing that leg, we transitioned quickly to go grab a couple of bonus CP's and then call it a day, finishing in 9:50. All told, we wrapped up 11th place in our division of 21 which is excellent for a new team! Looking for RSD or another team to roll into some races in '09!


Team Rubber Side Down transitions to trekking to get a final two bonus CPs

New article

I have a new article up on Sitepoint: Section 508: Uncle Sam's Guide To Web Accessibility.

One of these things

... should be found on a bicycle. The other should not:

Props to friendly people on the Maplewood Bicycle Tuesday ride for help wrestling tires I will never buy again.

Back in action

Many exciting things have happen since the last time we met:

Django 1.0 was released and trying to update to the new version broke my site (more correctly, I didn't read any documentation about the upgrade process... so I broke it)! I've finally pieced things together so that they seem to be working again.

My first race

I placed 7th out of 13 in the beginner race at the finale of the local dirt crit series. This was my first mountain bike race, so I arrived early, watched the A race, the B race and chatted up some folks. When the C race set out, I was determined not to be the first through the chutes and by the time we reached the singletrack I had succeeded in that: I was close to the back. At one point I saw an opening to pass some folks, so I started up the right side unfortunately at the same time as someone else. I caught his wheel and went down, throwing me into last place. I remember rolling, ducking and almost colliding with another rider who was behind me as I came up. My chain had of course fallen off, and everyone was at the creek by the time I got back on the bike.

Adrenaline pumping, I began a slow march of catching people. The creek crossing, which I handled fine on the first two laps became more and more sloppy as the race went on. I yo-yo'd with a few guys at this point, but was able to finish well, considering. Speed felt good and my base seemed to be able to handle the short lap count and I think I could have put down a little bit more speed (but maybe not another lap!).

Burin' 2008

The next weekend after the dirt crit, I took on a bigger, badder challenge: the 6-hour solo race for Mesa Cycles' Burnin' at the Bluffs. This is a 6/12 hour race at Council Bluff. It goes without saying that this was my first endurance bike race, but this was the first time I would have spent 6 hours on a bike, let alone my mountain bike (I've done about 80 miles on my road bike which took around 5 hours). Again, I didn't want to be out anywhere near the guys gunning for the fastest lap competition, so I jogged out the Le Mans start towards the back, hoped on and waited through the line at the first bit of singletrack. After a few position changes, I settled in behind a few folks and just pedaled on through.

I passed a couple folks, but not many, but I began to develop a serious issue with my rear derailleur where it was skipping horribly. For the dirt crit, it wouldn't have been an issue because there were little to no hills to deal with. C-Bluff, though, throws down at least three note-worthy climbs (including the one mile climb to get to the start/finish!), so this was pretty bad timing for this issue . So I took some time for a bit of mechanical help between this lap, with the assurance from Scott that my pace was above what I needed for my goal of three laps.

From what I remember, the second lap felt good. I had less issues with climbing (still a bit, but I could ride up hill!) and was able, I felt, to put down some decent speed from time to time. I started getting lapped by some fast guys, but things were going well for me.

When I came in from that lap, I decided to put down some solid food and sit for a minute. Either or both of these were a mistake. The first four miles of the course, I felt off and a bit sick to the stomach. Finally put off these feelings, but the energy was zapped. I took basically any chance I could to rest, took in a lot of fluid and gel, trying to see if that was the issue. But I was pretty much done. The last lap was a pace-killer. After my first couple laps, there was a possibility that I could finish with four laps if I went over 6-hours, but I rode in at 6:25 with 3 laps.

I can't really complain about the race: it was fun, I met my goal of three laps, and I turned out faster-than-expected lap times. And I know what I need to do next year! For 2008, I ended up in 12th out of 20 in the men's 6 hour solo. Not sure if I will hit the 6-hour next year or the 12-hour team, but I'm planning on being there again.

Up next in the race world for me is the Castlewood 8 hour race! This will be the first outing for the "Rubber Side Down" team and the best to date!

Burin' at the Bluffs 2008 photo by WTBiker: http://www.flickr.com/photos/wtbiker/