I currently work as a Software Engineer in the Group (👉 actually, they are looking for people to work in this position 👈) and I have had to make many developments in all my career, so I know how a person thinks and how he feels when he finishes them.
Once a development is finished, every developer has had the following feelings…
- What laziness! Now that I’ve finished developing, I have to test the development and I have more important things to do…
- If I’ve done it carefully, I’m sure it’s fine.
Well, experience tells us that no one is good enough not to make mistakes and that there is nothing more important than proving what has been implemented.
Through this post, I’m going to teach you some techniques to implement them, comment some Java libraries (and others) and try to show you the benefits they can have; and I’m going to do it going through the mental phases that all of us developers go through. So goodbye laziness and hello unit testing!
What are the unit tests? 🧐
The first thing is to define what we must consider a unit test, if we look at Wikipedia we find… “a unit test is a way to check the correct functioning of a unit of code“.
A definition a little more “of walking around” is the elaboration of a code that allows us to check that if in a line we have to add two numbers, that this sum is correct.
Mental Phase 1: Curiosity. How can I develop unit tests? The Test Driven Development 💻
Unit tests ensure the correct functioning of the SW components. To perform them we can use techniques such as TDD (Test Driven Development).
TDD is a development technique by which the test case is first implemented and then the use case is implemented.
Let’s imagine that we have a use case that tells us if a number is even or odd, the process would be as follows: first we will implement the test cases, for that we have to think about the possible answers that we can have, in this example, we would only have two, or the number received is even or odd. So we will have to implement 2 test cases.
- Test 1: esPar(4) = true
- Test 2: esPar(7) = false
The theorists of TDD indicate that once the tests are generated, they must be executed before implementing the use case (to see what really fails), then implement the method and then re-run the test (to see that it works properly) this process is known as Red/Green.
Once I know that the method works, we must consider a possible refactoring of the implemented code (if possible) to improve performance.
It may seem a bit tedious for a developer, anyone in their right mind may wonder… why would I run something I haven’t implemented yet? Luckily, when it comes to the truth, each developer uses his own technique and these are very diverse, from implementing the use case and then the Test, or even implementing the whole application and then testing, the most important thing… don’t forget the objective, develop the test and cover all the answers.
Mental Phase 2: Interest. What is there in the technology regarding unit tests? ⚙️
With the evolution of programming languages and their libraries, the implementation of this type of testing has become much easier.
Java example 🔥
In Java there are many libraries that we can use to elaborate the unit tests:
- Mockito, Powermock, these libraries give us the possibility to simulate calls to external services (like REST services, SOAP services,…)
- H2, this dependency allows us to generate a database in memory to be able to perform “real” tests on a simulated database.
- Podam (POjo DAta Mocker), allows us to initialize Java classes with random values and thus not having to generate the object in the traditional way
All these libraries (and many more that we could mention) allow us to cover in a simulated way practically all the implemented functionality without the need to call to real environments.
Other useful tools on which we should rely would be:
- Continuous integration tools (Jenkins, Bamboo, Concourse CI, …) with these we can ensure, through these tests the proper functioning of the SW in different environments in the process of continuous integration, these tools offer the possibility of running the tests in different processes (deployment to certification, pre-production, …) ensuring that the SW that is moving continues to function properly
- Code analysis tools (Sonar) that together with the use of libraries such as jacoco allow us to analyze the code coverage and generate reports of it, and even block deployments that do not meet minimum requirements.
I just presented you with one of the biggest fears of the developers, not to pass the coverage!
Mental Phase 3: Doubt. Is it really useful? 🧠
As a developer develops applications, he or she discovers that testing is really necessary and that it provides much more than it initially appears, from detecting flaws in the approach to the code, to detecting unintended coding errors that may have occurred. As time goes by, we assume the recommendation before the obligation… and even the fear of jacoco disappears!
Even if I haven’t convinced you with all this, look at this couple of other uses:
- Although I’ve already mentioned it, an important use is to ensure that the code continues to work in the various deployments, it’s a way for us to make sure that what we’re deploying is going to work as we expect it to.
- One of the less valued uses is the regression test of a SW, either by an evolutionary or an incidence. In case of a SW modification, unit tests will guarantee that what we have touched does not break any functionality previously implemented and in case of breaking it we can act prematurely when sending the SW.
Who hasn’t been able to fix one thing and break another? With a good test set, these problems are drastically reduced.
Mental Phase 4: Acceptance. Let’s change the mentality! 🤯
In short, the fundamental thing is to change the developers’ chip, many of them today still see unit testing as an obligation, it is typical to hear the phrase:
Bah! Now I’ve got to do the test.
But do you know how much this simple test can save you?
We have to fight for that change and that unit tests are seen as a powerful tool that helps us during the whole development, and to elaborate a very complete test set that assures that our development is going to work and that every implemented line does what we expect it to do.
Now what do you say, obligation or recommendation? 🤨