Archive > March 2009

The Perils of Testing Code

» 25 March 2009 » In Technology » No Comments

Testing code is good, right? No! Testing code is bad. Testing functionality is good. How many of us have written a bunch of code and then turned around and wrote a bunch of tests for that code? Be honest! Everyone has done it, but why is it a bad thing? The problem with this is that far too often you end up testing what the code DOES, not what it SHOULD DO. This has always been one problem with testing your own code. You assume your code is correct, so tests are written that validate the code. Unfortunately, all this does is keep you honest in case you change the code to cause the test to break. You have not proven that the code does what it’s supposed to do.

Here is a quick example in RoR:

app/models/user.rb:
class User < ActiveRecord::Base
  def unsubscribe!
    add_role(Role::UNSUBSCRIBED)
    forget_me # this will save
  end
end

test/unit/user_test.rb:
class UserTest < ActiveSupport::TestCase
  test "should unsubscribe" do
    user = users(:dave)
    assert user.unsubscribe!
    assert user.unsubscribed? # Assume I have a test for this as well
    assert_nil people(:dave).remember_token
  end
end

Great, we have a test that verifies that the user is unsubscribed. The problem is that when a user is unsubscribed, they SHOULD have had all their email preferences turned off as well. The code is wrong, but the tests will not catch that because the test only verified the code as written.

This is where Test Driven Development (TDD) comes in. With TDD, you write the tests for the functionality you want to happen. Once you described all the desired functionality as tests, you write the code necessary to make all the tests pass. Now, you’re testing what the code should do and not what it does. I’m on board with this, but there are a few problems in the real world.

The biggest problem that I have with TDD is that it assumes you know what the code should do in the first place. Unfortunately, when you innovate you don’t always know what you will end up with. You’re experimenting, trying new things, seeing what sticks. This is normal for many projects. Still, you need to have tests to verify things once you do settle on a direction.

How does this fit into TDD? It doesn’t fit directly because you aren’t writing tests first. What I do in this situation is the following:

  1. Once I settle on a direction and set of functionality, I attempt to write the tests for what I have without looking at the implementation code. Write the tests to verify your intended results rather than looking at the code to see what it does. I’m trying to avoid the perils of testing the code.
  2. Now that I have a direction, I can go back to writing the test followed by making the test pass.
  3. If a problem is discovered anywhere, I write a test to reproduce the issue before fixing it in the code.

The other issue I have with TDD is how do I write code to verify what code should do if I don’t know how it is supposed to do it? When writing the tests, I have to leave many method calls blank until I figure out how things are done and what I should check. Often, I go back to the above until I have a set of standard methods to use, or better yet I let the tests determine what the methods should be. Either way, the above scheme still works for me.

This hybrid approach works for me, but YMMV. The bottom line, as always, is that the code isn’t done until the tests are done as well.

Now, go write some tests!

Continue reading...

Tags: , ,

Replacing Mongrel with Passenger (mod_rails)

» 23 March 2009 » In Technology » 6 Comments

I’ve been using Apache + Mongrel for a while now. I read about Passenger when it first came out, but I never felt the need to bother with it since I have a bunch of recipes for Apache and Mongrel (see a previous posts about background tasks with Workling). The other day, I figured I would give it a shot. Now, I think I found my new way to deploy Rails apps. It is so simple, and it works well.

Some people write off Passenger because it uses Apache and not Nginx. Nginx is a little faster, and it is the latest “best practice,” but I haven’t had issues with Apache in forever. As for the speed issues, I don’t see it being a big factor to the end users. A few milliseconds is not going to be noticeable, at least for my apps.

Installation could not be simpler.

  1. sudo gem install passenger
  2. sudo passenger-install-apache2-module
  3. Follow the instructions the previous script displays
  4. Restart Apache
  5. Done!

If your development machine is OSX, don’t bother to manually change the Apache conf for your application and your hosts file just yet. You can use the Passenger Preference Pane instead. This little beauty will make all the changes to your Apache config files for you. One of the benefits is that you can have dozens of small Rails projects configured, and all are available with their own url — no need to run script/server for each. For install, the site explains it pretty well, so I won’t go into it here.

I did run into one problem on my Leopard machine. My default Apache config file had the httpd process running as the _www user, but my project files are owned by me. The result is that I kept getting permission errors accessing files in my project. I’m sure there is a solution to the problem by changing the permissions on my project files, but I didn’t find it. I ended up running httpd as me, and that fixed it. I did not have this issue on my test or production systems.

Even with the problem, the entire process took me less than an hour. What I gained is the following:

  • I no longer have to run script/server every time I switch to a new application for development.
  • All of my apps on my dev machine have their own url (myapp.local, etc.) instead of localhost:3000.
  • My god.rb config no longer has to watch Mongrel processes. It’s all in Apache.
  • No Mongrel cluster or load balancing in Apache configs among multiple Mongrels. Apache just operates normally, and my config files are a lot simpler.
  • Mongrel hasn’t had any updates in while, but Passenger is still under active development.
  • An added benefit is that my test/staging server performs better since only the applications being used are running. By default Passenger will drop any process not accessed in 300 seconds (you can change that).

All of the required changes involved removing any references to Mongrel in my god.rb config, apache config, and my deploy.rb. The only thing I needed to actually change is how to start/stop/restart my application. Remember, there is no mongrel process to start or stop. It’s all Apache. Passenger makes it easy, however. All you need to do is touch tmp/restart.txt. If that file is modified, then Passenger will restart your application.

My updated config/deploy.rb:

namespace :deploy do

  desc "Start the application"
  task :start, :roles => :app do
    run "touch #{current_release}/tmp/restart.txt"
    sudo "god start listeners"
  end

  desc "Stop the application"
  task :stop, :roles => :app do
    # Do nothing for application
    sudo "god stop listeners"
  end

  desc "Restart Application"
  task :restart, :roles => :app do
    run "touch #{current_release}/tmp/restart.txt"
    sudo "god restart listeners"
  end
end

Give Passenger a try. I think you will like it.

Continue reading...

Tags: , , ,

Music Is Dead: iPods and Young People Have Utterly Destroyed Music

» 19 March 2009 » In Life, Technology » 1 Comment

Music Is Dead: iPods and Young People Have Utterly Destroyed Music

This is depressing for someone like me. A Stanford professor did an informal study over several years, and he found that students each year preferred low-quality MP3 more and more. Like the author, this is disappointing for me because it most likely means it will become harder to find high-quality music. It’s already hard, but it will get worse. Even CDs are being mixed with MP3 players in mind.

I guess it comes down to what you’re used to. If it’s all you ever heard, then you don’t know what you’re missing. Personally, I am spoiled by hundreds of high quality live performances, and I always wanted to recreate that sound at home as much as possible. Low quality MP3s just don’t do it for me. They are fine on my iPhone or small player, but when I sit in front of my home system I want to hear like I was in the studio.

I had a similar experience many years ago when I had a top-end VCR with one of the best TVs available at the time. I thought the picture was amazing. Then I hooked up a cheap DVD player, and I forgot all about the VCR. The problem here is that these low quality recordings are becoming so much the norm that it will be hard for anyone to know what they are missing.

What is a music lover to do?

Continue reading...

Tags: , ,

Phew! That was close!

» 02 March 2009 » In Life » No Comments

I’m not sure why, but I seem to be on an astronomy kick lately. I came across a little tidbit today that reminded me of Deep Impact and Armageddon. At 13:44 UT today (March 2, 2009), a 30 meter asteroid (identified as 2009 DD45) will pass by earth and miss by only 37,282 miles. Even though it isn’t that big, it’s big enough that it would do some serious damage if it hit. As an example, the meteor that made the Barringer Crater in Arizona is estimated to be about the same size as this one, and the Barringer crater is 570 feet deep and nearly a mile across. To give you an idea how close we came to another crater, 37,000 miles is not quite twice the distance of a geostationary orbit. Unfortunately, you will not be able to see it because it is too small and moving too fast (1/2 degree per minute).

I take comfort that we are least finding these objects. I guess it doesn’t matter much either way, since there will not be much to do if one was found to be on a collision course. At least we will know it’s coming.

FYI, asteroid 2009 EA4 will pass by earth tomorrow doing 21,050 mph. Its closest distance will be over 1.7 million miles — still close by astronomical standards.

Continue reading...

Tags: