Sunday, September 25, 2011

Rail 3.1 CI setup with Jenkins, Test Unit & SimpleCov on OS X Lion.

I recently had to setup a build server for some rails work I'm doing. Still wanting to support my other projects I setup Jenkins. I ran into several issues.

Running Jenkins as a hidden user

First I noticed that jenkins was running as the "daemon" user, this obviously wasn't going to work for github and rvm needs. So I did some googling and had some guides to get Jenkins running as a specific user. I did the following (sourced from http://colonelpanic.net/2011/06/jenkins-on-mac-os-x-git-w-ssh-public-key/ ). Note: That's really $PASSWORD up above. This gives you a prompt to enter that password. Next you'll need to stop the Jenkins service and edit the plist and start the service back up.
You're plist file should end up like this.


RVM issues

Now my next issue was despite what I'd read elsewhere I was unable to get Jenkins to use the default ruby provided by RVM. So I just pasted the commands that I would run anyway in the "Execute Shell" build step.


Getting Jenkins to see tests

I've been using Test:Unit/Minitest lately just to keep more consistent with my day to day work. However I haven't found a way to get my tests to show when using the "Execute Shell" task. I found a little gem called ci_reporter that exports to the standard junit format, unfortunately it doesn't work with minitest yet. That's ok I haven't done anything that Test:Unit doesn't support so far so I added the the following to my Gemfile (note the part about unit-test 2.0):
Running "rake ci:setup:testunit test" should give you a bunch of xml files in tests/reports. Now we need to tell Jenkins where to find those reports so add a post build action to pick them up as junit reports.



Rcov reports

This was pretty easy.
  1. Install Jenkins plugin for RCov (it's in the plugin list in the admin section).
  2. add simplecov and semiplecov-rcov to your Gemfile.
  3. configure Jenkins rcov plugin to look in coverage/rcov
  4. add the following 4 lines to the TOP of your tests/test_helper.rb file:


In closing

This took a fair amount of time, but the end result was quite satisfying. I now have CI with tests, tests coverage, RVM to target different versions of Ruby and bundler to make sure my Gem environment is sane.

Friday, February 4, 2011

The difficult definition of professional software development

Here are some of the contradictory phrases (and a few paraphrases) I've overheard used to define what is "good" and "bad" code.
  • Code should always be well commented
  • Maintainable code has unit tests and well named methods therefore needs little if any comments
  • Class explosion is to be avoided at all costs
  • Many small simple well named classes are the key to well organized code
  • Unit tests really don't test anything useful
  • Dependency injection leads to an unusable mess
  • Dependency Injection is a very useful tool for making your code extensible and easily reused"
  • Inheritance leads to solid code reuse
  • Inheritance is the strongest coupling of your code you can have
  • Functional programming simplifies and minimizes the complexity of your code
  • Functional programing just makes my eyes bleed!
  • Static global references are 'just programming' and something you have to learn how to manage to make simple easy to understand code
  • Static global spiderwebs are crippling to maintenance and program lifetime
  The part that is most difficult about that list for me is while I agree with half of it strongly and respect the people who said those things, the other half that list I do not agree with, has all come from people I respect and who overall do some pretty impressive things. They've certainly created things by all measures more impressive than anything I've ever produced

  This leads me to question how much do software principles matter when taking them out of the context of yourself but viewing it in a bigger picture? Thinking about it, 95% of the software that I actually like probably wasn't using any TDD at any point in time and certainly violates a number of things that I would consider required for "professional software". I keep reinforcing this fact every time I checkout the source of a major software project I've used for years and gasp in horror at the spaghetti code I find.

  Worse still the different schools of thought are not compatible in the slightest, and one side views the other side as wholly unprofessional (granted for different reasons) to the point that I've realized I myself was perceived as the one being "amateur" by those with a different definition of what makes good and bad software. I of course unfortunately often thought the same of them, regardless of how I felt about them personally.

  Anyway, this is all food for thought and I have not yet come to any conclusion what it all means. I know I've tried coding under other schools of thought and while through practice I was able to deliver well enough, I'm far slower and more error prone with no TDD, big mega classes, and avoiding dependency injection.