In the last few years I worked on quite a few different projects with a variety of teams and I observed some trends and common pain points that affected most of them. This post is about some of these, some relevant stories and a few suggestions how to make more from a team of talented developers. As my projects were mostly with smaller and remote teams, I focus on these. Larger teams require very different management and have other problems, so it’s a different story.
These are purely my observations and based on my experiences. Please keep it in mind while reading.
To write tests or not to write tests?
One of the more prominent trends today is automated testing. Most of the technically minded management people have a romantic attitude on this subject, as like a holy grail of software quality. It is indeed a hot topic today and with reason, but it requires a great commitment too. Tests often require more lines of code than the actual system, contribute more to the build time than compiling, and also makes dirty quick fixes harder. These drawback are often overlooked during project planning.
Several years ago working on a project long overdue, the management sent a mail to the dev team asking to write unit tests because having them will greatly ease the work of everyone. On the other hand the specs were fragile with cursory changes, and the burn down charts were detached from reality. There were absolutely no effect of the call to testing, because no one wanted to pay the cost of doing it in an effectual way. The takeaway here is that testing needs serious commitment and only consider it if the team is embracing it.
On another instance I was working on a quite complex but isolated part of a system and decided to go the test-driven way. It was a great process, and I was able to progress at a good pace. When I finished the module, I moved on to another one for a few months. When I again needed to work on the tested code, I realized that some ‘quick fixes’ were made and my tests were mostly broken as there were no process in place that made sure that they got actually ran. So there should be some documentation how to run the tests that already exist.
One other aspect of testing is that they have to be included in the build process. One consequence is that breaking the tests should be treated like uncompilable code. This means that the HEAD commit must always be green or fixed ASAP. This is because if someone begins working on a feature, she must start from a clean state, otherwise she must also fix the bugs to make her work pass. This results in unnecessary rebasing and merging.
- First and foremost, decide whether or not the project needs automated testing. For small codebase or prototyping, it is probably more of a hindrance than an asset.
- If you go the testing route, commit to it. Have it enforced throughout the whole team.
- Document how the tests are run, how to structure them and help troubleshoot the common problems.
Communication is vital in the success of projects, and working with remote teams only amplify this. The key concept here is managing expectations between team members. Periodic status reports and setting clear deadlines on all tasks are effective ways to manage this. Another common symptom is information scarcity, when some people does not know vital infos. Using email as the primary channel can easily result in this, as people tend to misuse reply-all and it is generally not structured.
One of the most important thing is to have a clear workflow. Technically it can be anything that suits the team, but it must be clear to everyone who has to work on each task. I experienced countless times that there was a question on a ticket and it was waiting for ages before got answered, or tasks were stalled ‘in review’, just because the respondent did not thought it is her responsibility. These must be clearly indicated in the ticket, making sure nothing is stuck indefinitely.
Questions on tickets is a tricky part of the workflow, as it is often a borderline between the business and the development. First, the question should be addressed to someone, be it the ticket requester or someone else. Countless tickets got stalled with a simple question that no one felt being the one that should answer it. On the other hand, not all questions are blockers. It is essential to choose the right color for the background, but it can be changed with a single line of code, but deciding whether pages are predefined or can be added later has a fundamental effect on the architecture. From the business perspective, the two tasks does not seem to be that different, so the developer should make clear if a question is blocking the work now or at a foreseeable future, or just something that should be decided at some point of time.
On a final note on this subject, tickets from developers should be taken seriously, as they can signal more pressing problems early. At one point the client found a critical bug in their systems and the management had the whole team on exigent fixing, but that very same issue was discovered and announced by one of the developers weeks before, only to be neglected by everyone. The same holds for security findings, do not wait until the system gets breached.
- Do not use e-mails for more than 2 people.
- Have a clear workflow so that every ticket clearly indicates who needs to work on them
- Questions on tickets should be managed with the workflow. Have every question a recipient, and they should include whether it is a blocker or not
- Listen to developer tickets, as they can be an early warning.
Documentation or at least the lack of is pretty much understood in most projects. I’d cover only 3 area that took my attention for most of my projects. The first is to have a ‘how to start’ and ‘how to start developing’ docs for the codebase. Onboarding new developers are often a manual process because the lack of these docs, and others are generally afraid to migrate to a new dev environment. These docs should contain the exact steps that are needed to start the codebase and also how to effectively develop it.
The other thing I often see missing is a place where random documentations and how-tos can be placed. I often find myself in a situation when I am sure that a particular piece of information will be needed in the future, but have nowhere to write it. That said, even an unstructured central document would be a solution, as the contents can be refactored if it gets too lengthy and illegible.
Following the previous point, there should be an ideas docs too. This should be a place where random thoughts are recorded for later about what should be improved. This is just a collection of ideas that may be discarded later, but they might be a good starting point when planning the next or a refactored version of the system. Ideas are often discarded because there is no such place to record them.
- Have a ‘how to start’ document along with the codebase and keep it up-to-date.
- At least have a central document where infos regarding the codebase can be kept. It can be refactored later for a full-blown documentation, but at least have a place where developers can write such things.
- Have an ideas docs too, where random thought on how to amend the system can be put.
The last topic I cover here is about dependencies. Recently I saw more and more projects that have an awful lot of 3rd party libraries included, even when the system is still in it’s infancy and have only a few features. There is a blurred line between a well justified and a superfluous dependency, and this makes this matter hard to reason about. Also every developer has favorite libraries that are auto-included (for ex. Underscore.js and Guava to name mine). On the other hand, a library that ‘might be needed in the future’ should be postponed when it’s actually needed, as these can easily result in bloatware.
For a quick takeaway:
- Have a concept on dependencies and only include what is actually needed.