TITLE: Changing Default Actions AUTHOR: Eugene Wallingford DATE: June 30, 2010 5:17 PM DESC: ----- BODY: Learning to do test-driven design requires a big shift in mindset for many developers. I was impressed with how well the students in my recent agile development course took to the idea of writing tests first. Even the most skeptical students seemed willing to go along with the group in using tests to specify the code they needed to write. Other agile practices, such as pair programming and communal development, helped to support all of the students, willing or skeptical, to move in the right direction. My friend Steve Berczuk suggests another way to support the change in habit:
Rather than frame the testing challenge with the default being the old way of not testing:
Write a test when it makes sense.
Change your perspective to the default being to test:
Write a test unless you can explain why you did not.
I like how Steve shifts the focus onto default actions. The actions we take by default arise when our mental habits come into contact with the world. Some of my students prefer to talk about their "instincts", but the principle is the same: When things get hard -- or easy -- what will you do? We can change our habits. We can develop our instincts. Yes, it is hard to do. However we make the change, we have to change the individual actions we take at each moment of choice. The way to turn running into a habit is to run. When I have a run planned for a morning but wake up feeling rotten, my default has to be to run. I need to have a really good reason not to run, a reason I am willing to tell my family and running friends without shame. This is another example of using positive peer pressure to help myself act in a desired way. There are good reasons not to run some days. However, when I am creating a new habit, I have to place the burden of proof on the old habit: Why not? When I follow this discipline, there is a risk of overusing the technique I am learning. If my default answer is to just keep running, I will run on some mornings when I really should take a break. I may find out during the run, in which case I need to listen to my body immediately and adapt. Or I may find out later, when I see that my times from the workout were substandard or when I am sore or fatigued beyond reason later in the day. Whenever I recognize the problem, I can examine the outcome and try to learn the reason why I should not have run. This will allow me to make a sound exception to my default in the future. The same risk comes when we try this technique while learning test-driven design or any new programming practice. I may write a test I don't have to write. I may write code that is too simple. I may need it after all. This risk is an integral part of learning. I must learn when not to do something just as much as I need to learn when to do it. The risk of running when I ought not run carries a greater potential cost than writing a test when I need not write, because physical injury may result. The only real cost of writing an unnecessary test or taking too small a step forward in my code is the time lost. As a runner, the way I minimize the risk of injury or other significant cost I have to listen to my body. As a programmer, I still also have to listen to my code, and keep it clean through refactoring. Done steadily and faithfully, the side effect is a new habit, better instincts. The key to Steve's suggestion is that changing practice isn't just about habit and instinct, as important as they are. It's also about attitude. There are times when my surface attitude is compliant with a picking up a new practice, but my ingrained attitude gets in the way. My conscious mind may say, "I want to learn how to do TDD", while subconsciously I react as if "I don't need to write a test here". Taking the initiative to change my default action consciously helps me to bridge the gap. I think that's why I find Steve's idea so helpful. -----