JRuby & JTestR in Eclipse

Continuing my rampage upon the JRuby community, I have achieved beautiful success with running my tests inside of the eclipse IDE as a JUnit test. Now I have limited knowledge in the JUnit realm and encourage those to improve upon my approach.

In your eclipse Package Manager sidebar, Right Click -#> Run As.. -#> Run Configurations. Go ahead and select ‘JUnit’ and hit the ‘New Launch Configuration’ button.

Fill in the configuration as follows:

* Run a single test
Project: your-project-name
Test class: org.jtestr.ant.JtestRSuite

Now just open the ‘Arguments’ tab and inside the ‘VM arguments:’ box

-Djtestr.junit.tests=rspec_tests

rspec_tests is the folder where my tests are stored, feel free to change this to something like /test/jtestr/funny_test or whatever structure you store your files in.

I am still trying to figure out a more effecient way to get these test to run under eclipse. Till than I can always fall back on this approach as well as the standard ant task.

Git your own server!

With the recent boom of GitHub, there are thousands migrating from old subversion and even cvs servers to git. Surprisingly however, many people would rather pay GitHub to host their site instead of doing it themselves. Well I may be on the git bandwagon, but I am definitely not on the pay-for-git one. I recently setup two git servers (for redundancy). This will be a brief tutorial on getting your own git server running on Debian Etch/Lenny/Sid (or Ubuntu).

First we need to install git. Simple enough with this command:

$ sudo apt-get install git-core git-doc git-svn git-email git-cvs

Now we want to ensure git installed correctly

$ git --version
git version 1.5.6.3

If you are running Debian Etch, you need to use the backports-etch repo to install git >= 1.5. Or compile it from source.

Alright then just follow the commands:

$ sudo apt-get install python
$ sudo apt-get install python-setuptools

Once those are installed just copy paste the following commands. We are going to use gitosis as a way to manage repositories and git access privileges.

$ git clone git://eagain.net/gitosis
$ cd gitosis
$ python setup.py install

If you receive any errors from running the setup.py script, ensure you installed all the packages above from apt-get.

$ sudo adduser \
     --system \
     --shell /bin/sh \
     --gecos 'git version control' \
     --group \
     --disabled-password \
     --home /home/git \
     git

This will setup all your repositories inside of /home/git, feel free to change this to whatever location you desire. Now thats all done, we just need to get your SSH certificate setup so that you can initialize your gitosis install.

This is how it would be done on OSX (this guide for full info on generating SSH keys). From your local machine, issue this command:

$ scp ~/.ssh/id_rsa.pub yourusername@yourserver:/tmp/

Now to wrap this up quickly, go back to your server and setup the SSH key for the gitosis repo.

$ sudo -H -u git gitosis-init < /tmp/id_rsa.pub

If you get an error on initialization then you do not have git >= 1.5. For the rest of us, now we just need to edit the gitosis repo to add/delete users and git repositories! Issuing a simple git push, will propegate the change. For full information, see the gitosis README.

My Design_fu is lacking, need help!

This time had to come sometime, I have been ignoring it for just too long. I need to find a web designer. For years I have been able to get away with modifying open source layouts and copying trends on other sites. Well it just isn’t going to cut it for the web applications I have coming through the pipe right now. This definitely is an interesting problem that I am sure many software developers face. Exactly how I am going to find someone and build a work relationship remains to be seen. The majority of designers are either of ‘template monster’ quality or they are working for larger media/print corporations which are FAR out of my budget. Maybe I should write 37signals and tell them to add a chapter on this to their ‘Get Real?’ book…

As always, I will keep blogging as the search continues to unfold. Wish me luck!

JtestR - alive and kicking

Last week I posted about my JtestR problems and the lack of any solution. Well after some generous help from Ola Bini, JtestR’s lead developer, we found the problem. Apparently, you cannot run your Java application with the jtestr.jar file inside the root directory. The jar must be placed within a subdirectory, otherwise your Ruby runtime will try to include the JtestR.jar file through its require ‘jtestr’ statement. Its an odd quirk, with an easy workaround. Ola Bini has said its fixed in the latest trunk build, but to use the workaround until 0.4 comes out. I would like to thank him for all his help troubleshooting this issue. Cheers!

datamapper_fu

I have been discussing the potential of developing a datamapper-native attachment_fu port in the #merb and #datamapper channels. The response seems to be in agreement that this type of plugin needs to be developed, as building an ORM agnostic plugin of this type would add user configuration and confusion. Also in the spirit of Merb, “no code is faster than no code”. This may spawn other merb plugins under the _fu tag, but we have to start somewhere! Its also being discussed as to what happens with attachmerb_fu, and it seems to be heading down the AR-native route.

The project has its initial commit and encourage you to come contribute either through testing or actual code.

JtestR woes.

At work, all of our test and behavior driven development is done through the Fit libraries and an application layer called FitNesse. Now these are two tools that really fill a much needed void in the Java development world, however being an avid Ruby supporter I know that is far from the best. I decided to try RSpec and see if it had the chops to replace the dated and lacking Fit library.

It took about a day’s worth of google searching to find the best plan of action. Originally, I wanted to wire up JRuby and RSpec myself, but it seemed to involve too many hoops to be a viable option. Then I ran into JtestR thinking that it would be the end-all solution to my Java testing troubles. I was wrong.

The two days spent trying to get JRuby and JtestR to play nice with my Java project has culminated into an amazingly cryptic stack trace:

[junit] Exception in thread "main" java.lang.RuntimeException: Exception while running
    [junit]     at org.jtestr.JtestRRunner.execute(JtestRRunner.java:97)
    [junit]     at org.jtestr.ant.JtestRSuite.run(JtestRSuite.java:376)
    [junit]     at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:289)
    [junit]     at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:656)
    [junit]     at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:558)
    [junit] Caused by: org.jruby.exceptions.RaiseException
    [junit] Test org.jtestr.ant.JtestRSuite FAILED

Now begins the adventure of asking JtestR’s lead developer, Ola Bini, for help. It seems he is not entirely sure why this problem is occurring which is not very comforting, when I am pitching RSpec as a test replacement for Fitness in a few weeks. I will keep you posted with updates, feel free to follow the mailing list.

Reposting interview

Ran into this after launching up my old rails project for an interview. Figured it was worth reposting on a site that is live all the time. This interview took place back in March 2008.

RSpec puts my mind at ease.

Green never looked so good. Now that I am finally getting used to all the new RSpec syntax changes and settled into the 100% coverage realm, it is time to refactor some of my tests using some lambda tricks I have seen around the net. :)

RSpec - Mocks and Stubs

Behavior Driven Development (BDD) has become a driving force in the development industry right along the process of agile development. The two are almost synonymous with each other if you have done any sort of Agile/XP/SCRUM process on any of your projects. In the ruby world and the surrounding communities, RSpec has evolved as the leader for applying BDD practices and I felt it was about time I mastered the BDD process for all my projects.

The beauty of RSpec is in its simplicity. The code is very readable by anyone who comes across of it. For me, the syntax was the easy part. The headaches began once I tried to wrap my head around mocks (mocking) and stubs. Stubs seemed easier to start with, so I hit Google confident that my answer was just clicks away.

Well, I was wrong… After spending about an hour researching stubs, I figured maybe I should look up mocks. Unfortunately though, I got the same result posted at over 20 blogs. It was a link to a site called mockobjects. Now I am sure that somewhere on that site I could piece together an understanding of mocks and stubs, but I already had wasted a couple hours and did not have a day to spend on picking up these, seemingly simple, concepts.

Finally a ray of hope came when someone over at RailsForum posted the question I had been asking. The answers, although similar to ones I had read, made it clear as mud enough for me to take a stab at trying out some code. This is what I ended up with:

require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe UsersController, 'working with the show action' do

before(:each) do
@user = mock_model(User)
User.stub!(:find).and_return(@user)
end

it "should call the action successfully" do
get :show, :id => "1"
response.should be_success
end

it "should find the user" do
User.should_receive(:find).with("1").and_return(@user)
get :show, :id => "1"
end

it "should assign the found user to the view" do
get :show, :id => "1"
assigns[:user].should eql(@user)
end

end

describe UsersController, 'working with the index action' do
before(:each) do
@user = mock_model(User)
@users = [@user]
User.stub!(:find).and_return(@users)
end

it "should call the action successfully" do
get :index
response.should be_success
end

it 'should find the users' do
User.should_receive(:all).and_return(@user)
get :index
end

it 'should assign the found users to the view' do
get :index
assigns[:users].should eql(@users)
end
end

describe UsersController, 'working with the new action' do

end

describe UsersController, 'working with the create action' do

end

describe UsersController, 'working with the destroy action' do
before(:each) do
@user = mock_model(User)
User.stub!(:find).and_return(@user)
@user.stub!(:destroy).and_return(true)
end

it 'should find the user' do
User.should_receive(:find).with('1').and_return(@user)
delete :destroy, :id => 1
end

it 'should destroy the user' do
@user.should_receive(:destroy).once
delete :destroy, :id => 1
end

it 'should redirect to index' do
delete :destroy, :id => 1
response.should redirect_to(users_path)
end
end

Now I know I should have started with snippet by snippet and build up to a big post. However I feel its much easier to post the end result then break it down as we go, and its much quicker :)

Stubs: Simply put, it allows you to build canned responses to method calls. The reason for doing this is to maintain fast test execution by removing any database calls. Another factor is your controller tests (also known as functional tests) don’t need to rely on your models. Now when something breaks you don’t need to troubleshoot where to look since the model and controller are tested separately.

Mocks: Unlike stubs, I think of mocks as a basic barebone instance of an object. If you were to just define

@user = mock(’User’)

The @user object would respond to anything defined in your model. This means there is coupling between controller and model, unlike stubs, meaning when your tests break you need to do slightly more debugging. The amount of debugging can be minimized through good design.

To be continued.

Ruby 1.8.6 / 1.8.7 living side-by-side

With the most recent update of OSX, Apple did not update Ruby from 1.8.6 to 1.8.7 even though there are significant improvements incorporated into the new version. I decided that instead of waiting for Apple to update my default Ruby install, I would do it myself. My goal was to keep the default Apple Ruby install of 1.8.6 alone and install 1.8.7 through MacPorts. That was the easy part.

$ sudo port install ruby
$ sudo port install rb-rubygems

This will give you both ruby and a rubygems install. The way to make this installation the default is to adjust your PATH to have /opt/local/bin/ as the first item in your PATH definition (which is set in ~/.bash_profile).

PATH=/opt/local/bin:$PATH

Then reload your terminal or execute:

$ source ~/.bash_profile

Now here comes a nicety that many people will really appreciate. We want both version of Ruby to share the same gems! This is simply set (adjust paths accordingly if your not on OSX 10.5) the following inside your .bash_profile.

export GEM_HOME=`/usr/bin/gem env home`
export GEM_PATH=`/usr/bin/gem env path`

Make sure you use ` marks and not ‘ or “. This will use your 1.8.6 ruby gems as the source for your ruby gems. There you go, now you have two versions of Ruby living side by side in harmony, its so beautiful it brings a tear to my eye.

The goal of this is that you can leave the Apple install alone and if you ever want new (more current) ruby versions, you can just issue an update command via MacPorts. Thanks to drbrain for the help on troubleshooting this setup.