I find that I have very little to add to the words of Robert Martin (Uncle Bob).
I highly recommend people to look at the available videos of him and his talks about professionalism.
Our profession as programmers is very much immature. We have hard to accommodate accountability and transparency. We have little regard of what constitutes a true "Deliverable". And, to paraphrase Ken Schwaber, we have a very odd understand of what it means to be "done".
http://www.hanselman.com/blog/HanselminutesPodcast119WhatIsDoneWithScrumCoCreatorKenSchwaber.aspx
Basically, we like to do the algorithm, but we do not like to bridge the algorithm to the world.
A nice analogy is the difference between a hobby mechanic and a professional service business.
We put juniors in our office space and we expect them to produce.
Even a person operating the fryer at McDonalds gets some sort of apprenticeship.
We resist change. We resist being scrutinized. We resist being managed. We seldom recognize business value. We resist comparison.
We do not have objective standards or engineering principles. The only professional criticism from programmer to programmer is "that's not how I would do it".
http://www.hanselman.com/blog/HanselminutesPodcast171TheReturnOfUncleBob.aspx
But there are standards to be had. Engineering principles exist. But I sincerely do not know if you will actually appreciate them if you have no experience in the industry. I have yet to see this successfully condensed into a learning experience that mentor can bestow on apprentice. Or in the class room.
Uncle Bob has the comparison of when doctors learnt to wash their hands when walking from an autopsy to the maternity ward. It took a generation change to implement it. And the problem domain was unknown to anybody fresh out of the contemporary version of "med school". One may even argue wether or not it still was the same profession before and after knowing about germs.
Even though I don't think a serious argument still exist against Test Driven Development as a whole. It is still an immature practice which a significant part of the developer community still resist.
Without a frame of reference, it is hard to separate the community from the practices. It has become a part of the expected norm that software has bugs and that software development is an inherent financial liability.
I believe and hope that this will change.
Just fifteen years ago (being careful to pick a timeframe that excludes me), programmers were stereotyped to be socially awkward, cave dwelling magic workers with questionable antics and hygiene. Approachable only by the specially trained project manager who knew better than to hint at a questionable decision or belated milestone.
Today, most project managers are quite capable of programming in MS Excel and the sacred art of programming "magic" has unraveled.
Even though I presented a caricature strawman, something has certainly changed.
I hope that they will keep changing. That technical debt, development liability, Test Code coverage, Continuous Integration and automated deployment will be common case real life business metrics KPI's (Key Performance Indicators) for the future.
The debate is over, TDD won. Will the community inertia demand another 15 years before the change is de facto?
Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts
Sunday, August 30, 2009
The reverese dependency problem. TDD
When building the word chain app, http://codekata.pragprog.com/2007/01/kata_nineteen_w.html , I quickly identify that there are multiple problem domains involved. One is the generic question of finding the shorter path in a mesh of connected nodes.
Then the question is: do you build this functionality with its own set of unit tests or not?
I would like to say "not". I don't want to take "time out" from my real business problem to build a different class library in some BDUF venture. I want to refactor into this design.
However, let us say that I proceeded with this, and elegantly refactored a utility class library that was generic and succinct.
And then this class library is so generic that I have more client apps that should be consuming it. And new clients warrant more functionality.
I may not be able to express new client requirements from my wordchain problem, and therefore I need to TDD from the unit tests of the new client apps.
However, then the class library, slowly becomes "dependent" of a growing number of its clients, because that is where its unit tests are. It wont get coverage unless you run the unit tests of its clients.
I realize that at some point you must recognize that the new class library is a new "deliverable" and thus you need extract its own tests. This will however result in duplication and longer release cycle for the word chain app, because it is a separate release item. New word chain app requirements will have longer development time because new requirements to the class library must be TDD'ed through unit tests of the class library, parallel to the unit tests of the word chain app.
Theoretically, you should have 200% percent coverage in the class library. One "100" through the sum of its clients unit tests, and one "100" through its own unit tests.
Interesting problem. It becomes sort of a reverse dependency problem. Stabile components become dependant of unit tests of less stabile components.
Do you find that you get test duplication because you don't want some internal class libraries to be "depending" on the unit tests of its consumers?
Then the question is: do you build this functionality with its own set of unit tests or not?
I would like to say "not". I don't want to take "time out" from my real business problem to build a different class library in some BDUF venture. I want to refactor into this design.
However, let us say that I proceeded with this, and elegantly refactored a utility class library that was generic and succinct.
And then this class library is so generic that I have more client apps that should be consuming it. And new clients warrant more functionality.
I may not be able to express new client requirements from my wordchain problem, and therefore I need to TDD from the unit tests of the new client apps.
However, then the class library, slowly becomes "dependent" of a growing number of its clients, because that is where its unit tests are. It wont get coverage unless you run the unit tests of its clients.
I realize that at some point you must recognize that the new class library is a new "deliverable" and thus you need extract its own tests. This will however result in duplication and longer release cycle for the word chain app, because it is a separate release item. New word chain app requirements will have longer development time because new requirements to the class library must be TDD'ed through unit tests of the class library, parallel to the unit tests of the word chain app.
Theoretically, you should have 200% percent coverage in the class library. One "100" through the sum of its clients unit tests, and one "100" through its own unit tests.
Interesting problem. It becomes sort of a reverse dependency problem. Stabile components become dependant of unit tests of less stabile components.
Do you find that you get test duplication because you don't want some internal class libraries to be "depending" on the unit tests of its consumers?
Subscribe to:
Posts (Atom)
