Agile Testing with Lisa Crispin – Part 1

This past Wednesday, Apr-20-2011, I attended the DFW Scrum meetup with guest Lisa Crispin, @lisacrispin, presenting over Skype, and I managed to take a wonderful 7 pages of notes in my composition book on her presentation. Because of this I will be breaking this up into a number of posts to help make it more digestible. I hope I didn’t butcher her talk up too much as I was busy trying to keep up with all of the gems she was throwing out to us. Apologies to Lisa if I did.

The big thing she started with was: before a team tries to go off and make any decisions, or do anything, they need to answer the question: “What does a commitment to quality mean?” Once answered, only then can they procede to improve the quality of their product.

On Reducing Show-Stoppers

The steps Lisa’s team went about reducing the number of show-stoppers they had in their product.

  • 1st they setup the basics: Continuous Integration and a dedicated test environment.
  • Once they had those in place, they setup a police light for show-stoppers. And anytime someone would report a show-stopper, that person then had to turn on the light. This had a two fold effect; it made the business person look silly if it was really a trivial bug, and it got annoying for the team if that light was constantly on.
  • Development started TDDing their code. She made a quick side note that TDD is hard to learn, and really, any test automation is hard to learn. She pointed out that it took the developers 8 months to get over the hump of TDD.
  • In the meantime, they wrote manual test scripts over the critical parts of the application. It was painful, and a great motivation for automating tests.
  • Got UI based automated tests running.
  • Worked to get functional automated tests instead of UI testing. Lisa mentioned that her team used Fitnesse.
  • They started with a happy path case, after they had that going they woud then add tests around the more boundary and error condition cases.
  • She noted that it took lots of baby steps over 8 years with a commitment to testing.

Testing is Not a Phase

The goal is a short feedback loop, as it is easier to recall the code an hour later as opposed to a month or two later. She noted that testers may be against this at first since it means testing the same thing multiple times, but that is important to shortening the feedback loop and improving the quality. I would also personally venture that it would help emphasize the importance of getting tests automated against a baseline set of expected functionality.

Lisa advised against calling a story done until all of the exploratory testing has been done.

She then pointed out some things to watch out for when planning. Watch out for overcommitting, since it usually doesn’t take into account the testing activities and anything they uncover. Also watch out for testing estimates that are not inline with development effort/estimate. Giving the example that if the testing effort is 2X the development effort, that may mean development might be missing something.

Continued…

I will be posting part two soon as this was only two-and-a-half pages of the seven pages of notes.

Software Development Podcasts

As I have about a thirty minute commute each direction, so last summer after I got my iPhone, I started listening to podcasts on my way to and from work. So here is the list of podcasts that I have been listening to throughout the last 8 months or so. I am always looking for good technical related podcasts to fill the commute time, so if anybody has any other recommendations, throw them in the comments and let me know.

.NET Podcasts

Ruby Podcasts

  • Teach Me to Code – Combination of guest interviews and personal musings.
  • coderpath – Infrequent posting schedule, now that one of the co-hosts now hosts the Pragmatic Podcasts.
  • Rubiverse Podcast – Hasn’t been updated in a while, but had some interesting guests
  • RailsCoach Podcast – Same host as the Teach Me to Code podcast above.

Platform independent

General

TDD: Clicker Training for Developers?

I started thinking about some of the bigger names in the developer community and how polarizing they can be due to their hard line positions on topics.  One of the topics that came to mind was Test Driven Development, and how the advocates of it almost always have a strict stance on the correct ways to approach it.  Outside-in or inside-out.  Only one assertion per test or assert one logical concept.  Mocks vs stubs. State vs behavior. TDD or BDD, or is there is really even a difference.

My wife pet-sits, and as she is cooking, so she likes to watch shows which cover training pets, similiar to how one might listen to podcasts as they drive to work.  I will occasionally over-hear, or catch parts of these shows myself, usually while helping her in the kitchen. I also recently read Switch: How to Change When Change is Hard, by Chip and Dan Heath which has a section discussing the importance of reinforcing positive behavior when trying to encourage change and establish habits.  Thinking about the hard-liners and TDD, I realized Kent Beck created the perfect “training clicker” for developers.  Whether this was intentional or not at the time will be something I leave for him to answer.

To train by positive reinforcement, one has to capture the desired behavior and immediately reward it.  When one test drives their code they are encouraged to run their test after each change to see if their change works.  As unit tests are supposed to be fast, this gives the user immediate feedback to know if what they did worked or did not.

The majority of the test runners use either one of two words depending on the result of the test: success or failure.  These two words are very emotionally charged.  Combine this with the fact that they are usually printed in all caps and followed by a number of exclamation points results in output like:
SUCCESS!!!
or
FAILURE!!!

Can’t you just see the emotions getting charged.

Add on to this a graphical user interface for the test runner, or even add ons which change the console text color depending on the end state of the test runs, which use the colors green and red for successes and failures respectively, and you get even more emotional resonance.  You have now gone from the above results to something along the lines of
SUCCESS!!!
or
FAILURE!!!

How is that for evoking an emotional response? I believe I have even heard Kent Beck talking about the thrill he sees in seeing the status bar turn green.

Also, the proponents of TDD encourage small units of work.  The reason being, when you work in minimal units of change you know pretty much exactly what caused the test to fail.  There ends up being a hidden effect to this though.  When you work in small units between test runs, that behavior is now getting reinforced even more frequently, and engraining that behavior more deeply.  Do this enough and that behavior will eventually turn into a habit. And our self-serving egos love to rationalize why our habits are the right thing to be doing, lest we allow ourselves to realize we might be acting wrongly.

And I do not think this just applies to those that are strong proponents for TDD.  Do we ever consider that someone who is a strong opponent may have been negatively reinforced by TDD?  Might they have tried on their own with no guidance and gotten frequent feedback of failures?  Maybe they tried at the wrong level of abstraction, or on a codebase that was not designed with testability in mind. Maybe the test runner just kept giving them negative reinforcement on what they were doing until they decided that TDD is a waste of time.

I am putting this idea out there not to cast judgement against TDD, as it is a practice that I believe has a large amount of value to it, and would love to get good at, but as a something to think about.  Maybe this will help the each side see why the other side might feel they way they do about TDD.

I would love to know your thoughts on this.

Automatically disposing IDisposable?

Reading up on Ruby, I was intrigued by the way file operations are handled. Primarily the fact that Ruby allows you to pass a block as a parameter to Open method of a File object. When you do this it opens the file for you, passes the file to the block, and then closes the file when the block is done executing, relieving you of having to manage checking to make sure the file is open, as well as making sure that the file is closed when your are done using it.

Below is the example that is shown in Programming Ruby by Dave Thomas.

File.open("archive.log", "a") do |f|
  f.each_line { |line| puts "Got #{line.dump}" }
end

This ability seemed similar to how the FileStream returned from File.Open in C# implements IDisposable, and by putting that FileStream object in a using block, the .NET Framework will call disposable when that block is exited. But what struck me, was that every time you get a FileStream object, it needs to be put in a using block. I have stubbed out an example of this against a call to the method ExecuteReader on the SQLCommand class.

public class Test
{
	public void RunQuery()
	{
		string queryString = "testQueryString";
		SqlConnection connection = new SqlConnection("myConnectionString");
		SqlCommand command = new SqlCommand(queryString, connection);
		DbDataReader reader = command.ExecuteReader();
		using (SqlDataReader reader = command.ExecuteReader())
		{
			while (reader.Read())
			{
				Console.WriteLine(String.Format("{0}", reader[0]));
			}
		}
	}
}

While I do strongly agree the using block greatly improved the way we would have had to deal with closing the reader previously in .NET, after seeing the way Ruby deals with this. The reason I think Ruby handles this better is that for a number of scenarios the responsibility of disposing the object should be hidden from the consumer if possible. So I suggest that in the future, when designing your method calls the goal should be to make the disposing of the IDisposable automatic, at least from the point of view from the consumer. This helps reduce boiler plate code that has to be duplicated every where the method is used. The other reason that this is helpful, is that it prevents the consumer from forgetting to dispose of the object when they are done with it. It may also be helpful to create extension methods for those API calls you have no control over to give you this functionality as well, as shown below.

public static class FileExtensions
{
	public static void ExecuteReader(this SqlCommand command, Action block)
	{
		using (SqlDataReader reader = command.ExecuteReader())
		{
			block(reader);
		}
	}
}

public class Test
{
	public void RunQuery()
	{
		string queryString = "testQueryString";
		SqlConnection connection = new SqlConnection("myConnectionString");
		SqlCommand command = new SqlCommand(queryString, connection);
		command.ExecuteReader(reader =>
		{
			while (reader.Read())
			{
				Console.WriteLine(String.Format("{0}", reader[0]));
			}
		});
	}
}

Based on this we can even enhance this functionality and encapsulate the DbDataReader completely and pass a different type of object to the block if we decide that we have a better abstraction to work against.

Note: I almost decided not to post this, as I was at the Dallas Day of Dot Net this weekend and pinged Derick Bailey about this for his perspective as a developer who used both Ruby and .Net, and he mentioned his blog post How Ruby Taught Me To DRY Up My Code With Lambda Blocks on the topic.  So go read his entry as well, and try this out for yourself and let me know how this works for you.

Books I’ve Recently Read

This is my quick entry for helping to track the books that I have recently read, are currently reading, and are in my queue to read soon.

First up is the books I have recently read since around Christmas.   My Christmas list this past year was simply a listing of books that were on my To Read list.  Having gotten those and finished reading those that were in progress, I determined that I should make a note of what books I have read since then.  They are as follows, in no particular order.

  • Extreme Programming Explained – Kent Beck
  • The Passionate Programmer – Chad Fowler
  • Apprenticeship Patterns – Dave Hoover and Ade Oshineye
  • Continuous Deployment – Jez Humble and David Farley
  • A Mind of its Own: How Your Brain Distorts and Deceives – Cordelia Fine
  • Javascript Patterns – Stoyan Stefanov
  • The Book of Lies – Brad Meltzer (Fiction, for the sake of a mental break)
  • Web Design for Developers – Brian P. Hogan

To go with the list of books that I have recently read, here are the books that I am currently reading.

  • Pragmatic Thinking and Learning – Andy Hunt
  • Programming Ruby 1.9 – Dave Thomas

These are the books that are in my queue to read soon.  These have been through other developer’s reviews or recommendations, recommendations from Amazon or Barnes and Nobel based of books I have read, or books I have just browsed through or stumbled upon and which looked interesting.

  • The Humane Interface – Jef Raskin (Have from Christmas)
  • Don’t Make Me Think – Steve Krug (Have from Christmas)
  • Release It! – Michael T. Nygard (Have from Christmas)
  • Domain-Specific Languages – Martin Fowler (Have from Christmas)
  • Object-Oriented Software Construction – Bertrand Meyer
  • Software Craftsmanship: The New Imperative – Pete McBreen
  • The Pragmatic Programmer: From Journeyman to Master – Andy Hunt and Dave Thomas
  • Designing Object Systems: Object-Oriented Modelling with Syntropy – by Steve Cook and John  Daniels
  • The The Annotated Turing – Charles Petzold
  • Switch – Chip Heath and Dan Heath
  • Why We Make Mistakes – Joseph T. Hallinan
  • Javascript: The Good Parts – Douglas Crockford

Any other suggestions are open and welcome.

Amazon.com recommends….

Yesterday morning I get an email from Amazon.com with the following subject:

Amazon.com recommends "Clean Code: A Handbook of Agile Software Craftsmanship" and more

containing the latest product recommendations from Amazon for me.  After I skim it, I realize I have to go back and give it a deeper look.  After that second pass, I can’t help but laugh at their book recommendations for me:

  • Clean Code: A Handbook of Agile Software Craftsmanship – Robert C. Martin (Uncle Bob)
  • Refactoring: Improving the Design of Existing Code – Martin Fowler
  • Working Effectively with Legacy Code – Martin Feathers
  • Growing Object-Oriented Software, Guided by Tests – Steve Freeman and Nat Pryce
  • Patterns of Enterprise Application Architecture – Martin Fowler

Now looking at that book list, you may be wondering what prompted me to laugh at those recommendations, well I own and have read them all.  Time to go update Amazon.com as marking that I own all of them, and see what new recommendations it has for me.

Welcome

Hello and welcome. I have recently realized that I should start chronicling my journey to becoming a better software developer and honing my skills and my craft. Sometime around the first quarter of 2009, I began to realize that my career growth had started to slow, and that if I was not vigilant, my career would stagnate.

Since that time, I have been reading software development books as well as blogs, and trying to understand, absorb and apply that knowledge to writing better code, making better software, and making the software better. I was also fortunate to have come across a user group in the area that somehow manages to get software development luminaries, such as Martin Fowler, Dave Thomas (PragDave), Kent Beck, and others, in the software development field to come out and speak to them for free, and have since started to attend those. I have also just come back from the Software Craftsmanship North America 2010 conference and CodeRetreat, and as a result have plenty of ideas and half-formed thoughts in my head which need to be captured.

As such, is finally time to stop wondering if I have anything worth saying, and time to just start journaling, even if no-one else will ever come across this blog; for even just trying to record those thoughts will clarify them. With that, here is looking forward to being able to document, and reflect, on my journey of continuous improvement as a software developer.