Categories
Agile BT

Concurrent design and development – a better spin?

Another day, another argument discussion with a colleague over the common misapprehension that you can have a process with discrete requirements capture, design, development and test phases, yet somehow still claim to be agile. Once again, I tried (with limited success) to explain that you don’t need to do all your designing up front before you start writing code, and that starting to write code almost immediately isn’t ‘hacking’, provided that you are continuously paying attention to good design as you go.

In other words, agile developers do just as much designing as those still following waterfall methods, but we do it at the same time as writing the code.

Reflecting afterwards, I realised that I’ve been phrasing the message the wrong way. As anyone who really ‘gets’ test-driven (and particularly behaviour-driven) development knows, it’s not really about the testing, but about the design process. A waterfall ‘designer’ starts from an understanding of the problem and builds up some kind of model for a solution, which they then pass on to the implementors An agile developer does exactly the same, but the language they use for the model happens to be executable source code rather than documents or UML. This choice of modeling language has the rather large benefit of being testable, and once your design is finished, you’re done. No need for someone to try to interpret and implement it. No scope for misunderstandings between designer and developer. No danger that the design is incomplete, or that part of it turns out to be unworkable.

It’s not that we start writing code and design as we go along.

We are always designing – we just write the code as we go along.

[tags]agile, tdd, bdd[/tags]

Categories
Rants Software

Steven Fry’s call to arms

Steven Fry has written a detailed comparison of smartphones on his blog. It’s quite long, but very entertaining (as you would expect) and well worth a read.

As a ‘corporate software engineer’ myself, this in particular struck a chord:

Break free, all you corporate software engineers and designers: the excuse that you are under the rule of dullards, greedy share-price number crunchers and visually and ergonomically illiterate yahoos is not good enough. Persuade them. Otherwise we all get a digital environment that’s a vile as a 60s housing estate.

Amen to that.

Categories
Software

Search in Google Reader at last!

Google reader now has a search facility, which is nice. I can’t help wondering why it took so long though – I mean surely they have a little experience in the organisation of writing search tools?

[tags]google, reader, search[/tags]

Categories
Agile

Agile2007: Wednesday

As you may have noticed, I’m getting a little behind posting these. On the offchance that anyone’s actually reading, rest assured that I still have my scribbled notes, so they’ll be appearing here eventually.

Presenter First: TDD for Large, Complex GUIs

Scott Miller (Atomic Object)

I was torn between this session and the one on Ruby metaprogramming, but it wasn’t clear who that one was pitched at, so I decided not to risk sitting through another basic tutorial. Alkesh went to the Ruby one, and apparently it was pretty good (if I’d noticed that David Chelimsky was presenting, I probably would have gone along). Anyway, as we all know Alkesh doesn’t have a blog (actually that’s not strictly true), so you won’t be able to read about it :-)

Categories
General nonsense Ruby

Duck typing for dummies

def duck?
  respond_to? :quack
end
Categories
Agile

Agile2007: Tuesday

Keynote: Reaching New Heights: Learning to Adapt is Essential

Susan Ershler

I’m not quite sure what to make of this keynote. Susan’s talk about achieving her twin goals of success in business and climbing the highest peaks on each continent (culminating in Everest) was interesting and well-presented, but came across to me as a motivational speech for business leaders, slightly tweaked to include a few agile themes. I’d have preferred to hear something more concrete from a thought leader in agile development (after all, there are a fair few of them here!)

Categories
Agile

Agile2007: Monday

The first day of the conference didn’t get started until after lunch, so we took the opportunity to go up the Washington Monument in the morning (I’ve been posting some photos from the trip to Flickr, by the way).

Most of the slides from the conference are on the Agile2007 website, so I’m not going to go into great detail about any of the sessions here (not that I would have anyway!), but just mention the things I thought were interesting enough to specifically note down. This will probably mean that things are a bit jumbled, so sorry in advance.

Categories
Ruby

Unimplemented specs in RSpec

One of RSpec‘s many neat features is the ability to insert placeholder specs. These allow you to list a whole bunch of expected behaviour up front, without having to implement either the specs or the code, and without creating a huge swath of failing specs. All you need to do is omit the body of the specify or it block. Here’s a trivial example:

describe "The string 'foo'" do
  before do
    @foo = 'foo'
  end
  
  it "should be three characters long" do
    @foo.size.should == 3
  end
  
  it "should be capitalised to 'Foo'"
end
$ spec -f s foo_spec.rb                     

The string 'foo'
- should be three characters long
- should be capitalised to 'Foo' (NOT IMPLEMENTED)

Finished in 0.011201 seconds

2 examples, 0 failures, 1 not implemented

[tags]ruby,rspec[/tags]

Categories
Ruby Web 2.0

Updating FaceBook status from Twitter

I’ve recently jumped on the Facebook bandwagon. I can’t be bothered to update two statuses (I rarely get round to it with one), so I was looking for a way to update my FaceBook status from Twitter. I installed the Twitter application in FaceBook, but that just displays the Twitter status separately.

It seemed that the only way to do it was to write a script to regularly check Twitter, and update FaceBook when it found a new Twitter message. I found a partial solution in PHP, but decided to roll my own in Ruby anyway.

It took a few hours longer than I expected (the documentation for Net::HTTP could be better), but I got there in the end. I now have the script below installed on my DreamHost account, and set to fire every minute via cron. It’s not the prettiest code I’ve ever written, but it does the job. Feel free to borrow it if you think it’ll be useful.

Andrew ‘Boz’ Bosworth
11:29pm September 6th

I’m an engineer at facebook and I’m writing to ask if you would be willing to take down the link to your facebook/twitter status sync utility (located on your website kerrybuckley.com). Based on your comment on TechCrunch I suspect you anticipated this would be coming at some point. Even if your intended use of such a script is noble (as I’m sure it is), the simple script you have posted on your site is (and has always been) against our terms of service. Said more shortly, we just can’t let people automate aginst our site outside of the platform; it’s a slippery slope.

We’d obviously like to resolve this without disabling your account or getting the lawyers involved if possible, so please let me know as soon as you’ve taken the script down so that our legal department doesn’t get all fired up about this.

thanks,
Andrew Bosworth
Facebook Engineer

My reply:

Andrew,

As you’ll probably expect, I’m not particularly impressed with Facebook’s current stance on openness in general, or on this issue in particular. I hope that at some point you add an API to allow remote updating of status, in the same way that you recently added an RSS feed to allow tracking of friends’ statuses.

For the record, I don’t believe that posting the script on an external site constitutes a violation of the terms of service, although I accept that using it would be. Also, when you say “we can’t just let people automate”, I assume you really mean “we won’t just let people automate”. This is a shame, as it goes against the grain of the Internet, and reinforces the impression that you’re trying to lock people into your site.

All that said, I don’t particularly want to be spending my time fending off writs and takedown notices, so the script no longer appears on my site (see http://www.kerrybuckley.com/2007/07/14/updating-facebook-status-from-twitter/).

Kerry

[tags]facebook, twitter, ruby, mashup[/tags]

Categories
Rails

Correct use of the flash in Rails

[Update 9 May 2012]

This seems to work for testing flash.now in Rails 3:

it "puts an error in the flash" do
  post :create
  flash[:error].should == "Sorry, that's wrong."
end

it "does not persist the flash" do
  post :create
  flash.sweep
  flash[:error].should be_nil
end

[Update 20 April 2010]

I recently had problems testing flash.now, and Google kept leading me back to this post. Unfortunately it doesn’t seem to work with the current version of Rails (I’m using 2.3.5 at the moment).

This post from Pluit Solutions gives an alternative approach which seems to work. I haven’t tried it with Rails 3 though.


I don’t know whether this has caught anyone else out, or whether we just didn’t read the documentation properly (it’s covered briefly on p153 of AWDwR), but I thought I’d mention it anyway.

Anyone who’s written a Rails app will know that the ‘flash’ is used to store error and status messages, usually on form submissions. Model validation failure messages automatically get copied into the flash, but you often want to do it manually too.

flash[:notice] = "User Details updated."
redirect_to edit_user_path(@user)

The gotcha comes when you want to display a message and render a page, as opposed to redirecting – for example when errors are preventing a form from being submitted. This is how not to do it:

flash[:error] = "Password doesn't match confirmation." # WRONG!
render :action => 'change_password'

The problem is that the flash is stored for the next request. Because we’re no longer doing a redirect, that means the message may appear wherever the user goes next, not just on the page that we just rendered. To avoid this, use flash.now, which is only used for the current request:

flash.now[:error] = "Password doesn't match confirmation."
render :action => 'change_password'

The rule of thumb is to use flash if you’re redirecting, and flash.now if you’re rendering (either explicitly, or by dropping through to the default view for the action).

All very well, but whatever you put in flash.now is cleared out at the end of the request, so how do you test it? The answer (for RSpec, at least) lies in a comment on this RSpec feature request – basically just add the following to spec_helper.rb:

module ActionController
  module Flash
    class FlashHash 
      def initialize
        @hash = {}
        @now_hash = {}
      end
    
      def [](key)
        @hash[key]
      end
    
      def []=(key, obj)
        @hash[key] = obj
      end
    
      def discard(k = nil)
        initialize
      end
    
      def now
        @now_hash
      end
    
      def update(hash)
        @hash.update(hash)
      end
      
      def sweep
        # do nothing
      end
    end
  end
end

You can now do something like this:

describe "When a user tries to change his password with an invalid verification code" do
  ...

  it "should put an error message in the flash" do
    flash.now[:error].should == "Incorrect verification code or password."
  end
  
  it "should not persist the flash" do
    flash[:error].should be_nil
  end
end

[tags]Ruby,Rails,flash,RSpec[/tags]