August 28th, 2008 cschneid
I just read a post over at proggit titled “Can Unit Testing be a Waste?”. The basic argument was that unit testing should go at the problem from a high level of abstraction, and you shouldn’t worry about going after every low level method in your DAO classes, or your User model.
One of the ways the author used to justify his argument was an example in Java that testing the high level got an overall coverage amount in the 95+% range. This is a misleading number.
The goal of unit testing is not to run your code, that only shows that you compile, and don’t blow up. At best it’s a form of smoke testing. The goal of unit testing is to ensure that your unit works as expected, and because you’re so close to the unit, you’ll be able to setup the environment (and mocks) to simulate issues and problems.
Then you verify using the various asserts.
My argument against using the highest level of abstraction is that you give up some of the core benefits of unit testing, namely the ability to really dig into your implementation and identify edge cases, and error situations.
Before I get yelled at, I know that going too low into the nitty-gritty ties your unit tests too closely to your code, which negates many of the “safety net” features that make refactoring easy. Honestly, what I think was being described in the “Can Unit Testing be a Waste?” post was integration (or feature, or validation, or whatever term you like) tests, not unit tests.
Stop getting sidetracked by coverage, focus on what bugs are being exposed by your test code, and focus on the benefits you get from writing the test case.
August 16th, 2008 cschneid
I setup Passenger (mod_rails) on my Macbook Pro last night, with the Passenger Preference Pane. I ran into a few small issues while doing it, and hopefully I can share them, and their solutions.
The gem install - First I did the standard gem install.
sudo gem install passenger
Apache setup - Then do the passenger apache installation, which compiles the module, and has details about the exact content you need to insert into httpd.conf
httpd.conf setup - The passenger-install-apache2-module dumps a few lines to the console that need to be included in httpd.conf. Edit /etc/apache2/httpd.conf (
sudo vim /etc/apache2/httpd.conf). I put the inserted lines near line #117 in my httpd.conf, after the rest of the modules are defined.
LoadModule passenger_module /Library/Ruby/Gems/1.8/gems/passenger-2.0.3/ext/apache2/mod_passenger.so
Use the preference pane to setup an app - For testing purposes, I just used a rails app. I wanted to be sure Passenger was working correctly before going after Rack apps. Very quickly, I ran into an issue. This line was in
[Fri Aug 15 21:23:11 2008] [notice] child pid 48688 exit signal Abort trap (6)
terminate called after throwing an instance of 'Passenger::FileSystemException'
what(): Cannot stat '/Users/cschneid/Documents/Programming/Rails/BashFight/public/../config/environment.rb': Permission denied (13)
[Fri Aug 15 21:38:17 2008] [error] [client 127.0.0.1] (13)Permission denied: access to / denied
The solution to the permissions - It turns out that there is another step that is only mentioned in a single mailing list post. Apache needs another entry allowing itself access to the files. This is different and distinct from the filesystem permissions, which confused me for a while while trying to diagnose this.
Allow from all
Not quite - filesystem permissions matter too! After finding mention of the apache user directory details, I thought I had it fixed. BUT… not quite. It turns out that Apache needs file system permissions all the way up and down the file system tree. As you can see above, I keep all my code in /Users/cschneid/Documents/Programming/…. What turned out to be the final problem I faced was that /Users/cschneid had a permissions of 700. Apache was giving up because of that. A quick
chmod 755 /Users/cschneid fixed that problem. Just know that you need to check permissions on every directory in the path to your app.
The Sinatra App - Works exactly as you’d expect. Go see my various posts on deploying to a Passenger install (Another try w/ logging), (Deploying to Dreamhost) to see how to setup your config.ru file.