Command Line Spotlight

Spotlight is probably my favourite thing about Mac OS X. I recently found out that it’s possible to use spotlight on the command line using the mdfind command. But, the arguments I have to pass to it to get what I want mean that it’s a bit ‘wordy’ and not nearly as convenient to use as the Real Thing. So, I’ve written a tiny function that does exactly what I want:

function sl() {
  /usr/bin/mdfind -onlyin \. $@
}

If you put that in your .bash_profile you’ll have the…

sl

…command available to you (‘sl’ as in ‘SpotLight’). It allows you to type…

sl find this phrase

…which will search for files that contain ‘find this phrase’; but instead of searching system-wide, sl will search the current directory and all child directories.

Tag based logic in Cucumber

Sometimes cucumber’s Before hook just doesn’t cut it. Here’s a nice hack that allows you to perform some logic during execution of cucumber scenarios when a tag is first come across:

It’s a cucumber formatter that detects when a tag is first come across. When a new tag is found, the perform_logic_for method is called, passing the tag to it. Once you’re in the perform_logic_for method, you can do what you like. I’m doing stuff like checking to see if a directory matches the tag name; if I find one, I load the data into an environment (a great example of when the Before tag isn’t enough). You have free reign in here to do what you like with the tag.

To use it, save the file to features/support/tag_logic.rb, add your own tag logic, and then execute it with:

#cucumber -f pretty -f TestManagement::TagLogic -o /dev/null

I hope that helps!

Small print:
Use the Before hook instead of this if you possibly can.

Precision Failure

When tests fail it’s nice to know why. The more precise a failure message is and the less time required to investigate why the test failed, the better.

When trying to find out what broke the test, this…

Failure/Error: search_field.should_not be_visible
       expected visible? to return false, got true

…is infinitely preferable to this…

Failure/Error: search_field.visible?.should == false
       expected: false
            got: true (using ==)

The first failure tells you that the test expected the search field to be invisible, the second that it expected true to equal false – not very helpful. I’d rather have the first error message than the second, and unless you’re a masochist you probably would like the same (though having reviewed a lot of test code, I’m not so sure…).

Cucumber and rspec make “precision failure” easy through the use of matchers. Instead of checking whether “.visible?” returns true or false, you can use rspec matchers to write the following code:

search_field.should_not be_visible
...or...
search_field.should be_visible

…instead of this:

search_field.visible?.should == false
...or...
search_field.visible?.should == true

Your test code will be more understandable, and when tests fail you’ll have a high chance of knowing exactly what went wrong.

So, go and learn about RSpec Matchers!

Silencing Log4Net in White Automation

The BBC Journalism WPF app is currently tested by a suite of bewildr tests. Sadly we also have a bunch of legacy tests written using White which we have to monitor. As anyone who uses it knows, White has a habit of dumping logging messages everywhere due to its use of log4net. An example:

Log4Net not configured. Looked for file: D:\...\...\log4net.config
Using RecheckDurationInMilliseconds=100 for Bricks/Bricks

There are hints on the white website that try to help out with silencing the log messages, but they don’t work. What’s needed is a vicious butchering of the log messages; and here’s how it’s done:

  1. Create a file called log4net.config in your project root
  2. Set the file contents to the following:

<log4net threshold="OFF" />

That will silence log4net – no more will filth be spewed all over the console!

RSpec and ci_reporter

In order to use rspec within hudson, you need to use the ci_reporter gem. The gem extends rspec’s behaviour to include the junit-style output required by hudson. Annoyingly, the documentation for creating a rspec rake task that uses ci_reporter is a bit sparse and not particularly “googleable”, so I’m putting some example code here for posterity. The following is all that is required in a Rakefile for the most basic rspec task that integrates with hudson:


require 'rspec/core/rake_task'
require 'ci/reporter/rake/rspec'

RSpec::Core::RakeTask.new(:all => ["ci:setup:rspec"]) do |t|
  t.pattern = '**/*_spec.rb'
end

You can now run the rspec task named “all” within hudson and get pretty results, graphs, and all the other goodness that hudson derives from junit output files. To run the above task:

rake all

Hope that saves you some searching around!

Tagging with Git

My brain just doesn’t seem to be able to store the git commands for tagging commits and then pushing the tags. So, primarily for my benefit, here’s how to tag a commit and then push the tags:

git tag -a v0.1.2 be4410b0d4e805f4b94c4f271980b0c44c998745 -m v0.1.2
git push --tags

…where be4410b0d4e805f4… is the commit hash.

Announcing ‘responsalizr’ – test HTTP Response Codes in Ruby

Get it here:

gem install responsalizr

Responsalizr is a very small and very simple gem I’ve written that extends the standard ruby Net::HTTPResponse class with a few methods to allow for idiomatic testing of HTTP response codes. The methods added are:

  1. A numeric response code comparer:
    • code?(integer) #eg: code?(200), code?(404)
  2. Response type name comparers:
    • ok? – corresponds to code 200
    • not_found? – corresponds to code 404
    • moved_permanently? – corresponds to a 301
    • etc…

    The response type name compare methods are derived from the subclasses of Net::HTTPResponse; you can find a table with their names at the bottom of this post.

Here is an example rspec script that demonstrates what you can do with responsalizr. Each test does the same thing twice; once doing a numeric response code compare, the other doing a response type name compare:


require 'rubygems'
require 'responsalizr'

include Responsalizr

describe "Google" do
  it "should respond to the uk homepage with a 200 or an ok" do
    Response.from("http://www.google.co.uk").should be_ok
    Response.from("http://www.google.co.uk").should be_a_code 200
  end

  it "should respond with a 404 or not found" do
    Response.from("http://www.google.com/bing.aspx").should be_not_found
    Response.from("http://www.google.com/bing.aspx").should be_a_code 404
  end

  it "should respond with a 302 or a moved permanently" do
    Response.from("http://finance.google.com").should be_moved_permanently
    Response.from("http://finance.google.com").should be_a_code 301
  end

  it "should be testable through a proxy" do
    Response.from("http://www.google.co.uk", {:proxy_host => "63.223.106.54", :port => 80}).should be_ok
    Response.from("http://www.google.co.uk", {:proxy_host => "63.223.106.54", :port => 80}).should be_a_code(200)
  end
end

Chose whichever way you like (codes/names) and – I’ve only used both above for demonstration purposes.

So, if all you’re doing is testing HTTP responses for their code (whether you want to do that with codes – 404 – or names – not_found) then responsalizr is the thing for you.

About the specific response name methods and their respective codes, here’s a table that summarizes them:

Response Type Name Response Code
information? 1xx
continue? 100
switch_protocol? 101
success? 2xx
ok? 200
created? 201
accepted? 202
non_authoritative_information? 203
no_content? 204
reset_content? 205
partial_content? 206
redirection? 3xx
multiple_choice? 300
moved_permanently? 301
found? 302
see_other? 303
not_modified? 304
use_proxy? 305
temporary_redirect? 307
client_error? 4xx
bad_request? 400
unauthorized? 401
payment_required? 402
forbidden? 403
not_found? 404
method_not_allowed? 405
not_acceptable? 406
proxy_authentication_required? 407
request_time_out? 408
conflict? 409
gone? 410
length_required? 411
precondition_failed? 412
request_entity_too_large? 413
request_uri_too_long? 414
unsupported_media_type? 415
requested_range_not_satisfiable? 416
expectation_failed? 417
server_error? 5xx
internal_server_error? 500
not_implemented? 501
bad_gateway? 502
service_unavailable? 503
gateway_time_out? 504
version_not_supported? 505
unknown_response? xxx

Because of the rspec (and cucumber) predicate magic, you can use, eg, the bad_gateway?, the forbidden? and the internal_server_error? method as follows:


...should be_a_bad_gateway
...should be_forbidden
...should be_an_internal_server_error

Happy HTTP Response Code testing!

Counting strings in a file: Ruby vs Windows Command shell

This is not the usual material that I put up, but I’d like to immortalize an event that demonstrated yet again the beauty of Ruby for basic file manipulation, especially in contrast to doing the same in a Windows command shell. Here goes:

“Nat, I need a script that displays a count of the number of instances of a string in a file. The output must be a number and nothing else.”
“No worries, that won’t take 2 seconds.”
“Stop right there – I don’t want any of your ruby nonsense – it must be a batch file.”
“Hmmm… Can the batch file call a ruby script?”
“No.”
“Err… ok… I’ll see what I can do.”

So off I went trawling google, stackoverflow, random blogs, and websites which can’t have seen hits since 1995. One hour, some frustration, and several cups of tea later, this is what I came up with:

findstr /C:"search string" "c:\my\file.txt" | find /C /V "nonsense"

And that, ladies and gentlemen, works! Let me explain what’s going on… The script uses 2 commands: findstr and find. findstr is used for finding strings in files, and find is also used for finding strings in files. It of course makes perfect sense to have two commands that do the same thing – the very definition of the word “intuitive”. In the above example, findstr returns lines from the file that contain the search string. These lines are piped to find which then displays the number of lines that don’t contain a particular string, in the above case: "nonsense". That will return a number. It’s the only way you can get find, findstr or a combination of the two to return a-number-and-only-a-number of the instances of a string in a file. I would love to see this improved – leave a comment if you know a better way to do it.

To demonstrate to myself why doing the above in DOS is crazy, I wrote the same line in ruby:

File.open("c:/my/file.txt").read.scan(/search string/).count

It doesn’t take much explanation: It opens a file, reads it, scans it for a search string and then returns the number of instances it found.

Now. Can we all start using the right tool for the right job please? I know it may involve a bit of learning, but that never hurt anyone. That is all.