Thursday, June 12, 2014

mini post - Chef (Opscode) best practices series - Unit testing and TDD

The argument of TDD is great and all, but I do not think it's directly applicable to Chef.

Here is the idea - Chef offers a lot of resources, and a lot of ways to skin the cat/dog/lizard/etc.. So you simply can't write unit tests first, because you don't actually know which resources you're going to use to skin said animal.

What you CAN do, is write integration tests first. Because you DO know the ultimate outcome of your cookbook. And you can write Stubs for your unit tests ahead of time, if that makes you feel good.

Lets say you want to write a WSUS cookbook. The goal of the cookbook is to install WSUS role on your server. So your TDD (test driven development) for installing WSUS server would look something like this:
/> knife kitchen create wsus (or knife cookbook create wsus)
Your unit test would look very generic:

it 'installs some prerequisite that came with windows' do
end 
it 'downloads some prereq that didnt come with windows' do
end 
it 'installs the downloaded prereq' do
end 
etc...
Your integration tests on the other hand, would look very specific - Because you know ahead of time what constitutes a functional WSUS server.

 describe package('wsus') do
   it { should be_installed }
 end 
describe service('wsus') do
  it { should be_enabled   }
  it { should be_running   }
end 
describe port(3859) do
  it { should be_listening }
end
etc... 
IMHO, that's the best you can do when it comes to TDD with Chef. If you start with unit tests you're forcing yourself down the path of constantly re-writing your tests... over and over and over...

Here is an image of DNA relication.



No comments:

Post a Comment

Comments are welcomed and appreciated.