That said, I do believe in testing the hell out of the system, especially in a QA-less environment like mine. So it shouldn't be too surprising that, with fewer than 30 classes in the system total so far, I've just written my second test harness. The first one was the pure black-box system, based on Selenium: it fires up the browser, runs the app, and puts it through its paces for real. That's my gold standard for testing: no fakery, the real thing from end to end, making sure the user sees what he should.
But black-box testing is a pain in the ass for some kinds of problems. In particular, when I'm dependent on external state -- and especially when the test requires *changing* external state -- it becomes pretty dicey. Today's test case was adding and removing Facebook friends, and making sure that my own cache responds appropriately. That's problematic to test in a completely black-box way, since my test can't control Facebook's database to set the preconditions up easily.
So today's project was to write the white-box test system. This is still pretty high level, mainly interacting with the top-level components of the system, but inserting simulators into all the places where it interacts with the outside world (specifically, Facebook and the browser). As usual, this forced me to improve the code -- for instance, it required coming up with a proper abstraction of the Facebook APIs, so that I could drop a simulator in place of them. And now I've got a nice little JUnit environment that allows me to precisely control my inputs and outputs to tests, which will undoubtedly be very useful on a day-to-day basis; I now have more options about *how* to test new code as I add it.
Overall, I'm pleased: I'm managing to make acceptable progress without cutting corners. Given that I'm still at the "8 stories down, 75 to go" level, this makes me more optimistic that the system won't suck when I come out the other side...