Software projects differ, obstacles don’t – five key ways of tackling the most common issues

I’ve been working for Reaktor for almost six years. During that time I’ve taken part in numerous projects. In a way, projects are always as unique as the customer and industry; the overall look and feel of the end results are usually different as well.

However, there are more similarities than one might think of – especially when it comes to obstacles that software developers bump into in their daily tasks. Fortunately, there are ways to tackle these common problems – here’s my top-five.

1. Keep power and responsibility in your own hands

When starting a project, I always have a hunch about the risks that it might include. Knowing the magnitude of each risk helps the team prioritize tasks. For example, there might be risks that could well jeopardize the whole project, and there’s no point in continuing the work before the team is absolutely sure that these risks are taken care of.

Integration points are commonly seen as risks: it’s hard to estimate the amount of work of the implementation when you’re not in control of all the variables. The number of integration points is directly proportional to the number of possible errors. In addition to common programming errors, integrations make errors in communication possible. Fixing these errors is not only difficult but also very time consuming.

The fact is that integrations can’t always be avoided. However, they can be done in a way that reduces the possibility of failure. Keep APIs simple, atomic and retryable. Avoid any magic behind the scenes. Aim for keeping power and responsibility at your end of the integration.

It’s usually easier to test your own code and fix your own bugs than the ones made by other people. And as we all know, bugs can’t be avoided since we’re only human – and humans make mistakes.

2. If it’s possible to use something differently, it will be used differently

Why? Simply because users behave differently.

A case in point: When developing an application to be used in a web browser, every possible way to use the software is going to be used. Separate tabs, windows, ad-blockers – you name it.

You don’t have to support all the possible combinations, but you should be aware of their existence. For example, if the software doesn’t work without a browser’s Local Storage and the support for it can be detected with code, it’s better to tell the end-user about it rather than letting the customer service correct the misuse. Communication always improves the customer experience.

3. Test with real end users

You are blind to your own creation and you should be aware of this. If you don’t test with real end-users you are testing your behavior – and you end up developing the application for yourself.

As said before, people behave differently. Test your design and user experience in real contexts and with real customers. The logic behind this is that acting out different scenarios yourself usually results in flawed data and the real need never reveals itself. Simple.

This realization should also affect the process of choosing the right test users. Basically, choosing a heterogeneous set of users is a crucial cornerstone of any successful service.

4. Automate the things that should be automated

Automating tests should be a no-brainer, so I won’t rant about that. However, automation can and should be done in other parts of software as well. A good rule of thumb is: if you do it daily or even weekly and it can be automated, you should definitely invest in it. It’s also good to automate large scale tasks that should be done precisely and that are error-prone when done manually.

Building up environments for your software is a great example of the latter one. Environments should always be prepared and attributed in the same way in order to make results similar and process robust. And these days when software is run in cloud, setup is a large task.

To namedrop a few of the tools I’ve used: There’s Terraform to automate creation of AWS infrastructure all the way from the network configurations to the Docker containers to be run in different clusters. I’ve turned to Ansible when there has been a need for building, for example, a Continuous Integration machine (CI) from scratch. And of course, I use Jenkins as a CI machine that tests the code and builds the artifacts to be deployed to cloud.

Automation can be seen as a big investment and sometimes it is. So pick your battles and consider carefully where the value of automation surpasses the investment.

5. Keep your environments as close to production as possible

Bugs and errors are likely to occur when software is run in many environments that don’t match the production environment. For example, there could be a different test account for a payment service and different hardware wiring at the production location. Or maybe the production environment doesn’t even exist yet.

The last case happened when we were building an in-flight entertainment system for Finnair. The first new Airbus A350 was still under construction somewhere in France, and our team had to rely on mere specifications of the aircraft.

When developing software there are usually many environments. There’s your local environment running on your laptop. There might be a couple of testing environments running in the cloud. And then there’s the production environment. You can’t always match the environments completely, but you should nevertheless aim for it.

As previously discussed automation is highly useful when setting up these different environments. A good automation tool will give the developer certainty as only the parameters of these environments differ. In a nutshell, automation with a good tool will enable a more transparent developing process and in the end, result in better digital products.

Recommended content