Consistency in Features

Posted by Andrew Premdas Fri, 18 Nov 2011 16:31:00 GMT

Writing good features is difficult. One way to write better features is to read them critically. Two criteria useful for this are consistency and exclusivity. So a feature should be consistent and exclusive, what does this mean.

Consistency

For a feature to be consistent the following needs to apply

  1. The filename (including path) of the feature should be consistent with the title of the feature

    • inconsistent: features/purchasing.feature and Feature: Writing a blog
    • consistent: features/blog/new_article/ and Feature: New article
  2. The narrative should be consistent with the title

  3. A scenario title should be consistent with the narrative

  4. A scenarios steps should be consistent with the scenario title

n.b. In addition each thing lower down the list should be consistent with all the things above it.

Typical Inconsistencies

  1. Change of vocabulary: e.g. changing from talking about articles to talking about posts
  2. Introducing concepts outside the context. A classic in web applications is introducing different behaviour for different user types.
  3. Scenarios about separate content that appears on the same web page but has nothing to do with the feature.

Exclusivity

This is partially covered by being consistent. What it is saying is that a feature should only contain scenarios that are part of its narrative. It might also be saying that these scenarios belong here and nowhere else. In practice having no overlap between features is probably impossible. However lots of overlap is probably a good indicator that things could be better

Summary

Reading your features critically and applying rules of consistency and exclusivity is useful in creating simpler features that have greater focus. This should be done before, during and after implementation. In the long run its far more important that your features make sense than go green. If they make sense but are red you will have lots of context to help create your fix. If they make no sense then when they go red (and they will some day) then finding a fix will be much harder.

JRuby too slow for development 3

Posted by Andrew Premdas Mon, 26 Sep 2011 23:04:00 GMT

A controversial title which I hope I will be able to amend.

I'm new to JRuby, and the following may be due to my ignorance, which I am trying to address.

Two identical rails projects with almost identical Gemfile's. One running under JRuby 1.6.3 and the other on MRI 1.8.7p352. Running exactly the same specs. JRuby is 20x slower!!!

Git-Svn Workflow

Posted by Andrew Premdas Tue, 13 Sep 2011 20:29:00 GMT

The following is from a post by Jim Lindley in 2008. This seems to have from the net, so I'm reposting here (with some amendments) so I have a reference.

Composable Features

Posted by Andrew Premdas Mon, 27 Jun 2011 09:47:15 GMT

In Eloquent Ruby, Russ Olsen applies the composed method technique to a class. He says

"The composed method technique advocates dividing your class up into methods that have three characteristics. First, each method should do a single thing—focus on solving a single aspect of the problem ...

Second, each method needs to operate at a single conceptual level: Simply put, don’t mix high-level logic with the nitty-gritty details. A method that implements the business logic around, say, currency conversions, should not suddenly veer off into the details of how the various accounts are stored in a database.
Finally, each method needs to have a name that reflects its purpose.
"

When you apply this technique to classes you end up with classes with a relatively large number of methods each which is very simple. In applying this in detail I find that I create two sorts of methods.

  1. Methods that do something
  2. Methods that call other methods to do something

And in applying this technique I NEVER mix the two.

These techniques have been around for along time, as have a number of refactoring to get your code more composable. Use them and you'll never write another 20 line method ever again - personally anything over 5 lines sends of my alarm bells.

Anyhow if this technique is good for classes, might it also be good for features? And if it is how do we apply it?

A clue lies in how composed method technique helps eliminate proceduaral code. Perhaps we can make our features less procedural

    Feature: Title
      In order to encourage return visits
      As a site owner
      I want to support user accounts

    Scenario: login


    Procedural |                                  |  How   |
    -----------|----------------------------------|--------|
       ↓       |  When I go to the home page      |   ↓    | 
       ↓       |  And I fill in login with 'me'   |   ↓    | 
       ↓       |  And I fill in my password       |   ↓    | 
       ↓       |  And I press submit              |   ↓    | 
       ↓       |  Then I should be logged in      |   ↓    | 
       ↓       |                                  |   ↓    |
       ↓       |  When I go to the home page      |   ↓    | 
       ↓       |  And I login                     |   ↓    | 
       ↓       |  Then I should be logged in      |   ↓    | 
       ↓       |                                  |   ↓    |
       ↓       |  When I login                    |   ↓    | 
       ↓       |  Then I should be logged in      |   ↓    | 
    -----------|----------------------------------|--------|
    Declarative|                                  |  Why   |
    -----------|----------------------------------|--------|

Here we see a simple feature being refactored down to its bare minimum. The final feature format may make you uncomfortable

 When I XXXX
 Then I should be XXXX

seems to simplistic to be valuable. However in practice finding a good XXXX is really useful, and expressing basic functionality in this way is a great starting point for further exploration.

For example we can start dealing with failure very easily

When I login badly

instead of putting in fake credentials into a table.

So what do we get when we apply this sort of technique to a large set of features?

  1. A very succinct specification of what the application should do and why it should do it.
  2. No indication of how the application should do something.
  3. Features that are technically very easy to turn into step definitions
  4. Features that are very readable
  5. Features that have just the right amount of information

This last point is contentious. I know many people feel that features need to have more information in them. In particular the idea of features needing to have descriptive examples so you can explore how to do things is a strong argument. However I think this exploration and description is best done by implementation, review and iteration. If you iterate very quickly you don't need to explore the how up front, you can explore how things are done as you go along.

Why Would You Be Uncomfortable with This

Agile in general is not comfortable, and working in this way builds on that. This discomfort shows itself as

  1. the need to plan what will happen, rather than reacting to what is happening.

  2. the need to specify how things will be done, rather than provide feedback on how things are being done

  3. the need to micro manage rather than delegate responsibility

  4. the inability to trust

Composable Features and Tables

Posted by Andrew Premdas Mon, 27 Jun 2011 09:09:31 GMT

Recently I've been commenting on the this blog article. I think it would be better to gather my thoughts here.

ergonomics, guitar arpeggios, mac keyboards and mice

Posted by Andrew Premdas Wed, 13 Apr 2011 04:46:42 GMT

For the longest time I've been plagued by a chronic inability to play arpeggios on my guitar using my index finger. Playing a simple pim has at times become almost impossible, yet pma is fine and precise. Similarly playing scales with 'im' alternation has become very difficult, my speed being less than half that when playing with ma. Things have got so bad that I've resorted to hybrid picking, that is holding a plectrum between my thumb and index finger and using the other three fingers when playing fingerstyle pieces.

The Evils of Cut and Paste

Posted by Andrew Premdas Thu, 24 Feb 2011 08:23:08 GMT

Its a given in programming that bad habits are hard to get rid off. Its also a given that when you try and go fast, and when you feel pressure bad habits re-surface.

Cut and paste programming may be the worst habit of all. Its so enticing, easy to do and so productive! At least that's how it appears, but really its a cancer, destroying the joy of programming and at the same time destroying your code.

Such strong words, can they be justified? Well lets have a closer look at cut and paste and see what it does

Array.inject

Posted by Andrew Premdas Sun, 23 Jan 2011 14:23:43 GMT

Having had a lot of fun last week doing Uncle Bob's prime factors kata, I've been doing the Codebreaker example from the RSpec book this week. In section 9.2 the number_match_count method is refactored to be

def number_match_count 
  total_match_count - exact_match_count
end

And the problem of implementing total_match_count is discussed. The book starts with

def total_match_count 
  count = 0 
  secret = @secret.split('') 
  @guess.split('').map do |n|
    if secret.include?(n) 
      secret.delete_at(secret.index(n)) 
      count += 1
    end 
  end
  count
end

I didn't like this so in a separate branch I came up with

 def total_match_count
   total_match_count = 0
   secret = @secret.clone # need a copy as we will slice destructively  
   @guess.each_char do |char|
     pos = secret.index(char)        
     secret.slice!(pos) and total_match_count +=1 if pos 
   end
   total_match_count
 end

Which is OK, but fairly similar.

What the RSpec book is leading upto though is

def total_match_count 
  secret = @secret.split('') 
  @guess.split('').inject(0) do |count, n|
    count + (delete_first(secret, n) ? 1 : 0)
  end 
end

def 
  delete_first(code, n) code.delete_at(code.index(n)) if code.index(n)
end

This uses Array.inject, something I have always avoided. This is the second time the book has focused on Array.inject, and I started thinking why the fascination with inject. What is it that Ruby programmers like about it that I'm missing.

Some googling produced

  1. Jay Fields loves inject

  2. This thread, of which the best bits are:

    -

    How I remember:  Inject takes a binary operation (e.g. +) and injects it 
    between each element of a list.
    
    
       [1,2,3].inject { |a,b| a+b }  => 1+2+3
    
    
    -- Jim Weirich
    

    -

    ... there is a fundamental difference between the inject and 
    each versions.  The "each" verison is procedural.  It defines state (the 
    value of b) and how that state changes in each iteration (b += a).
    
    
    The "inject" version is functional.  There are no extra state variables 
    in our code that need initialization.  And the expression itself is the 
    value, rather than having a side effect on a local variable.
    
    
    Not that one way is better than the other, just noting differences.
    
    
    -- Jim Weirich
    

    -

    So, in math-speak, I think one could say:
    
    
    inject applies a block pairwise as an n-ary operation over an
    Enumerable, with an optional initial value.
    
    
    -- A LeDonne
    

Perhaps Array.inject is worth investigating further as a step towards doing more functional programming.

Blogging with Vim

Posted by Andrew Premdas Mon, 03 Jan 2011 16:12:17 GMT

In my attempts to become more proficient with VIM I thought I would try and push some standard editing tasks in its direction. My first choice was blog posting. For this to work I need VIM to:

  1. Understand that my blog posts are in markdown
  2. Get and retrieve posts from typo like the textmate blogging bundle does.

As usual with anything VIM things are not easy. Much of this is down to my ignorance, but the steep learning curve VIM never ceases to amaze me with its incline :)

After much googling I came across a vimblog.vim, and was able to get and retrieve posts ... SORT OF

However post retrieval doesn't quite work (partly my fault for using Typo and not Wordpress!) as not all the post is returned when I use a "Continue reading...".

So know I have to learn how to debug vim scripts so I can examine the XML object returned and see if either

  1. Vimblog is making the wrong call and getting only the article summary rather than the full article
  2. Vimblog is not extracting the correct field from the XML object
  3. Something else is going wrong

I guess if VIM really was the editor for me, I would just hack a solution to this. Perhaps I will, but I feel that I've got better things to do than spending tens of hours learning how to script VIM.

Using Vim

Posted by Andrew Premdas Fri, 24 Dec 2010 09:13:45 GMT

Currently I use textmate as my main editor, but I find myself often using Vim as a secondary editor for small tasks run from the command prompt. I'm thinking about extending my use of VIM for the following reasons

  1. Its available on all the VM's that I have to use
  2. I really like modal editing

However textmate still has a number of very attractive features that I will want VIM to emulate including:

  1. Excellent markdown support
  2. Good cucumber and rspec support
  3. OK RVM support
  4. ctrl-T find file support

Older posts: 1 2 3 ... 11