I am a technologist who became test infected in 2004 and I have been trying to spread it ever since. This blog was formally titled "XP in Anger"
Wednesday, November 26, 2008
Courtesy of Michelle
An SQL query goes into a bar, walks up to two tables and says, "Can I join you?"
Monday, November 24, 2008
REST Track at QCon
I really wanted to go to this and after reading Jim Webber's posts on the REST track, I really regret having stayed home!
Sunday, November 23, 2008
Rails config for concordion
I am working with rcor, a ruby port of concordion, and I have run into a little setback working with Rails. RCor searches the $LOAD_PATH to find the html specifications, so I decided to add it to the standard config/test.rb. Here was the output:
Really? Well it doesn't work. I had to add the following line to my config/environment.rb:
WhyTF do I have to do this? Rather than STFW or RTFM I am blogging about it. Talk about open-closed jeez!!!
new-host:rcor-spike ariel$ rake test
(in /Users/ariel/Documents/dev/bookstore)
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -Ilib:test "/Users/ariel/.gem/ruby/1.8/gems/rake-0.8.3/lib/rake/rake_test_loader.rb" "test/unit/book_test.rb" "test/unit/hello_world_test.rb"
Loaded suite /Users/ariel/.gem/ruby/1.8/gems/rake-0.8.3/lib/rake/rake_test_loader
Started
...E
Finished in 0.073126 seconds.
1) Error:
test_spec(HelloWorldTest):
RuntimeError: Could not find hello_world.html on the system load path!
/Users/ariel/.gem/ruby/1.8/gems/rcor-0.7.0/lib/concordion_reader.rb:15:in `find_on_load_path'
/Users/ariel/.gem/ruby/1.8/gems/rcor-0.7.0/lib/concordion_reader.rb:4:in `read'
/Users/ariel/.gem/ruby/1.8/gems/rcor-0.7.0/lib/concordion_parser.rb:22:in `parse'
/Users/ariel/.gem/ruby/1.8/gems/rcor-0.7.0/lib/concordion_test_case.rb:69:in `parse_spec'
/Users/ariel/.gem/ruby/1.8/gems/rcor-0.7.0/lib/concordion_test_case.rb:22:in `test_spec'
/Users/ariel/.gem/ruby/1.8/gems/activesupport-2.1.1/lib/active_support/testing/setup_and_teardown.rb:67:in `__send__'
/Users/ariel/.gem/ruby/1.8/gems/activesupport-2.1.1/lib/active_support/testing/setup_and_teardown.rb:67:in `run'
4 tests, 3 assertions, 0 failures, 1 errors
Really? Well it doesn't work. I had to add the following line to my config/environment.rb:
config.load_paths += %W( #{RAILS_ROOT}/test/acceptance ) if ENV['RAILS_ENV'] == 'test'
WhyTF do I have to do this? Rather than STFW or RTFM I am blogging about it. Talk about open-closed jeez!!!
Saturday, November 22, 2008
Non Functional Requirements as stories
Mike Cohn has this to say:
These are requirements that are not about specific functionality (”As a user of a word processor, I want to insert a table into my document.”), but are rather about an attribute or characteristic of the system... “If it’s non-functional, why do I care about it?”... Each constraint we put on a system narrows the design choices a bit; calling these “constraints” rather than “non-functional requirements” helps us remember this... Trying to put a constraint into this template is a good exercise as it helps make sure you understand who wants what and why.This post resonates with me because I firmly believe that any feature in your application must fulfill the needs of its users not its engineers. Doing so will encourage simplicity in your application development that way you avoid useless stories like, As an architect, I want for the system to be integrated using an ESB (so that my resume looks good and I can frustrate the developers who are forced to use it).
Tuesday, November 18, 2008
Rails periodically_call_remote issue
Here is an interesting problem that I ran into today. A few guys where working on a feature that used a progress bar to give a user feedback on the status of a background task. In order to do this, they used the Rails prototype helper periodically_call_remote method however they noticed that multiple requests were being fired after an interval had passed. I wasn't sure what was happening so I started to read the source code and as of the time of the writing of this post periodically_call_remote creates a PeriodicExecuter but does not ever stop it. According to the Prototype website: "Once launched, a PeriodicalExecuter triggers indefinitely, until the page unloads (which browsers usually take as an opportunity to clear all intervals and timers) or the executer is manually stopped"
e.g. of stopping manually:
Now what happens is that every time the application rendered the ajax call, it spawned a new executor, which ends up hanging around for a while. This would not be a problem if the browser "unloaded" itself every once and a while so here is some advice... if you need write a feature that requires rendering a periodically_call_remote multiple times then you are probably doing it wrong.
e.g. of stopping manually:
new PeriodicalExecuter(function(pe) {
if (!confirm('Want me to annoy you again later?'))
pe.stop();
}, 5);
Now what happens is that every time the application rendered the ajax call, it spawned a new executor, which ends up hanging around for a while. This would not be a problem if the browser "unloaded" itself every once and a while so here is some advice... if you need write a feature that requires rendering a periodically_call_remote multiple times then you are probably doing it wrong.
Sunday, November 16, 2008
Death to Agile - Rebuttal
Uncle Bob posted a rebuttal to Shores post.
If I read the next part correctly he believes its your job to do a good job...
The industry, like a mob, is not rational or scientific; it often blindly follows trends; it believes and accepts fallacies as truth; and it subscribes to leadership of the "strongest" of the group. From the mobs perspective, failing at agile (a.k.a Scrum) means failing at agile (Scrum, XP, Crystal, et al.). That's the a terrible reality and Jim is afraid that we are in trouble as a result.
As I stated in my earlier post I say f**k it. Just let people fail there is nothing wrong with that. Let them think that agile sucks because what they are practicing right now actually does.
Some have implied that if all those scrum teams had adopted XP instead of scrum, they wouldn’t be having all the technical debt they are seeing. BALDERDASH!... Let me be more precise. ASININE, INANE, ABSURDITY. BALONEY. DINGOES KIDNEYS.I do not think that Jim alluded to that at all but OK. I have been on too many teams that are composed of the wrong people, the wrong talent, the wrong leadership, in the wrong place, at the wrong time. The teams that gave birth to many of the agile practices where composed of all-stars! Think about the first XP team on the C3 project, wouldn't you be successful with these guys on your team: Beck, Fowler, Cunningham, Jefferies, Hendrickson?
If I read the next part correctly he believes its your job to do a good job...
But it is neither the purpose of scrum nor of CSMs to make engineers out of us, or to instill the disciplines of craftsmanship within us. That’s our job!... Oh, yeah, and stop blaming everything (and everybody) else for your own laziness.As you can tell I agree with Uncle Bobs position on individual responsibility however the fact of the matter is perception is a reality.
The industry, like a mob, is not rational or scientific; it often blindly follows trends; it believes and accepts fallacies as truth; and it subscribes to leadership of the "strongest" of the group. From the mobs perspective, failing at agile (a.k.a Scrum) means failing at agile (Scrum, XP, Crystal, et al.). That's the a terrible reality and Jim is afraid that we are in trouble as a result.
As I stated in my earlier post I say f**k it. Just let people fail there is nothing wrong with that. Let them think that agile sucks because what they are practicing right now actually does.
Saturday, November 15, 2008
Death to Agile
In this blog post James Shore expresses a bit of concern about the bad reputation agile has gotten as a result of "malpractice". If I read it right, he feels that this reputation will lead to the baby being thrown out with the bathwater:
Whatever we do, we need to do it soon. Agile is failing all around us, and I'd hate for the failure of the fad to take down the truly useful ideas that we started with.To tell you the truth I can't wait until "agile" dies. I am sick of it.
Tuesday, November 11, 2008
More on "Technical" User Stories
Consider a project where you are replacing an antiquated system for the police department and you have a user story similar to "As the captain, I want to know about the crimes committed in our precinct so that I know where to assign officers and reduce crime". Now imagine that your project team is composed of individuals in very well defined roles such as UI designers, server side developers, DBAs, and sysadmins.
How would this team go about implementing this story? In my experience the system would be designed in layers with integration occuring after each team completed the work on their tier. Then there is the question of, what do we do about the "old system"? Some feel that disabling or perhaps integrating the antiquated system with the new feature in the "old system" should be part of the "definition of done" while others believe that it should be treated as a separate user story. Scott Ambler wrote an article on the subject where he describes the problem with creating user stories that focus on these "so-called" non-functional requirements:
How would this team go about implementing this story? In my experience the system would be designed in layers with integration occuring after each team completed the work on their tier. Then there is the question of, what do we do about the "old system"? Some feel that disabling or perhaps integrating the antiquated system with the new feature in the "old system" should be part of the "definition of done" while others believe that it should be treated as a separate user story. Scott Ambler wrote an article on the subject where he describes the problem with creating user stories that focus on these "so-called" non-functional requirements:
All interesting requirements, but each one on their own provides very little value until you put them in the greater context of sending out marketing literature to a targeted group of customers. Until all of those user stories, and more, are implemented your system really doesn't provide true business value to your stakeholders, regardless of the fact that you have been producing potentially shippable software every iteration up to that point.Now if you have not read my original rant on "technical" user stories, then I should probably let you know that I believe it is a bad idea. The simplest approach IMO is to pair down user stories into the smallest vertical slices possible and incrementally add support for more general features. Using my example above, we could reduce this story to a specific type of crime. Another way to reduce the scope from an entire city to a neighborhood. Do whatever it takes to make it small enough to get "production releasable software" in one iteration. Its not that hard.
Saturday, November 8, 2008
RubyConf 2008 Day 3 - Code Review
There is not much I can say about this. I actually felt a little uncomfortable because it was poking fun at some of my customers. Here are some of the problems they pointed out:
- Leave no broken windows
- Fixtures are brittle
- Do not test "validate" using invalid data in your fixtures
- Use VI as your editor
- If you need default values for your Model, encode them in a class method
- Use "comment out code" while writing characterization tests
- hook methods ... check if it applies to you.. make sure you call super in another if you are implementing decoration using inheritance
RubyConf 2008 Day 3 - Advanced DSL's in Ruby
Neal Ford gave this talk and I would say that this was one of the best presentations at this conference. For the most part Neil is talking about some of the patterns that Fowler has been working on in his book only using examples written in Ruby. Ford also introduces some patterns he has identified and a handful of interesting frameworks to help support writing both internal and external DSLs.
The Beginning
He started by discussing the fluent interfaces, which use method chaining to express logic in a "sentence". The challenge with using this style is how method chaining semantics requires "an explicit terminator ", but that causes a "the finishing problem" because it breaks the fluency in the language. In order to mitigate this problem he advised the audience to use a wrapper context and use nested methods to control completion: e.g.
The Middle
Another thing to keep in mind is that we should control the context. In other words, alias methods so that it reads a little better: e.g. Instead of
He goes on to discuss a few more ways to combat the finishing a.k.a. stopping problem. A common mistake he sees people make in Ruby is using method_missing as a factory to create types. This approach violates the open-closed principle so he advised the audience to use Mixins and builders instead of using method_missing.
Almost at the End
Some other interesting things he discussed where function sequences, bubble words i.e. words that are there for readability not and executable statement, and the declarative nature of DSLs.
Sprinkled throughout the presentation were examples of some DSL code in Ruby. What I found particularly interesting was the work that Jay Fields has done with Business Natural Languages.
Just remember the three P's (Polish, Preprocess, Parse):
Polish => simple string substitutions to convert nearly ruby to actual ruby
Pre-process => load strings and modify to coerce them into ruby code
Parse => strings into your own language
The End
Another bunch of interesting work he talked about were:
semr (Matt Deiters)
Xample (Ola Bini)
Conclusions
I haven't had much of an opportunity to follow up on these project but I must say they are all rather interesting. DSLs have influenced the way I write code for some time, I just did not know that the coding style I adopted used some of the patterns that Neal described here. That made me feel good :)
Also can't wait for Jays book!
The Beginning
He started by discussing the fluent interfaces, which use method chaining to express logic in a "sentence". The challenge with using this style is how method chaining semantics requires "an explicit terminator ", but that causes a "the finishing problem" because it breaks the fluency in the language. In order to mitigate this problem he advised the audience to use a wrapper context and use nested methods to control completion: e.g.
rules.add(Discount.new.based_on(foo))
instead of rules.add_discount_based_on(foo)
The Middle
Another thing to keep in mind is that we should control the context. In other words, alias methods so that it reads a little better: e.g. Instead of
recepie.instance_eval { @ingredients }
alias instance_eval to provide context recepie.consists_of{ @ingredients }
He goes on to discuss a few more ways to combat the finishing a.k.a. stopping problem. A common mistake he sees people make in Ruby is using method_missing as a factory to create types. This approach violates the open-closed principle so he advised the audience to use Mixins and builders instead of using method_missing.
Almost at the End
Some other interesting things he discussed where function sequences, bubble words i.e. words that are there for readability not and executable statement, and the declarative nature of DSLs.
Sprinkled throughout the presentation were examples of some DSL code in Ruby. What I found particularly interesting was the work that Jay Fields has done with Business Natural Languages.
Just remember the three P's (Polish, Preprocess, Parse):
Polish => simple string substitutions to convert nearly ruby to actual ruby
Pre-process => load strings and modify to coerce them into ruby code
Parse => strings into your own language
The End
Another bunch of interesting work he talked about were:
semr (Matt Deiters)
Xample (Ola Bini)
Conclusions
I haven't had much of an opportunity to follow up on these project but I must say they are all rather interesting. DSLs have influenced the way I write code for some time, I just did not know that the coding style I adopted used some of the patterns that Neal described here. That made me feel good :)
Also can't wait for Jays book!
Friday, November 7, 2008
RubyConf 2008 Day 2 - What Every Rubyist Should Know About Threads
Jim Weirich starts with an introduction of computer architecture, Moore's law, and how the market is looking to build more multicore systems than they are investing in faster CPUs.
Java and Ruby share similarities in their concurrent programming models, although I am not sure how much since JRE 1.5.
He is demonstrated ruby thread code which incremented a nuber:
@amount += 1
We expect that this operation is atomic but there are a few operations here:
@amount #read operation
+ 1 #object creation operation
@amount = (the result) #write operation
With ruby you can create a Mutex object to synchronize a block:
Mutex.new.synchronize do
@amount += amount
end
Jim also demonstrated deadlocks and the ruby script failed. Chain of threads where waiting for each other. Increases when you lock more than one resource at a time. Basically he is saying that multi-threading is difficult.
Its hard because we share mutable memory.
What can we do to write correct multi-threaded code?
Use Erlang => Only Constants, Pattern Matching, Recusion (tail) (Erland eats serial for breakfast!)
Use Clojure => pretty much a functional language. The language is designed to avoid deadlocks.
Java and Ruby share similarities in their concurrent programming models, although I am not sure how much since JRE 1.5.
He is demonstrated ruby thread code which incremented a nuber:
@amount += 1
We expect that this operation is atomic but there are a few operations here:
@amount #read operation
+ 1 #object creation operation
@amount = (the result) #write operation
With ruby you can create a Mutex object to synchronize a block:
Mutex.new.synchronize do
@amount += amount
end
Jim also demonstrated deadlocks and the ruby script failed. Chain of threads where waiting for each other. Increases when you lock more than one resource at a time. Basically he is saying that multi-threading is difficult.
Its hard because we share mutable memory.
What can we do to write correct multi-threaded code?
Use Erlang => Only Constants, Pattern Matching, Recusion (tail) (Erland eats serial for breakfast!)
Use Clojure => pretty much a functional language. The language is designed to avoid deadlocks.
RubyConf 2008 Day 2 - Rameze
These are my raw unedited notes:
Luc Castera
His presentation is pretty amusing
He believes that Ramaze is one of the underrated ruby web frameworks
It is modular
There is only one dependency... Rack
ORM-agnostic
Template agnostic
From his perspective the source is Beautiful Code
Bacon BDD - It looks interesting
How is this different from rails?
Action methods accept parameters
#/controller_name/add/1/2
def add(first, second)
Supports regex and lambda routing
It integrates easily with jquery
Something that annoys me, Ariel not Luc, about these web frameworks is all of the scriptlets in the view. link_to for example makes it hard to read.
I, Ariel, don't know that this is better than rails. It seems almost like there is more room to make mistakes.
Luc Castera
His presentation is pretty amusing
He believes that Ramaze is one of the underrated ruby web frameworks
It is modular
There is only one dependency... Rack
ORM-agnostic
Template agnostic
From his perspective the source is Beautiful Code
Bacon BDD - It looks interesting
How is this different from rails?
Action methods accept parameters
#/controller_name/add/1/2
def add(first, second)
Supports regex and lambda routing
It integrates easily with jquery
Something that annoys me, Ariel not Luc, about these web frameworks is all of the scriptlets in the view. link_to for example makes it hard to read.
I, Ariel, don't know that this is better than rails. It seems almost like there is more room to make mistakes.
RubyConf 2008 Day 2 - Fear of Programming
This was a pretty engaging talk. No slides just us.
Nathaniel Talbott started his talk by asserting that artists have an emotional relationship with their creations. Fred Brooks likened programmers to artists (actually poets) because we both start with a "blank sheet" were we use our skills, knowledge, and imagination to "create" something. Now if Brooks is correct, Nathaniel believes that programmers are also subject to this emotional connection but because we do not tend to think of ourselves as artists, we tend not to explore this part of our lives.
Fear is a "very significant emotion" that prevent us from doing "that thing" but "all fear is legitimate because they are warning signs" trying to protect us from danger. "Fear is to your mind as pain is in your body", your body uses pain to tell you that there is something wrong.
Nathaniel went on to describe how fear hinders our productivity. Here are just some of the fears that he described we face:
Fear of a blank page
How do I start? What do I do?
Fear of the code
Legacy code
Beautiful code. Am I gonna mess this up?
Maybe I will write something that I will not respect and others will not respect me
Fear of not finishing
I am afraid it will not get done
Fear of finishing
Management or lead developers are afraid to call it done and push this out
Its easy to hack away on a side project without publishing it
Fear of the unknown
The big amorphous blob that I cannot conceptualize.
Some of us in the audience added the following:
Fear of not liking what I do
Fear of developing meaningless code
Fear of commitment
Fear of re-invention
Fear rejecting people
Fear of all of the non-programming activities
Fear imagination outreaches my ability
He states that since fear is a warning mechanism than "it is pathetic as a decision maker". Do not rely on your "fear" to make decisions instead rely on more knowledge and wisdom. He said use testing; prototypes; setting boundaries; and worst case scenarios. Nathaniel then polled the audience and I said use pair programming to combat fear. Others said be more afraid of something else however that would probably lead to layer upon layer of neuroses. One individual said that he prays. Nathaniel also referenced a few books that desribe how to deal with fear: "The War of Art", "Art and Fear", and "The Road Less Traveled". The jist of the this part was that big fuzzy problems are harder to deal with than smaller fuzzy problems. So work with smaller fuzzy problems.
His second suggestion which he described as the "ultimate antidote to fear" is Love! Surround yourself with people who love you unconditionally and support your decisions. Its better to make decisions based on the passion that you have for your craft. Pour yourself into the things that you are working on. Be motivated by your passion e.g. I love to solve problems!
Nathaniel Talbott started his talk by asserting that artists have an emotional relationship with their creations. Fred Brooks likened programmers to artists (actually poets) because we both start with a "blank sheet" were we use our skills, knowledge, and imagination to "create" something. Now if Brooks is correct, Nathaniel believes that programmers are also subject to this emotional connection but because we do not tend to think of ourselves as artists, we tend not to explore this part of our lives.
Fear is a "very significant emotion" that prevent us from doing "that thing" but "all fear is legitimate because they are warning signs" trying to protect us from danger. "Fear is to your mind as pain is in your body", your body uses pain to tell you that there is something wrong.
Nathaniel went on to describe how fear hinders our productivity. Here are just some of the fears that he described we face:
Fear of a blank page
How do I start? What do I do?
Fear of the code
Legacy code
Beautiful code. Am I gonna mess this up?
Maybe I will write something that I will not respect and others will not respect me
Fear of not finishing
I am afraid it will not get done
Fear of finishing
Management or lead developers are afraid to call it done and push this out
Its easy to hack away on a side project without publishing it
Fear of the unknown
The big amorphous blob that I cannot conceptualize.
Some of us in the audience added the following:
Fear of not liking what I do
Fear of developing meaningless code
Fear of commitment
Fear of re-invention
Fear rejecting people
Fear of all of the non-programming activities
Fear imagination outreaches my ability
He states that since fear is a warning mechanism than "it is pathetic as a decision maker". Do not rely on your "fear" to make decisions instead rely on more knowledge and wisdom. He said use testing; prototypes; setting boundaries; and worst case scenarios. Nathaniel then polled the audience and I said use pair programming to combat fear. Others said be more afraid of something else however that would probably lead to layer upon layer of neuroses. One individual said that he prays. Nathaniel also referenced a few books that desribe how to deal with fear: "The War of Art", "Art and Fear", and "The Road Less Traveled". The jist of the this part was that big fuzzy problems are harder to deal with than smaller fuzzy problems. So work with smaller fuzzy problems.
His second suggestion which he described as the "ultimate antidote to fear" is Love! Surround yourself with people who love you unconditionally and support your decisions. Its better to make decisions based on the passion that you have for your craft. Pour yourself into the things that you are working on. Be motivated by your passion e.g. I love to solve problems!
Taking your laptop
I gave The Man a lecture on why he shouldn't bring his laptop to the talks at RubyConf. I said "I don't do it because it distracts me during the talks; it acts as an anchor because if I do not like the talk its harder to leave the room (power cord, LAN cable, etc...); and well its just plain rude!"
Turns out I am a hypocrite. Here I am blogging while I wait for the next talk.
Turns out I am a hypocrite. Here I am blogging while I wait for the next talk.
RubyConf 2008 Day 2 - Patterns in Distributed Processing
Distributed computing and threading have been my favorite topics to learn about over the past year. In general this stuff is just way over my head and I feel like I learn something new every time I attend a talk on these subjects. This conference is filled with all sorts of interesting presentations including one where Mike Perham is discussing a library he created for clustered systems. He gave us a little background on himself and I was impressed to find out that he is responsible for shard support in ActiveRecord.
He seems like a brilliant fellow and is demonstrating some advanced threading concepts, only using distributed machines using DRb. This is an entirely different approach from a NeverBlock, which used Fibers, i.e. continuations, to allow green threads to "work" faster. I believe that based on the code I have seen today, Mike's approach is probably easier to understand and use.
He is also describing "Paxos" and encouraged us to take a look at Google's white paper "Paxos Made Live". Paxos is slow because there is lots of network chatter and Mike decided to head in a less formal direction using a designated "leader" and follower workers. Quote from his blog:
He seems like a brilliant fellow and is demonstrating some advanced threading concepts, only using distributed machines using DRb. This is an entirely different approach from a NeverBlock, which used Fibers, i.e. continuations, to allow green threads to "work" faster. I believe that based on the code I have seen today, Mike's approach is probably easier to understand and use.
He is also describing "Paxos" and encouraged us to take a look at Google's white paper "Paxos Made Live". Paxos is slow because there is lots of network chatter and Mike decided to head in a less formal direction using a designated "leader" and follower workers. Quote from his blog:
TokenWorker
ensures that one process from a group of redundant processes will be elected to perform processing for the next N seconds.StaticQueueWorker
distributes a predefined set of work to a dynamic set of processes every N seconds.
Wednesday, November 5, 2008
The XP Coaching Paradox
As a team new to XP, I want for you to coach my team, so that we can deliver valuable features to our customers.
Great, now that I know what our goal is, lets get down to business! However its just not that simple because people are afraid to embrace change for a myriad of reasons. The mistake I regularly make is reacting when I loose my patience or when someone says something that runs contrary to pure XP. The dogmatist in me converts anger into logic and I refuse to stop arguing until I am able to make them look foolish.
Although Emperor Palpatine would encourage you to "release your anger" that behavior is simply unbecoming of a Jedi and is just not the right thing to do! It hurts peoples feelings and brings down the teams morale.
Today was a great step forward in my life as a professional coach. I did not allow my emotions to get in the way of what I was doing. I listened to what my customers where saying without prejudice and reserved my comments when I heard someone say that testing was a waste of time.
As a coach you have to let people make mistakes. Its all part of the game.
Great, now that I know what our goal is, lets get down to business! However its just not that simple because people are afraid to embrace change for a myriad of reasons. The mistake I regularly make is reacting when I loose my patience or when someone says something that runs contrary to pure XP. The dogmatist in me converts anger into logic and I refuse to stop arguing until I am able to make them look foolish.
Today was a great step forward in my life as a professional coach. I did not allow my emotions to get in the way of what I was doing. I listened to what my customers where saying without prejudice and reserved my comments when I heard someone say that testing was a waste of time.
As a coach you have to let people make mistakes. Its all part of the game.
Characterization Testing
Test that code
Michael Feathers introduced the concept of using characterization testing in order to provide code coverage for untested legacy code. This technique is essential for anyone working with existing production code because it ensures that the external behavior of the system under modification is not effected as it undergoes internal changes. The problem with this technique is that it turns people off to testing despite the fact that this technique often helps to identify design problems in the system under test.
Unit Testing Is Stupid
On one occasion I was paring with a developer who was a staunch supporter of "test automation" but did not believe in unit level tests. His organization however mandated that every developer write unit tests, so he came to my team for help with writing tests for the system. I started by writing the first test....
def test_do_it
assert_equal "no clue what you do", @sut.do_it
end
... he said, "What are you testing? That really doesn't make any sense". I responded by saying, "I don't know what this class is supposed to do, but I can find out what it actually does by executing it". He scowled furiously at me but I executed it and low and behold there was an error! In disbelief he exclaimed, "what nil object?!?" Yes, we actually found a bug by writing a characterization test! This sparked a conversation among a few team members and it turned out that a misunderstanding of what his class was supposed lead to a bug.
Well not really. He ran off into his cave again writing code without tests in order to fix this problem. However he never came back to me. When I ran into him again I asked how testing was going and he gave me the same spiel about how unit testing is not important. Really? Even though it lead to discovering a BUG!
On other projects where there is just a ton of legacy code and I have to add or correct the existing behavior, we often spend a few hours just writing characterization tests. When I am pairing with someone relatively new to TDD they hate it. Lets just face it, test-last development is tedious. Shouldn't that be reason enough for people to prefer TDD?
Michael Feathers introduced the concept of using characterization testing in order to provide code coverage for untested legacy code. This technique is essential for anyone working with existing production code because it ensures that the external behavior of the system under modification is not effected as it undergoes internal changes. The problem with this technique is that it turns people off to testing despite the fact that this technique often helps to identify design problems in the system under test.
Unit Testing Is Stupid
On one occasion I was paring with a developer who was a staunch supporter of "test automation" but did not believe in unit level tests. His organization however mandated that every developer write unit tests, so he came to my team for help with writing tests for the system. I started by writing the first test....
def test_do_it
assert_equal "no clue what you do", @sut.do_it
end
... he said, "What are you testing? That really doesn't make any sense". I responded by saying, "I don't know what this class is supposed to do, but I can find out what it actually does by executing it". He scowled furiously at me but I executed it and low and behold there was an error! In disbelief he exclaimed, "what nil object?!?" Yes, we actually found a bug by writing a characterization test! This sparked a conversation among a few team members and it turned out that a misunderstanding of what his class was supposed lead to a bug.
Well not really. He ran off into his cave again writing code without tests in order to fix this problem. However he never came back to me. When I ran into him again I asked how testing was going and he gave me the same spiel about how unit testing is not important. Really? Even though it lead to discovering a BUG!
On other projects where there is just a ton of legacy code and I have to add or correct the existing behavior, we often spend a few hours just writing characterization tests. When I am pairing with someone relatively new to TDD they hate it. Lets just face it, test-last development is tedious. Shouldn't that be reason enough for people to prefer TDD?
Tuesday, November 4, 2008
A place for everything
Switiching from project to project is one of the most rewarding things about being a consultant but it is also extremely frustrating. Every few months I found myself asking people, where may I find X? When I would verbalize my frustration, my customers would dismiss it saying that its part of the process of "getting up to speed", however I would prefer to spend my time implementing features. Why must I be burdened with this accidental complexity?
That's one of the things that I love about Rails. What stands out to me immediately is how everyone seems to know where to find X.
Rails encouraged me to organize my Java web projects in a way that is intuitive to people. The results have been mostly positive; easier to understand file structure; increased diligence in using domain language for naming; common names for related features; easier to understand the relationship between view components and "server-side" code; and reduced complexity of our configuration files. I highly recommend that you go back to basics and start simplifying your code base structure!
That's one of the things that I love about Rails. What stands out to me immediately is how everyone seems to know where to find X.
Rails encouraged me to organize my Java web projects in a way that is intuitive to people. The results have been mostly positive; easier to understand file structure; increased diligence in using domain language for naming; common names for related features; easier to understand the relationship between view components and "server-side" code; and reduced complexity of our configuration files. I highly recommend that you go back to basics and start simplifying your code base structure!
Subscribe to:
Posts (Atom)