I'm sure by now you've seen my comments and my other post, so I won't pretend that I actually know the answer. Best I can offer is a summary of what I've heard/read from others and add some of my own experience into the mix.
First, I want to say that a little while ago I came across a blog which belongs to one of our own Programmers SE members, Martin Blore and IMO this one specific post about TDD self-actualization is very accurate. TDD is the last, highest level that ties everything together but without previous levels, especially the largest one, principles and practices of producing clear and readable code, it will be very difficult if not impossible to make TDD work.
In my company, both Agile and TDD were imposed on us by management, and at first we simply did them because we were told (which is the opposite of agile). We've tried TDD twice and while I'm a huge proponent of using automated tests, I've personally thrown out all the ones that the team slapped together in the last release. They were fragile, gigantic, copy/pasted up the wazoo and riddled with sleep statements that made them run really slowly and unpredictably. My advice for your team: DO NOT DO TDD... yet.
I don't know what your situation is because you mentioned you've been with the company for only 6 months and that you are a contractor. Are your long-term goals to stay with this company or is the contract going to run out? I'm asking because even if you do something, it might take quite some time to actually see results.
Also when you join a team, it usually takes time before you get enough credibility and respect of your team where they (developers and management) would even consider anything you propose. In my experience, it helps if you put out few fires and demonstrate that you have skills and knowledge that others can depend on. Not sure if 6 months is enough. Quite frequently a new, ambitious person would join the team, then make a post here asking how they can change the world. Sad reality is that they simply can't.
So assuming you have your team's respect and attention. Now what?
First, both management and developers need to be aware that there is a problem. Management measures results in terms of work delivered. If they are happy with the current quantity and quality of features, then sad reality is that they won't listen. As others have pointed out, without management's support, it will be extremely difficult to introduce any kind of change.
Once you do get management support, next step is to dig deep and identify the root causes of why the team operates the way it does. This next topic is something that's been a personal quest of mine of a little while now. So far this has been my journey:
- Once you have management's support. You can start introducing a lot of centrally-dictated practices/processes that MainMa suggested in response to my question. We've done a lot of them (except for paired programming) and you definitely see benefits. Code reviews especially helped to standardize on styling, documentation and also allowed us to shared knowledge/techniques among the team. Even though, code reviews were dictated, the team actually likes them and we review every piece of functionality that is checked in. However...
- You notice that the code that is generally written is still too coupled, design is bad or completely lacking. Code reviews catch some of it, but there's only so much you can rewrite. Why is design bad in the first place? -- A lot of developers have never been introduced to good practices and were never formally taught OOD in the first place. A lot of people "simply coded" whatever task they were given.
- With management's support you can introduce more process, such as discussing design before any coding takes place. But you are only one person and it seems that as soon as you don't pay attention the team reverts back to what they've always done. Why?
- Can better practices or habits be introduced and taught so you don't have to constantly monitor? -- Turns out this part is not so easy.
- Why are other team members reluctant to learn and pick up new practices and why are they so resistant to SOLID or DRY when it's been written about so much in modern software methodology literature? With all positive changes we've had in my team, 2 weeks ago I had an argument were I refactored 2 functions that had identical 15 lines of code and the reviewer called it heroic, unnecessary effort because there's nothing wrong with copy/paste of only 15 lines. I strongly disagree with such views but for now we've settled on agreeing to disagree. -- So now what? Now we've reached the topic of my other post.
- As maple_shaft and nikie pointed out in their answers (sorry, MainMa, you got the most votes, but you are so 5 steps behind :) ), you have reached a stage where "process" can no longer help you and nobody on this forum can tell you what the "fix" is. Next step is to approach individuals, maybe one-on-one, maybe as a team, probably both at one time or another and talk to them. Ask them, what works and what doesn't. The only way to identify the root cause of what drives them is now to talk to them individually and find that out. As part of this step, I recently came across a completely different team problem, but I think Joel's answer here, which is very detailed and insightful, would apply to this case as well. In summary, while using management as "short leash" is a possible approach to just about anything, we need to remember that we are dealing with humans so to truly understand motivations we have to cross more into psychoanalysis than pure management or technical leadership.
- So now you are talking to your teammates? What do you ask them? I'm not sure about this next part because I've never been here. Here's a possible scenario: Q: How come no SOLID? A: I don't need it. Q: It might help. A: I do alright as is. -- somehow you need to generate a series of sounds that would leave your mouth and cause the listener to recognize that things could be better if they give whatever you are peddling a chance. If you fail here, they won't ever be convinced that whatever "the process" makes them do actually has any value. On the other hand if you get past this point, you'll probably find you don't even need "the process" any more.
- IMO at the very root, your teammates won't learn if they don't see anything wrong with their current habits/practices. So maybe next step in all this is to find a way to illustrate, highlight the problems and make them obvious. After all, we are not writing readable code, using SOLID/DRY principles or maintaining documentation just because it gives us a warm and fuzzy feeling. We do it because it produces better quality code and frankly makes us code faster. Can that be measured? Maybe this is where software metrics come in?
- Here's a crazy idea and I have no idea if it would actually work (it might be a standard industry practice, or it maybe completely invalid. I just made it up in the last 24 hours), but I'm very tempted to bring it to the table as soon as next year starts:
- Against opinions of many others, introduce the idea of Author/Owner for all source files. As The Pragmatic Programmer suggests this will give a sense of ownership and responsibility to a single person who will be responsible for a piece of source code. It doesn't mean other people can't modify the code, we are all working as a team, but at the end of the day, person that owns the code is responsible for reviewing changes.
- Create a source repository trigger that monitors all check-ins and specifically looks for those which are bug fixes. Make it a process so that every bug fix has a reference identifier right up front in the check-in description. Now write a script that would parse a list of files that were changed and strip out the "Author" from the file header comment block. Create a SQL database that would track # of defects checked in per file/per project/per author.
- Once you have enough statistics, hopefully you will notice that your code has fewer defects/changes than some of the other code. This is hard data you can use. If a single project has significantly above average defect rate, bring it up as a candidate for next clean-up/refactoring effort to pay back some technical debt.
- If a project or file has significantly above average defect rate and it has one owner, talk one-on-one with that person. Ask them, very politely, non-confrontationally what they can do to address this. Since they are the owner, they should drive the change, but offer any and all help from your side. Hopefully, the owner will trace a lot of the causes to their own spaghetti code and as soon as they ask for help, that's when you spring into action and lay down some SOLID.