October 20, 2007

Software Development Essential Practices

I was in an interesting discussion last night: what software development practices do you consider essential? 

While opinions varied, I think there was some consensus on a few items.  In my list I also include some tools.  Some of these were mentioned by the group, but consider them my own additions.  Also, I am making this list specific to .NET, but the list applies to just about every language.

Universally agreed Practices

  • Source Control (1)
  • Local Development -- Every developer should have everything on their computer to run the system.  This includes all of the software and all of the source code.
  • Bug Tracking - nuf said.  There are to many tools available to list here.
  • TDD - Test Driven Development.  There was a little bit of back and forth, but the general consensus was that this should be done.
  • ORM - Object-Relational Mapping
    • NHibernate 
    • SubSonic - My person favorite
    • LINQ to SQL - not yet, but I feel this should be on the list.
    • LLBLGen ($) - Not free, but I've heard many good things about it.
    • More
  • Continuous Integration - Simple process that sits on a server and waits for things to get checked into your source control system.  When it sees something new, it gets all of the latest source code, compiles it, and runs all of the unit tests.  If there are any problems anywhere in that process it alerts the users (email, desktop icon, wave red flag, etc). (3)
  • One Step Build - it is unbelievably cool to be able to click one button and have your entire project compile, run all tests, and possibly create an install in one step.  Personally, I do like it, but with the current set of tools this is one of the hardest parts to setup.

Highly thought of but non-essential practices

I'm sure I have missed some tools in the list, but it is the practices that are more important anyway.  But if you put a comment about any tool that I missed I will add it to the list.

(1) Source Safe was notably not in the list.  While I don't like it either, it is better than nothing.  But if your team is greater than 5 people or you have multiple people working on the same project you really should look at one of the other products on the list.

(2) Not a unit testing library, but a Mock Object library.  Pick a unit testing libarary (NUnit, MBUnit, XUnit), then pick a mock object library (Rhino Mocks, TypeMock, NMock) to use with it.

(3) I really need to talk about continuous integration more.  But it is one of those things that leads you down a path.  First you add source control, then you start adhering to separation of concerns, then you start unit testing and mocking more, then you add continuous integration, and then one step builds are all part of the mix.  One best practice leads to another, but they don't make a bit of sense without some of the prior pieces.

(4) If you are a Code Rush person instead of a ReSharper person -- carry on, you are in good company.

($) The cost money - not just beer, but may have free version versions as well.

5 comments:

Anonymous said...

"Every developer should have everything on their computer to run the system"

I can't agree with this. Suppose you are a company with several large clients using different dbs (Oracle, MSSQL, DB2 etc). Now, are you going to run all databases on your development machines, all test/staging/live equivalents with all the relevant test data and security on all machines? A dedicated db server (or servers) is way better and produces a lot less work for internal support.

"...includes all of the software and all of the source code"

Why? Is everybody going to be working on all, say, 500k lines of code (that is, all projects of the company), at the same time?

And is every developer working with, say, Perl or Cobol or Photoshop? If not, why would they all need it?

Look at this from the point of view of the company (who pays your wages). Everything for every developer costs more. Money that could be more effectively spent on infrastructure so that all people in the company benefit. This applies especially to small companies.

Chris Brandsma said...

I think you are reading way more into that statement than you should have. Way more than was intended anyway.

Secondly, it sounds like you are dealing with a large enterprise system that has gone through multiple iterations, with multiple developers, using whatever language they felt like. In other words, you are working with a mess.

I guess I left off the "within reason" part. Every developer should have everything to do their job at their disposal.

Now, should a developer have ALL of the source code: yes! At minimum they should have access to it. Even if they don't have the tools to compile it.

But, if one "developer" needs photoshop, they should have it. For the rest of the developers. But that doesn't mean everyone NEEDS photoshop. I've done lots of graphics work in my time, and still haven't used PhotoShop. Currently I use a free tool called Paint.Net.

Now as for databases.
Oracle has a free version.
MSSQL has a free version.
DB2 has a free version.
(how many databases are you running anyway?) But, which databases are the developers writing code against? Those are the important ones.

Next part, the data.
Yes, I would say that the developer should have as much of the data on their laptop as they need to be able to test their data.

That does not mean the developers need full copies of the entire database, but they need some of the data and the structure of the database (tables, view, sprocs).

I have that currently, where I am working with a large MSSQL database. I have the entire structure of the database on my system, but all of the data is fake. I have a script that creates the fake data for me and I use that for testing.

Now I can do whatever I need to the data without affecting any of the other developers on the team.

If you have a team of developers working on the same database, with the same data, you just invite chaos. And yes, I've been there, I know.

So what is this trying to do? Add structure to a chaotic environment. Developers don't step on each other 's toes, and they can test in isolation of each other.

I am sympathetic to the needs of the corporation. This also means being cognizant of developer productivity and human nature. Developers make mistakes while developing ("oops, I just deleted all the data in that table"), this limits those mistakes till they are done, and the rest of the developers don't have to suffer through someone else's blunder.

Anonymous said...

Deveoper speak: Everything != everything. You should be clear what you mean, after all, I expect you have to be when talking to your clients (whether internal or external).

It is a big problem with developers, I find. They live in their own little world without putting their heads over the parapet and seeing what reality looks like. I know, I've been there.

First, having the db (or dbs) on your laptop often means the configuration (such as security settings) are ignored. When the system gets shipped to the client, lo and behold!, it doesn't immediately work. Who deals with the client in this case? Not the developer, or not very often anyway.

And then the data. Test data is sometimes shipped by the client. Sticking this on 50 desktops and laptops is just a waste of time and resource.

And then there's stored procedures and UDFs and whatever else a developer may usefully create. Do all developers ensure all other deveopers have these? Nope. And then the db gets shipped to the client. Lo and behold! A problem is subsequently discovered.

You can also create any database on a central db server and script the tables and test data. Then anybody else can look at this and test against it, they don't have to have access to your laptop. Saves time and effort.

Whether the dbs are free or not is irrelevant to this scenario.

Let's now look at whatever else developers do. Documentation, bits of design, code building, some config work, property files, estimation, timesheets etc.etc. All of this should be somewhere central - not on a laptop, otherwise the work multiplies and by more than the number of developers.

Let's look at a code build. It's useful to the whole IT department to see how builds are going. The PMs, Dev mgrs, product mgrs can all find it useful. It may be that a refactor is in order to make the code easier to maintain. Rather than hiding this fact, all interested people can see it for themselves. Hence the reporting, graphs etc. of succesful/failed builds and the detail should be somewhere central and accessible.

I strongly suggest you have your night-time discussions with the CIO, with some savvy commercial people, with PMs and Development Managers. Talk to interested people other than developers. You might find that your assertions on this blog would be seriously questioned by a lot of other people in the company. And it doesn't have to be a large outfit either.

Chris Brandsma said...

I get the feeling I'm being bated here. :)

First, this blog post was prompted by a list group containing many developers, architects, and other people in the developer community. I didn't just make this stuff up.

And this is a group that actively works with corporate environments on a regular basis and they do ship code. In other words, I don't think I'm talking from an Ivory Tower here. These are practices that a large group of developers (not just myself) have repeatedly seen to work.

Second, at the company I work for, we DO follow these practices. And I can point to several other companies that do this as well.

One item that you are preaching here, that I fully agree with and was buried in my post, is having a build server and a test environment other than the developers machine.

We also have test databases with larger datasets. But I don't develop directly against those. I do integration testing against those databases.

This is what Continuous Integration is about. Each developer's code should be compilable on a build server. The build server has the compiler and the software needed to run the tests (Unit Testing). The build server builds all of the source code when a developer checks in, and runs all of the tests.

If all of the tests succeed, then the testers can test the code. Otherwise, why bother.

Also, an application should not go straight from a developers machine to a customer. It should come from the build server.

Second part: we have scripts that recreate the entire database as part of a batch process. It also creates any base data that we need. This script is also run by our build server and is used by the tests that the build server runs.

We also have a script that we can point at an existing database, extract the database metadata, and create the build scripts for us. Without that: yes, it would be a waist of time to create scripts to generate all of the tables, sprocs, and functions needed. But since we have it scripted...why not?

We have been effectively able to do this with SQL Server, Oracle, Advantage, and SQL Anywhere. I can't speak to MySQL, but I wouldn't assume it would be too large a problem.

Also, in all of my database projects, I design them so that it is a simple procedure to change the connection string and connect to a different database.

That allows me to develop against a local database, and then do broader testing against a larger central database.

Once this is created and in practice, you now have an environment that is fully recreatable on a variety of systems. To me that is worth the effort and the time.

Now take this one more step down the food chain. I was talking specifically to developers about better ways of creating software.

I have spent a inordant amount of my time working on other developer's code, that is already in production, that had none of these things. I still got the job done, and I did it without a lot of these practices.

But there was not way to release that software without a nagging feeling in the back of my head that something could go wrong at any time because there were no unit tests, or test procedures writing down anywhere. I was coding blind and hoping of the best.

And with a lot of existing code bases, that is what you have to do.

But if you are starting from scratch, or there isn't much code there to begin with, then by all means please try some of these.

No essential practices will work if it brings developer productivity to a stand still. And nothing that I mentioned should.

This is a long reply, but it is a complicated topic, with many ins and outs. Please keep pestering me with questions if you have them.

JAGID said...

Chris has already said much of this but I'd like to also weigh in to this debate.

Automated tests are an essential element of any modern software project. To be able to run these tests a developer is going to need the appropriate software. This definitely includes the database.

Shared development databases just don't work. In a shared environment a schema changes breaks the app for everyone. And there's no way that the database should be changing without the appropriate app changes also being made. You can't do that in a shared environment. And if I work from home in the evenings or on the train I might not be able to VPN into work and access the shared database.

Developers need the freedom to experiment locally. Perhaps this is even taken a step further by using Git to source control 'experimental' changes locally without affecting the central repository. Normally however everyone is checking in multiple (10+) times a day. And everyone can see what is going on - the CI server makes sure of that.

To the developers that I work with every day it is essential than a new team member can check out the application from source control, run a build script and then it just works. These scripts are also designed to handle any environmental (dev, CI, QA, prod etc.) changes.

Today's agile teams require multi-skilled developers. Broadly I need everyone on a team to be able to do everything. However no principle is applicable all the time. Photoshop falls into this category. I can guarantee that you don't want me doing editing graphics! This is the exception though. You need to invest in your developers. They need the tools to do the job. And most tools that we use are not expensive or are free. In fact apart from Visual Studio the only other commercial tool that we use is R#. And seriously this is the best $350 that you will ever spend.