Stories

Unit testing for nearshore software development

An insight into coding best practices.

in software development By Cedric Santos, Ruben Mateus, Ricardo Neves

What is unit testing and why is it important?

Our core value as developers is a deep commitment to quality. We take pride in our work. We don’t just deliver the requested features to our clients. We also improve software using cutting edge technologies.

At Hexis we strive for a codebase which is as clean as possible and we deliver documentation regarding any new features (as well as existing ones which we improve on). Another major thing is improving the quality of our deliverables. For that, we attack two fronts. First, we have a top-notch quality assurance team that makes sure that the final client receives the best new features. And second, we test our code.

Yes, it's a controversial topic, but we made an oath in our lives to always have code that tests our code (aka unit tests).

For us, writing and maintaining unit tests for our code is as important as testing all the features in a new car. Unit testing can be seen as testing the breaks, the throttle, the lights, the airbags, and every individual “unit” in the car to make sure that everything works as expected.

Unit testing and nearshoring

Working at a nearshore software development company like Hexis means working in an environment where everything you do must have an additional value.

Our clients trust us to be responsible for their software, so we must be able to take it to the next level. This doesn’t just mean creating a new feature. It also includes making the software more complete and operating transparently with the client. We believe that this reduces the distance in a nearshore partnership.

Why some software developers don't do unit testing

It's pretty much common sense that the quality of the software we deliver (in terms of correctness, added business value, and the developer’s peace of mind) is greatly influenced by the tests we maintain. However, some developers are still resistant to unit testing and its added value. This may be due to:

  • Arrogance: Thinking your algorithm is too tight to have a bug;
  • Lack of management: You don’t have time;
  • Carelessness: If something goes wrong you’ll fix the bug in production;
  • You don’t like unit tests.

The best way to do unit testing

Nearshoring, by nature, requires us to develop solutions in different technologies in order to meet all our clients' challenges. But whether you’re unit testing C#, Python, Java code, and independently of the unit testing frameworks or libraries, there are a few items you should always have in mind.

These are some of the fundamental points to keep as principles to make sure the unit tests you write will actually add value to your codebase instead of just adding time to refactor later (that, in case you don’t follow these principles and your unit tests are poorly written):

  • Write tests for core business logic

Certainly not the only tests you should have, but most definitely the most important unit tests that absolutely have to be written are the ones that test the core functionality of your business logic. These tests will of course differ depending on if the business is an e-commerce platform: where you’d have a test that validates that when a user finishes an order, the stock for the products ordered are decremented; and in case of a FinTech platform, you’d want to make sure the price you show to the client is correctly calculated.

  • Different types of tests are written differently

As we have different types of software testing methods (e.g. integration testing, unit testing, penetration testing, smoke testing, among others), each one of them has their own purpose. So make sure you understand the difference between them and how they should be written.

  • Travel the logical paths

Your tests should cover all scenarios and all business logic. You must aim to test the basics (what is required for the business logic to happen) and also the extremes. All the stuff that could go wrong must be tested, all the possible data input and output. Keep in mind the Murphy law - "whatever can go wrong, will go wrong”.

  • Don't aim for 100% code coverage

100% code coverage is just an indicator telling you that all of your code branches, conditions, functions, and methods are being covered by tests, but this does not mean that it is being tested correctly. Strange right? Well, the goal should be to have a 100% scenario test coverage, meaning that all the logic must be tested in order to ensure your code is resilient to different possible use cases.

  • Promote a culture of more in-depth analysis of unit tests on code review

This one can be one of the hardest things to do, since it can be so hard having the self-discipline to even write unit tests in the first place, imagine motivating a whole team to care enough about carefully reviewing written unit tests. But think about the benefits in achieving this, as you and your team will not only consider the code more carefully, but you'll also develop your unit test writing quality along the way - win-win situation!

  • Break down your code

Unit tests, in their essence, test modules, classes, and methods in isolation, although the vast majority of our modules have some dependency to other modules in order to perform their logic.

When you start understanding and accepting the importance of unit tests and apply it in all circumstances, you'll come across situations where your code is hard to test. Such situations are clear signs that your code could use a bit of breaking down in order to be easily tested and upscaled.

  • Strive for maintainable and readable tests

For many, test code doesn’t hold the same importance as the actual production code, but unit tests do bring a lot of benefits to the codebase, such as:

  • Can be used as documentation;
  • Allows for introspection of code complexity (code that requires breaking down);
  • Can also serve as proof that our code actually works before delivering it;
  • It gives you confidence that new code doesn't break existing code (Very important).

At Hexis, we do consider unit testing code with the same importance as the production code (HA, That's right! You should feel offended if you think otherwise!). So for these reasons, you should follow some best practices and recommended naming standards, in order to keep your tests in shape and not just write them to tick a box and forget about it.

Summary

At the end of any feature development we look at the unit tests as a part of our effort in developing this new feature. And this is bringing us a more readable, robust, and stable software. As a result of applying these practices we are experiencing an increasing quality in our deliverables to the client and this improves the quality of our work.

We know that there are different opinions concerning the types of software testing methods to use in order to keep your codebase the most resilient as possible. We say, do the "whatever it is” testing to make sure your software in production is not going to give you sleepless nights. This "whatever it is” testing (which should definitely become a thing!), is most of the times a combination of multiple types of tests.

Stay tuned for more info on types of software testing. Meanwhile, put these unit testing best practices into place for all your code, and live a better, calmer life...

Get in touch