markhneedham/blog huggingface dataset:
RSpec: Testing Rails routes
Date: 2010-10-13 18:25:32

Something which I keep forgetting is how to write controller tests where I want to check whether an action correctly redirected to another action.

With most of the routes in our application we've created a 'resourceful route' where each action maps to a CRUD operation in the database.

We can do that with this type of code in routes.rb:

[source,ruby]
----

ActionController::Routing::Routes.draw do |map|
	map.resources :foos
end
----

http://guides.rubyonrails.org/routing.html#paths-and-urls[Several helper methods based on named rotes get created and included in our controllers] when we do this and we have access to those inside our specs.

We can see the named routes by executing the following command from the terminal:

[source,text]
----

mneedham@markneedham.local ~/SandBox/rails_test$ rake routes CONTROLLER=foos
(in /Users/mneedham/SandBox)
    foos GET    /foos(.:format)          {:action=>"index", :controller=>"foos"}
         POST   /foos(.:format)          {:action=>"create", :controller=>"foos"}
 new_foo GET    /foos/new(.:format)      {:action=>"new", :controller=>"foos"}
edit_foo GET    /foos/:id/edit(.:format) {:action=>"edit", :controller=>"foos"}
     foo GET    /foos/:id(.:format)      {:action=>"show", :controller=>"foos"}
         PUT    /foos/:id(.:format)      {:action=>"update", :controller=>"foos"}
         DELETE /foos/:id(.:format)      {:action=>"destroy", :controller=>"foos"}
----

The following helper methods would be created for this resource as per the documentation in resources.rb:

____
# Named Route Helpers # ============ ===================================================== # foos foos_url, hash_for_foos_url, # foos_path, hash_for_foos_path # # foo foo_url(id), hash_for_foo_url(id), # foo_path(id), hash_for_foo_path(id) # # new_foo new_foo_url, hash_for_new_foo_url, # new_foo_path, hash_for_new_foo_path # # edit_foo edit_foo_url(id), hash_for_edit_foo_url(id), # edit_foo_path(id), hash_for_edit_foo_path(id)
____

Keeping this in mind means that if we do something like this inside our 'create' action:

[source,ruby]
----

class FoosController < ApplicationController
   def create
      ...
      redirect_to :action => :index
   end
end
----

We'd be able to test that redirection with a spec along the following lines:

[source,ruby]
----

describe "POST create" do
   it "should redirect back to the index page" do
      post :create, :foo => { :bar => "value" }

      response.should redirect_to foos_path
   end
end
----

We can also use any of those other helper methods inside our tests which seems obvious looking at it now but wasn't for me until a colleague pointed it out.

It is pretty cool to be able to write specs like this and they seem much more readable than the equivalents you'd be able to test around ASP.NET MVC code in C#.
Agile: Story Wall - A couple of learnings
Date: 2010-10-22 17:13:34

I wrote earlier in the week about http://www.markhneedham.com/blog/2010/10/20/distributed-agile-physical-story-wall-still-useful/[the benefits of having a physical story wall on a distributed team] and in the process of getting one in place on the project we learnt a few things that I'd previously taken for granted.

== All the work in one place

We initially started off by having stories on one part of the wall, bugs on another part and any technical tasks stored in Mingle somewhere.

The problem with this approach was that it wasn't easy to glance at the wall from wherever you were sitting and be able to quickly gauge the state of the project at any given time.

We needed to look at one side of the wall to check what stories were being worked on and then check the other side of the wall to see who was working on bugs.

A couple of times we'd forget that the bugs were being tracked on the other side of the wall and two pairs would look at the same bug before realising that it had already been picked up.

We're now in a place where we have stories, bugs to be fixed in this iteration and technical tasks all in the same lane on the wall.

Doing this means that *everyone can quickly gain visibility into what can be worked* on and then they can easily work out what the next thing to pick up is.

== Proactiveness

I hadn't realised the value of having upcoming stories visible on the wall in the 'ready for dev' column until I saw it not being done.

The proactivity of the team seemed much less than in previous teams I'd worked on because people were unaware what they could pick up once they'd finished working on a story.

As a result of this there tended to be a lot of time where developers were waiting around looking for something to do.

A *bottleneck had been created* where they would need to wait for an analyst to tell them what could be picked up.

Now a pair can what the next highest priority thing for them and pick it up or at least work out roughly what they need to do before running through it with an analyst.
Communication: Logging levels
Date: 2010-10-25 18:49:23

I think one of the most important skills to perfect when communicating with other people is to understand the level of detail that we need to be speaking at, something my colleague link:[Ashwin Raghav] refers to as our logging level.

We log various things in our code at varying logging levels ranging from 'error' through 'debug' to 'warn', and each of these is useful for understanding what our code is doing.

However, we might typically only report problems at the 'error' level unless something goes wrong and we want to try and understand in greater details what's going on.

The same thing applies at a conversational level and I've noticed that the tendency is to zoom into the detail very quickly rather than staying at a high level.

== In a group situation

While speaking at a detailed level is appropriate in some situations it can easily isolate people in a group situation if only one or two people are able to take part in the conversation at this logging level.

Given that it is possible to end up at the wrong logging level by mistake it then becomes important to watch the body language and reaction of other people in the group.

If they seem to be zoning out, losing interest or if the conversation excludes them then it's fairly likely the logging level is too verbose and it would make more sense to take that conversation offline.

== In a one on one situation

A similar thing applies in a one on one conversation but the way it rears its head is slightly different

When talking about code the tendency can be to talk at the syntax level in order to explain something.

For example if we're talking about the merits of http://www.markhneedham.com/blog/2010/10/24/ruby-mocking-or-stubbing-methods-on-the-system-under-test/[mocking or stubbing out methods on the system under test] then the conversation has been set at a conceptual level and it wouldn't make sense to start talking about the way that RSpec actually makes it possible to do this.

It's also useful to work out the other person's level of understanding so that we know what logging level our explanations need to be at.

We'll typically get rapid feedback from the other person if we're not doing this.

For example when I first started working with Ashwin my explanations were too detailed and he quickly pointed that out. That allowed me to jump straight to a higher level from then on.

The logging level that we'll need to use will be different for each person and it does take a little bit of time to work out where exactly it needs to be.

I quite like Ashwin's metaphor and I've been keeping it in mind when watching conversations and when communicating myself to try and ensure that the right logging level is being kept to for various conversations.

It is surprisingly easy to drift away from the optimal logging level though!

'''

As a side note it seems much less frequent that the people I work with speak at a level of detail which isn't verbose enough and I can't really explain why that is!
Mikado-ish method for debugging
Date: 2010-07-04 01:20:45

I've http://www.markhneedham.com/blog/2010/02/23/coding-effect-sketches-and-the-mikado-method/[written previously about the Mikado method and how I've made use of it for identifying ways in which I could refactor code] but I think this approach is more generally applicable for any kind of code investigation.

Our application has a lot of calculations in it and we've been trying to refactor the code which wires all the calculators up to make use of a DSL which reveals the intention of the code more as well as making it easier to test.

Unfortunately after changing the code to use this approach one of the calculations was about by about £15.00 in one of our acceptance tests.

We didn't have the best logging around all the calculators so it wasn't immediately obvious where to start looking for the problem.

I decided to sketch out the ways the calculators interacted with each other and then follow the deepest path - which was Calculator D - Calculator G - Calculator H -  to see if there were any differences in the values being calculated when running the old and new versions of the code.

image::{{<siteurl>}}/uploads/2010/07/mikado.jpg[mikado.jpg,521]

Interestingly there was no problem in that bit of the code which then allowed me to rule out that whole part of the tree and then start looking at the other calculators to try and find the problem.

I'd previously been trying to work out what was going on just by reading through the code but found it incredibly difficult to remember where I'd already investigated so drawing the diagram really helped with that too.
Feedback, the environment and other people
Date: 2010-07-20 17:30:16

Something that I've noticed over the last few years is that when people give feedback to each other there is often an over emphasis on the individual and less attention paid to the environment in which they were working.

I covered this a bit in a blog post I wrote about a year ago titled 'http://www.markhneedham.com/blog/2009/08/13/challenging-projects-and-the-five-stages-of-grief/[Challenging projects and the Kubler Ross Grief Cycle]' which I converted into a presentation that I gave at XP2010 in June. In the presentation I spoke more about the way the environment can impact the way we behave.

One of the points I made was that *the environment has a very big impact on the way that people act*.

After one particular project that I worked on http://twitter.com/lindystephens[Lindy], who was running our performance review process, pointed out that everyone who had worked on that project had the exact same feedback and that it said way more about the environment that project was operating in than it did about the individuals.

image::{{<siteurl>}}/uploads/2010/07/Workplace_chart2.jpg[Workplace_chart2.jpg,250]

I'm not quite sure where we draw the line between what an individual can reasonably be said to have control over and what is difficult for them to influence because of the environment. Perhaps there doesn't need to be a line.

In http://www.amazon.com/Crucial-Confrontations-promises-violated-expectations/dp/0071446524/ref=sr_1_1?ie=UTF8&s=books&qid=1279646916&sr=8-1-spell[Crucial Confrontations] the authors talk about there being three sources of influence - self, others and things - or personal, social and structural as on the diagram on the right!

As I understand it the authors suggest that we start looking at the individual in terms of their own motivation and ability first and then work our way down through the others.

Although this model is intended for conversations where one person is confronting the other for not behaving how they expected in some way, it seems like a reasonable model to follow for general feedback as well.

As assumptions seem to drift into our perceptions of what other people are doing often in an unfavourable way the point of following the model is that it will help draw out these assumptions and help us to see exactly why someone acted the way they did.

A fairly common example is where a tech lead just give instructions to their team to do something without explaining why they want them to do that.

They assume that the team already know why - assuming that the team has the information, context and experience of making this type of decision that they do. The team assumes that the tech lead isn't telling them because he/she just wants them to follow orders.

Neither of these assumptions are particularly useful and it seems much more effective to *talk through something with the other person based only on what we've observed* so that we can see whether there is something for them to improve or if we need to try and improve the environment in some way.

Easier said than done.
Agile: Developer attendance at showcases
Date: 2010-07-27 07:31:59

On the majority of the projects that I've worked on at ThoughtWorks we've held a showcase at the end of each iteration to show our client what we've been working on and finished over the previous one or two weeks.

The format of these showcases has been fairly similar each time but the people who attended has tended to vary depending on the situation.

As part of the project being worked on at http://www.thoughtworks.com/thoughtworks-university[ThoughtWorks University] we've run a showcase at the end of each week which the whole team have been attending.

http://www.facebook.com/tobyclemson[Toby] pointed out that having everyone there didn't seem to be the best use of people's time since the majority of the developers in the room didn't actually have any input during the showcase.

I've often felt the same in that situation although we used a similar approach on a project I worked on last year and it seemed to be quite useful for addressing the human aspect of the project.

The client was able to meet all the people on the team and equally the developers were able to gain some insight into the types of conversations that the analysts were having with the client.

In that particular example we had around 10-15 developers so there was quite a big gathering but on the other projects where we've had the whole team at the showcase there's only been 3 or 4 of us.

On the last project I worked on we took it in turns to go to the showcase. I think it's quite useful to have at least one technical person in a showcase as they're able to give instant feedback on implementation details such as how difficult it will be to change the way a certain piece of functionality works.

A lot of the time we didn't have any input but it was interesting that quite often we'd come out of those showcases with more understanding of what the client was trying to achieve with a specific feature.

If we don't have all the developers in every showcase we do tend to have them all there for the first showcase at least as that tends to be the one where the most stakeholders will be present.

Overall though it's a call to make depending on the situation and the difficulty in judging the value of attending the showcase seems to come about because a lot of the benefits of attending are indirect whereas staying at our desk and coding has a direct benefit to the project.
A new found respect for acceptance tests
Date: 2010-07-11 17:08:39

On the project that I've been working on over the past few months one of the key benefits of the application was its ability to perform various calculations based on user input.

In order to check that these calculators are producing the correct outputs we created a series of acceptance tests that ran directly against one of the objects in the system.

We did this by defining the inputs and expected outputs for each scenario in an excel spreadsheet which we converted into a CSV file before reading that into an NUnit test.

It looked roughly like this:

image::{{<siteurl>}}/uploads/2010/07/acceptance-tests3.jpg[acceptance-tests.jpg,523]

We found that testing the calculations like this gave us a quicker feedback cycle than testing them from UI tests both in terms of the time taken to run the tests and the fact that we were able to narrow in on problematic areas of the code more quickly.

As I http://www.markhneedham.com/blog/2010/07/04/mikado-ish-method-for-debugging/[mentioned on a previous post] we've been trying to move the creation of the calculators away from the 'CalculatorProvider' and 'CalculatorFactory' so that they're all created in one place based on a DSL which describes the data required to initialise a calculator.

In order to introduce this DSL into the code base these acceptance tests acted as our safety net as we pulled out the existing code and replaced it with the new DSL.

image::{{<siteurl>}}/uploads/2010/07/acceptance-tests-part21.jpg[acceptance-tests-part2.jpg,538]

We had to completely rewrite the 'CalculationService' unit tests so those unit tests didn't provide us much protection while we made the changes I described above.

The acceptance tests, on the other hand, were invaluable and saved us from incorrectly changing the code even when we were certain we'd taken such small steps along the way that we couldn't possibly have made a mistake.

This is certainly an approach I'd use again in a similar situation although it could probably be improved my removing the step where we convert the data from the spreadsheet to CSV file.
The Internet Explorer 6 dilemma
Date: 2010-07-11 19:31:16

A couple of weeks ago Dermot and I showcased a piece of functionality that we'd been working on - notably http://www.markhneedham.com/blog/2010/06/30/jquery-dynamically-updating-a-drop-down-list/[hiding some options in a drop down list].

We showcased this piece of functionality to the rest of the team in Firefox and it all worked correctly.

Our business analyst, who was also acting as QA, then had a look at the story in Internet Explorer 6 and we promptly realised that the way we'd solved the problem didn't actually work in IE6.

In retrospect we should have showcased the story in IE6 in order to shorten the feedback cycle but if we take that logic even further than it's clear that we should be running our application in IE6 frequently as we're developing functionality.

It's a dilemma that we've faced on nearly every project I've worked on recently.

We know in the back of our minds that we need to make it work on Internet Explorer 6 but because of http://getfirebug.com/[Firebug] the speed of development is siginifcantly quicker if we use Firefox.

It's almost as if we're trading off the longer term safety we would have if we use IE6 all the time for the quick feedback cycles we get from the Firebug console/CSS editor when we're fiddling around with Javascript and CSS.

The way that we're working at the moment is to continue using Firefox for local development but trying to make sure that we test and showcase in IE6.

It's not a foolproof approach, as can be seen by the example I gave at the beginning of this post, so I'd be interested if anyone has any clever ideas for dealing with the situation where we have a requirement to make our application IE6 compatible.
TDD: Testing collections
Date: 2010-07-28 06:05:25

I've been watching http://www.pragprog.com/screencasts/v-kbtdd/test-driven-development[Kent Beck's TDD screencasts] and in the 3rd episode he reminded me of a mistake I used to make when I was first learning how to test drive code.

The mistake happens when testing collections and I would write a test which would pass even if the collection had nothing in it.

The code would look something like this:

[source,csharp]
----

[Test]
public void SomeTestOfACollection()
{
	var someObject = new Object();
	var aCollection = someObject.Collection;

	for(var anItem : aCollection)
	{
		Assert.That(anItem.Value, Is.EqualTo(...));
	}
}
----

If the collection returned by someObject is empty then the test will still pass because there is no assertion to deal with that situation coming up.

In Kent's example he is using an iterator rather than a collection so he creates a local 'count' variable which he increments inside the for loop and then writes an assertion outside the loop that the 'count' variable has a certain value.

In my example we can just check that the length of the collection is non zero before we iterate through it.

[source,csharp]
----

[Test]
public void SomeTestOfACollection()
{
	var someObject = new Object();
	var aCollection = someObject.Collection;

	Assert.That(aCollection.Count(), Is.GreaterThan(0));
	for(var anItem : aCollection)
	{
		Assert.That(anItem.Value, Is.EqualTo(...));
	}
}
----

It's a relatively simple problem to fix but it's certainly one that's caught me out before!
TDD: Call your shots
Date: 2010-07-28 07:39:03

One of the other neat ideas I was reminded of when watching http://www.pragprog.com/screencasts/v-kbtdd/test-driven-development[Kent Beck's TDD screencasts] is the value of '*calling your shots*' i.e. writing a test and then saying what's going to happen when you run that test.

It reminds me of an exercise we used to do in tennis training when I was younger.

The coach would feed the ball to you and just before you hit it you had to say exactly where on the court you were going to place it - cross court/down the line and short/deep.

The point of this exercise is that it's relatively easy to just hit the ball over the net but to have control over exactly where the ball's going to go is way more powerful albeit more difficult.

This applies to TDD as well - it's easy to write a failing test but much more useful to write a failing test which fails in exactly the way that we expect it to.

I've http://www.markhneedham.com/blog/2009/05/23/its-not-about-equal-keyboard-time/[written previously about the value of commentating when pair programming] and calling your shots is a really easy way of keeping the conversation flowing in a pair.

I like to ask not only how a test is going to fail but why it's going to fail in that way. I think it's a pretty good way of making sure that you as a pair understand exactly what you're doing. It also *slows the pace just enough that you're not coding without thinking* about what you're doing.

I quite like Bryan Liles' take on this which he described in a talk at acts_as_conference 2009. Bryan suggests that we http://aac2009.confreaks.com/07-feb-2009-13-30-tatft-the-laymans-guide-bryan-liles.html[first write a test and then either make it green or change the error message that you're getting].

We should know whether or not the test is going to go green or the error message is going to change before we run the test and the idea is that we want to either get the test to pass in one go or at least get a step closer to a passing test.
Performance: Do it less or find another way
Date: 2010-07-10 22:49:52

One thing that we tried to avoid on the project that I've been working on is making use of http://msdn.microsoft.com/en-us/library/bb397951.aspx[C# expressions trees] in production code.

We found that the areas of the code where we compiled these expressions trees frequently showed up as being the least performant areas of the code base when run through a performance profiler.

In a discussion about the ways to improve the performance of an application http://twitter.com/christianralph[Christian] pointed out that once we've identified the area for improvement there are two ways to do this:

* Do it less
* Find another way to do it

We were able to find another way to achieve what we wanted without using them and we favoured this approach because it was much easier to do,

An alternative would have been to cache the compilation of the expression so that it wouldn't happen every single time a request passed through that code path.

A lot of the time it seems like it's actually possible to just do something less frequently rather than changing our approach...

For example:

* Caching a HTTP response so that not every request has to go all the way to the server.
* Grouping together database inserts into a bulk query rather than executing each one individually.

... and most of the time this would probably be a simpler way to solve our problem.

I quite like this heuristic for looking at performance problems but I haven't done a lot of work in this area so I'd be interested in hearing other approaches as well.