Time-to-Login-Screen, and the absolute basic requirements for good software
I went and hung out with some fellow developers on Saturday (at the Grist Mill in New Braunfels, TX, incidentally — wonderful place!) and we talked about all sorts of things on the way down, there, and back up. One of the things that particularly stuck in my mind was a discussion how there are still software development teams out there not using things like source control or automated builds. Everything is by hand and magic.
It occurred to me that this is simply unacceptable and embarrassing. I don’t believe this is an elitist statement. We can debate the finer points of how to do unit testing with TDD or TAD, etc we can debate about what BDD is and whether and to which degree it’s useful, etc. But, and I hope this isn’t just my thought, there are certain things which are simply not debatable. If you’re not doing these things on any sufficiently large project (although I could make an argument that these things are important enough for any project delivered to a customer and/or used in a production manner).
I’ll get to what these things I consider as ‘absolutes’ in a minute, but before I do that, I want to explain why these things might be important — to define the values I think are important so that you can get a feel for where I’m coming from.
Horrors of an Unrepeatable Setup
How many times have you walked into a software shop and picked up the maintenance on a project and it was in total tatters. It didn’t compile, you weren’t even sure you had the latest source code –in fact, no one was sure, you seemed to be missing all sorts of 3rd party components and their obnoxiously-installed licenses, etc, etc. To boot, your manager says that you need to fix a particular bug and get the fix in for testing by the end of the week. It’s Monday, you ‘fix’ the ‘bug’ in a matter of minutes, but now you about 4 days to figure out how to create a build and put it into the test environment. Fast forward 6 days later after you manage to get enough clues from co-workers and phone calls to ex-employees, you find out that the build you deployed is an OLD build that contains several already-fixed-and-deployed bugs. Now you begin the fun of trying to track down where the latest source code is so you can start everything over.
I’m willing to bet that almost every single one of you has had an experience like this. If not, then you are VERY lucky and I hate to be the one to tell you that, odds are, your time is coming. For me, this scenario has happened to me on almost every project.
The Virtues of Repeatability
No Magic
What this all points to is a failure of the dev team to create ‘repeatability’ in their software infrastructure. While it’s unlikely, it’s possible that the code itself could be the best, most well-written code ever known to man. But since no one knows how to build, test, or deploy it, it might as well be crayon drawings from my 2 year old. One of the most important attributes of ‘good software’ should be ‘repeatability’ of its build, test, and deployment. So I’m gonna go out on a limb here and suggest that these things should be a must for any software project that is intended to be used in a production manner. If you don’t have these things, you have created a situation where serious and potentially irreconcilable problems will surface in the future. If you don’t have these things, you should be working soon on achieving these. One last thing: I don’t want to hear any argument about how long it will take to get this going. I can say without any hesitation that you’ve already spent or will be spending many orders of magnitude more time dealing with the problems that arise from NOT having repeatability, than you would setting your project up for repeatability.
Without more adieu, the key points of achieving Repeatability (with more specifics on each will follow) are:
- Source Control
- Automated Build
- Automated Testing
- Continuous Integration (for multi-dev teams)
- Automated Deployment</ul>
Source Control
The code should have it’s primary home in a central, well-known location
This one should hopefully be pretty simple: The code should have it’s primary home in a central location and absolutely not in the ‘Visual Studio Projects’ folder in someone’s My Documents folder on their desktop. Of course, if you don’t have an actual server box, the source control repository can be on someone’s desktop, as long as that’s the CENTRAL location for it and as long as it’s getting backed up somewhere.
In addition to simply having a central go-to location for the source code, I highly recommend you get a source control management software that tracks versions and enables you to do differences, branching, merging, reports, etc. I personally recommend ‘Subversion’ for this task, but others have found software such as git, SourceGear Vault, Microsoft Visual SourceSafe, StarTeam, and many others useful. But whatever you do, for the love of software, PLEASE use SOMETHING.
Automated Build
The code should have an associated automated build script that requires no magic by the person running the script
Once a would-be software maintenance programmer (possibly yourself) pulls down the latest code from the source control repository, building the code into a runnable unit should be automated to the maximum extent possible (preferably 100%). Now, that doesn’t mean you have to install IIS/Apache on the box, it’s OK to have certain prerequisites (i.e. ‘Windows’ or ‘Linux’, ‘IIS’ or ‘Apache’, etc). If there are specific environmental requirements like this though, you should have the build script at least check for them and alert the human there’s something missing.
A helpful side-effect of automating your build process is that you see what a pain it is to configure your app (and they’re all a pain) and it might motivate you to make configuration easier.
Automated Testing
The code should have at least a basic success indication check test and it should be able to run in an automated fashion
There should be some way to prove that a build was ‘successful’ beyond the build script telling us so. We need real proof/verification. If you’re not doing unit tests, TDD, TAD, POUT, whatever, at least have ONE test that does SOMETHING with the app to verify that it doesn’t just crash on startup.
A maintenance programmer who’s new on the project should have some indication as to whether the code he just built actually resembles a working product or not. The more tests you have, the more confident he/she’s going to be. Please give the gift of confidence to your successor.
Continuous Integration
When a developer commits code to the source control repository, a separate, objective, and impartial system should report the success and health of the build.
I was strongly tempted to say that this should be a requirement all the time — even for a solo ‘team’. CI certainly helps even for a solo developer, but I wouldn’t consider it an absolute must. Having said that, if you have more than one developer committing code to the same project in the same source control repository, I will say that CI is an absolute must.
It is important that the CI run on a non-developer machine install. It is, however, perfectly acceptable to run it in a virtual machine running on a developer’s desktop computer though if the budget is tight. The intention here is that you have a somewhat pristine OS install that isn’t polluted with SDK’s, developer tools, environment settings, etc. You want to try to create a production-like environment to the maximum extent possible. This doesn’t mean you need to replicate your production hardware requirements, but you should try to use a similar OS setup to what the production servers (or customer computers) are running. If the production server is running Windows 2003 Server, see if you can get your CI OS install to be Windows 2003 Server. If the budget is tight, you might consider using a 180-day trial version of Windows 2003 Server until you’re sure how you like your CI setup. Hopefully by then you’ll be making some money and you can afford a copy of Server or an MSDN Subscription or something. I’m not sure about the legality of re-building your CI virtual machine with 180-day trial versions of Win2K3 server over and over again. If it’s legal and doesn’t violate the EULA, that may be an option too. Please check with your corporate attorney, priest, or local fortune teller for clarification (since no one can really truly understand Microsoft EULA’s and divination is just as an acceptable means as legal review for getting it right).
Automated Deployment
The build product should be deployable to another environment with minimal human interaction
Having said that, it’s not usually possible (or feasible) to have one-button automatic deployment to any specified environment. In my experience, there’s always something required by a SysAdmin, a DBA, etc. If not perfection, you should at least strive to deliver a ZIP file or MSI to your SysAdmin and a well formatted change script to your DBA. Strive to make deployment convenient, coherent, and above all consistent.
A Metric of Success: Time-to-Login-Screen
Now that we’ve established the virtues of repeatability — and I hope you are intent on practicing them — how do we measure our success in this effort? I propose a metric: “Time-to-Login-Screen” (TTLS). This of course assumes your app has a ‘login screen’, but it applies to any app. Perhaps it should say ‘Time-to-First-Screen-With-Functionality’ but ‘TTFSWF’ isn’t as sexy as ‘TTLS’.
The general concept here is how long can I take a new-hire developer and get him/her coding/building/deploying (i.e. a productive member of the team). This metric can expand further to include how long HR takes, how long IT takes to set up the desktop, how long it takes to install any 3rd party components, etc. But for our purposes, let’s start with using TTLS to represent the time it takes from when the IT department hands your dev a desktop to the time when they’re committing code into your source control repository. Let’s exclude commonalities like Visual Studio (or your IDE of choice) and other basic tools. We should, however, include things like 3rd party components (Infragistics, Telerik, etc) and their licenses and such.
If your TTLS is over a day, that’s a problem. If it’s over a few days, the situation is highly dysfunctional. If it’s approaching a month (yes, I worked at a shop where it was a little over a MONTH before I was committing code into source control), then you should re-think how you do software entirely. Something is seriously wrong.
- Automated Deployment</ul>
- Continuous Integration (for multi-dev teams)
- Automated Testing
- Automated Build