DEV Community

Andrzej Karaś
Andrzej Karaś

Posted on • Originally published at karas.codes on

How to break down your app? A short guide.

Let's take some imaginary enterprise or SaaS application which helps to solve many use cases. In this article, we will think, about how a lack of testing and couple other behaviours could impact such applications.

I. Writing code without implementing unit tests along

If you want your app to be crashing after every release, don't implement unit tests! For sure, you saw some cases where your system was failing on production because of a bug that could be discovered on the unit tests level.

Also, keep doing it for a couple of months or years. That will lead you to the situation where you are scared of changing anything in your app because it could break aby other modules :)

Objections on implementing unit tests

Let's be clear that we are considering a production ready app here. The biggest objections about writing tests are:

  1. It consumes time
  2. Development team needs to maintain it along with changes
  3. It's hard to implement them when dealing with legacy code
  4. "It can't be unit tested"

Answers

Let's break down all the objections.

1. Not implementing unit tests also costs time

Not implementing unit tests cost even more in the long term, and we want to maintain our applications as long as possible, no (when we're having revenue of course)? Solving bugs in an app without tests costs us: developer time (money), customer frustration (money), and support teamwork (money), sometimes bugs could e.g. increase infrastructure usage - which also generates costs. When fighting with bugs we can't work on new features at the same time, so it takes also our time.

2. You could do it way easier to maintain

Referring to the previous point, from my perspective maintaining well-written unit tests is easy to maintain and costs less than buggy applications.

3. Implementing unit tests will help you fix bugs and understand your application more

When you are in that place, and you are dealing with e.g. buggy feature you have two options:

  • try to fix without implementing unit tests
  • gather functional requirements, understand them, plan solutions from a technical perspective, implement unit tests for an API that solves it, implement code

The second solution allows you to understand the root of problems, prepare a correct solution for it and cover it with tests that would be working as a guard for the future. Such an approach is paying a lot in the future. I was doing that many times when working on legacy code.

Also, correctly written unit tests would work as documentation that is maintainable and resides very close to the source code.

4. "You can't unit test it properly"

Yes, this is the hard truth. Every piece of code could be unit tested in a proper way. But first, you need to learn how to:

  • decouple technical parts from business logic, because in most cases we want to cover the latter one-by-unit tests
  • separating things on many levels: single method, class, package, module, application, and infrastructure. Thanks to that you could focus on one problem at a time. This is very helpful when fighting some serious bugs - you are making them easier to spot! And at the end of the day that saves you a lot of time.

II. Pushing changes to the dev or master branch without manual (or any other tests)

I was seeing such situations many times. Developer X is finishing his code, committing everything, and pushing to production. After some time (we need to wait for CI/CD and instances rollout) we have a "fire on production" and no one knows what's happening.

The worst thing in those situations is when you need to solve that problem instead of so-called Developer X because they did not spot it or they did not want to.

Solution

I don't understand why developers act like that. I don't care. It's a very bad habit.

So my approach is simple. Try to separate from such developers or at least take away push permissions from them :)

III. Don't think about how your changes would impact anything or anyone

Unfortunately, the team I worked on was in that situation many times.

When you work in a big company, you could have multiple developer teams even though you all work on the same app

This leads to a couple of problems, (especially when working on the legacy app):

  • changes in app A could impact app B e.g. on performance, functional or security level
  • when the code is not correctly maintained you could waste much more time on solving merge conflicts
  • when you are using mono repo and your code is not correctly separated then teams could code dependencies that shouldn't be possible
  • when access to the projects is not restricted, anyone could change anything in your core module...

Also, every team could have:

  • a different approach to solving problems
  • a different opinion on testing things
  • a different process of delivering things to production
  • a different velocity for delivering changes
  • different skill levels

Everything adds up to one conclusion.

Divide & Conquer

When you apply that simple rule on code, infrastructure, and teams/company level you will get to the one important point. Developer teams won't be influencing each other.

Giving teams extreme ownership of the app they develop will pay off, you can try that. Developers are not stupid, they won't be doing things that would break an app they develop - or this is only my opinion?

IV. Don't care who is leading your development teams

I know, that I wrote above that teams should have ownership and freedom in developing the app they maintain. But you need to strictly check who leads your teams.

One simple hint

I heard somewhere one saying. 'When you have bad workers in a management place, then good workers will start leaving the company.'

I saw a couple of times e.g. when working on consulting company how someone who doesn't know how to lead the project could crash it in a second.

I am not telling that I know everything about project management. But I just want to show what you should avoid in your work.

Observation

When you have a skilled team of people, who do care about code quality, apps they develop, and are IT enthusiasts (and don't get up to work as punishment). Then you don't have anyone above them - especially the manager that would be assigned tasks. Such people would organize the team internally, you just need to show them the long-term goal(s) you want to achieve.

V. Don't try to release your changes as soon as possible

Of course, who needs that?! You can play with your code on the feature branch till the end of the world :) For sure your code would be optimized and polished as much as possible.

The problems

Such an approach leads to a couple of problems:

  • you won't get feedback from the end-users and people that make decisions (so-called business)
  • technology would go forward
  • your teammates would add a lot of changes to the code

When you're not trying to release it ASAP, then you're just wasting your time and company money. I need to clarify one thing. I am writing about things that could be precisely designed. But 99% of enterprise or SaaS applications fit into that.

VI. Don't care what're your colleagues asking for

If you are working in a company that has multiple teams - don't try to understand your colleague's needs. Who needs that? You exactly know what to do. Don't you?

Such a situation could end up in one way... You will implement or prepare a solution that nobody would be using. That's the hard truth, but even as a developer, you should be able to talk with your teammates and prepare a solution that they accept. Again, don't waste your time!

VII. Who needs code reviews? No one.

This topic is a little related to pushing changes to production without tests. But even though you are performing code reviews, you could still do it incorrectly.

I know this is a very broad topic, but short checks on what has been done without pointing out technical and business problems are a very bad approach. Also, when you do a code review, you should expect that all changes would be done or at least someone will discuss with you why something was done in that way.

VII. Documentation? My code is self-documented.

As I wrote before e.g. properly written unit tests are good at documenting our project. We need to understand all benefits that we could have from actual documentation. Especially, our new colleagues would be happy when passing the introductory stage. I know that thousands of pages are not the approach that anyone wants to take. But there is one more thing that you could use!

ADR - Architecture Design Record

There is a lot of templates for such document. In short:

  • you could store them in the same place as you store code
  • should be updated along with the code
  • explains what, how, and why would be solved
  • help us keep track history of changes and decisions that were made in the project
  • help us discover problems on a design level, which is the cheapest level ever possible

You could find examples on the internet. Maybe I will prepare a dedicated post in the future.

Summary

If you want to spoil the application you work on, please follow these steps :)

But, if you want to improve your skills and the app you work on, try to pick one thing I mentioned and deal with it in your organization.

For sure, you have some other ideas about what negatively impacts an application. You could share your thoughts on my dev.to profile. All comments are welcome.

Stay tuned!

Top comments (0)