You know you’re doing it. You know your development, test, and deployment practices are in serious need of repair, but you think you’re getting away with it because no one is calling you out. Well, my apologies in advance because that’s what I’m doing. Your DevTest and DevOps practices are bad. Don’t believe me? Here are 4 DevTest/DevOps practices that are keeping you from being the best you can be, (as well as some things you can do to break these bad habits).
1. You check in code that breaks the app (no unit tests).
Every bad practice has a reasonable explanation. One of the most common bad practices is checking in code that breaks the app. I suspect it’s rare to find a developer who proactively chooses to check in code that will break the app, but unless you have unit tests, the odds increase, regardless of your local machine testing. You can reduce this likely hood if you have highly decoupled code and a suite of unit tests that validate functionality.
So, why would someone not have unit tests? The most common answers I hear are “there’s not enough time”, “it’s expensive to maintain”, and “our application is too complex”. What folks need to understand however is if you have well-architected, highly decoupled code that is covered by unit tests, then you’ll save time in bug repairs and regression testing. Plus, it’s much easier and more cost effective to maintain the unit tests when your code is highly decoupled.
Adding unit tests is not an easy proposition, and neither is re-architecting your code. But until you take the time to do it, you will continue to have the same problems, and you will continue to bear the cost that a tightly-coupled architecture brings you.
We have found that making a mindful choice to include unit tests has forced us to be proactive about writing decoupled code. This type of architecture gave us the side benefit of letting us redesign portions of our application when we discovered we’d gone down the wrong path, and we could do so without having to rewrite the entire application.
2. You use branches to manage deployments.
This is my own rookie mistake. Many years back I chose to map my branches to the environments they deploy to. In essence I had a dev branch, a QA branch, a UAT branch, and a prod branch. I even created an Archive branch where the master releases would go. The problem with this model is that I would build off each of these branches and push the build to the corresponding environment. This essentially meant that I rebuilt code for each environment, resulting in a code base for each environment, which is not necessarily a clone of the other branches.
I suspect you may be thinking, “if each branch comes from the previous branch, (Dev to QA to UAT to Prod), then wouldn’t the code be the same?” The answer to that is deceiving. Yes, the code would be the same, but building off of two different code bases does not necessarily result in the same bits in the final build. At least not with managed code such as C# or VB.NET. Each time you run a build, the compiler will build in an order that will be determined at the time of build and may not be consistent from build to build. It is dependent on the file system and the order in which the files are given to the compiler. In other words, a singular code base could compile differently from build to build, resulting in different binaries, even if the differences are limited to a timestamp in the meta data.
With this in mind, rebuilding your code for each environment could result in differing binaries, and you don’t want to do this. Instead, you should be deploying a single package into an environment, evaluating whether it passes its acceptance criteria for that environment, and then promoting that same package into the next environment. That’s a far better practice and will help contribute to a higher-quality QA process.
3. You need to manually configure your environment.
Are you manually configuring the individual components for an environment? If so, you’re wasting time. Are you manually deploying or configuring your databases each time you are about to deploy to an environment? If so, you are wasting time. Are you waiting on operations for days at a time to get a new environment provisioned? I won’t say you’re wasting time, but I will say that there are more efficient ways to do it.
If you want to improve your DevTest practices you should start with automation. Manual practices result in errors. You know this, so why are you still doing it? The most frequent response I hear is, “we don’t have time”, followed by “we don’t know how”. If you put time into automating, you will be saving time in the long run. (You know this as well.) It’s time to start automating!
Start with using your MSDN subscription and take advantage of Azure VM’s. It’s really easy and there are some fantastic guides to help you get started. Then start using PowerShell to automate the provisioning of new environments. After you figure that out, start using the Desired State Configuration to make sure that the environments are configured with the right components. Configuration as code is your key to happiness. Whether it’s using PowerShell, DSC, Chef, Puppet, or some other tool, automated provisioning and configuring of environments will make your life easier.
4. You need to manually deploy your app.
This one may seem obvious, but the fact is, most companies we work with do not use an automated release management tool. Most release management and deployments use at least some manual intervention. Manually deploying an app has the same issues that manually configuring an environment has. If you manually deploy something, you’re more likely to introduce errors. And the more complex the deployment, the more likely the error. It’s time to automate the deployment.
Microsoft offers Release Management, and there are other tools out there to support your deployments. First, start with using an automated build practice. Team Foundation Server offers a great tool for automated builds, and there are others too! Then use a release management tool to deploy the application to the right environment.
Configuration of a release management tool may seem daunting at first, but if you have a build team, it’s likely that they’d love to learn a new tool that will make their lives easier!
If any of these practices are familiar to you, then it’s time you take a closer look at your business priorities. Addressing even one of these practices will result in a noticeable improvement on the quality of your deliveries, whether by reducing the potential for errors, or by reducing the potential for introducing bugs. Now is the time to take a serious look at your DevTest practices!