The focus of this blog, explicitly and without apology, is on software test and quality issues.
One way to achieve software quality is to slow development to a crawl.
Say, for example, that you start with a team of 100 programmers and fire ninety-nine of them. Now take all that money and hire ninety-nine people of different roles - testers, configuration managers, methodologists, version control experts, graphic designers, planners, project managers, analysts, technical writers, and so on.
You may have better software - software that looks prettier, has fewer defects, and has a better user experience ...
... it's just that it's going to take you a year what you used to do in a week, right?
I'm reluctant to call that improvement, and I suspect you are too. I suspect with most companies, the 'right' answer for how to staff 100 people lies somewhere in the middle.
That said, here's a story for you ...
A Christmas Carol (Sort of)
Imagine for a moment that you are a programmer (or tester, or whatever) at XY Corp, medium-sized business in the United States, with a software development group of, say, fifty people. The business folks email your whole team with a request -- a report to pull data out of the database and display it on a web page, maybe with a parameter or two. One of the old programmers, now a director of IT, wants to be be helpful and replies with the basic SQL for the query.
Joe, the intern, gets the email and immediately starts coding.
"Woa, woa, woa, Joe, you don't understand", you say. "We need to get this request into our story-card system and have a kick-off. We need to identify success criteria up-front."
And you do. You hold the meeting and get conditions which will lead to what outcomes, the create an executable specification in a tool like
Cucumber or
Fitnesse. The developers wire up these conditions and see red bars (no output), then go off to design the system.
Geek party time.
The developers go off to design models, each representing a customer, a row of the output. The models will be pulled from the database through an object-relational mapper. They will design the models test-first, using unit-testing tools like jUnit or nUnit.
The objects will be pulled from a self-aware list that has a connection to the database; the programmers will also build that test-first. The self-aware list will take the parameters, generate itself (well, not exactly, they will be generated by a factory), and then be passed by a controller to a view that will take the list and draw it on one screen. It's all test-first. It is a sight to see - it will only take a pair of programmers four or five days to kick this thing out.
There's only one problem.
Before you are done the kickoff meeting, Joe the intern drops by.
"It seemed simple to me; I hooked up the parameters to the SQL, did a for loop, and kicked out the results as an HTML table."
Let's see here: The 'right' solution would take about two person-weeks, and the wrong one took an hour or two, right?
What Just Happened?
I'm not against object-relational mappers. I'm certainly for TDD, and I've seen TDD done at the true unit level with mock objects work extremely well. The Model View Controller (or MV Presenter if you prefer) pattern is established well, and I like tools like selenium or fitnesse
... yet Joe the intern was faster.
Yes, he was, really. One thing we know for certain about all those extra practices is that they are just that: Extra. They add drag to the project.
Now, there are certain advantages to all those extra practices. Through those practices:
- We reduce the risk that we will build the wrong thing
- We reduce the risk that we build it, but it isn't quite right
- We make more clear communications with the customer and technical staff, so the developers know what 'done' means and the customer know what to expect
- We can increase the reusability of the components we are creating
- We increase the maintainability of the components we are creating
- We increase the extensibility of the components we are creating
- We decrease the testing time we will spend next time, after the next modification
... and so on.
For this project, none of those risks were very big. It is very possible this is a one-time report that you write once -- or that modifications will still be extremely cheap and easy.
Then again, it is possible that this is the beginning of a reporting framework that will go and the object-oriented approach I described above is more appropriate. With the context describe above,
we don't really know.
And that's the thing. Different software development practices are appropriate to solve different kinds of problems.
To some extent, this is an impossible problem - because some practices lead to code that is more extensible, malleable, and cheap to test, which will be valuable if we know we will experience churn, and knowing if we will experience churn is essentially predicting the future.
Yet in some environments, like Socialtext, where we touched all the code all the time and released every two weeks for two years, we know we will experience more churn then that time we produce that one report for the Customer Service Department. (By the way, yes, I know, the intern took two hours, but we could train the department to do it themselves with a SQL reporting package. You're getting ahead of me. Hold on.)
So, while we might not have an accurate crystal ball, it may be possible to examine the factors involved in our problem and decide what kinds of solution is appropriate -- and those factors may cause the scope of the solution to scale up or down. The reporting solution might just be a SQL reporting package; a one-time log reader and reporter might be a awk script we hack out.
Now, if you want to take that same script and run it, piping the output to a database and reporting that output to the executives, you might want to re-write it test-driven in a language like perl, running it overnight as a scheduled task. Want it to be real-time and we might look at a different approach.
What I'm saying here is that the context matters in software development.
We've know that for years in software testing, and even have a formal
school of testing around it.
Many of the same principles hold for programming, software development, and project management. We talk about the project management things, at least implicitly, when we talk about
methodology design.
Programming, not so much - or at least, not often enough in the circles I listen to.
If I'm listening to the wrong voices, please, help me plug into the context-driven software development community.
If those voices aren't out there enough, well, let's go make them.
What do you say?