Maybe you’ve ever wondered if the application you created, or that you worked with another team, is robust enough to “handle the bumps” of production.
Well, today we’re going to talk about some characteristics that in my opinion are necessary for your application, whether mobile, desktop or web, to be resilient and deliver its real value within a production environment.
In summary, what I’m going to explain is what needs to be done beyond the functions and classes that make up your code.
If there’s one thing I’ve learned in this life of development, it’s that good code without tests doesn’t exist… Almost everything I’m going to consider is summed up in tests. Of the most varied types. The recipe for a robust and resilient application is the creation of tests.
For this we have numerous types. From behavioral, which simulate the use of a user, beta version tests, which use real users to discover bugs, integration, resilience or capacity tests.
The first ones to be done are unit tests. As a developer, these are your best friends to guide development. What would be unit tests or unit tests? As the name says… they test only ONE thing. If the function adds a value to another, the test for this will only check if the function returns 6 when the parameters are 2 and 4. Or that it returns 7 if the parameters are 1, 2 and 4, and so on.
def sum(a, b, *args): total = a + b for i in args: total += i return total def test_sum_two_values(): assert sum(4, 2) == 6 print("test with two values passed") def test_sum_three_values(): assert sum(3, 2, 2) == 7 print("test with three values passed") if name == "main": test_sum_two_values() test_sum_three_values()
Of course, this is a very simple example, some functions require more complex logic and paths, involving other functions. For this, there are some techniques such as mock, fixtures or factories.
The unit test is the basis for TDD. It is the minimum to be delivered when developing any code. It is the most basic test of development. It is the factory floor, the one that is side by side when you are developing.
Integration tests are one level above the unit test. They have the purpose of checking some components more unitedly, already starting to stop caring about the “HOW” and looking more at “WHAT” the component does. In other words and doing justice to its own name, they test INTEGRATION between methods.
I usually use integration tests to check API queries, for example. I test to verify if the API queries have an expected return.
Notice that in this case, the integration test doesn’t worry about what happens inside the API system and instead cares about its response and its behavior.
End-to-end testing is another important test. It is the third one I consider in the development pipeline. It usually runs in a staging environment.
End-to-end testing is a simulation of a user on the platform. For example, if my application is a platform for scheduling medical appointments. The end-to-end test will simulate a user entering the website, registering, verifying the email and scheduling a time.
One of the tools that can be used for this is Selenium.
This pyramid is a way of seeing the stack of tests. Unit tests are the foundation of your development and are done in greater quantity. Ideally, you should have one or more tests for each function, testing all possible values and the expected response of the function.
Integration tests are in smaller quantity than unit tests. Because they involve the relationship between objects and methods, they do not need to be as granular as unit tests.
Finally, the end-to-end or end-to-end tests are the top of the pyramid, as they analyze the application as a whole. And of course, it has the smallest granularity of all.
Now you may ask, but who does all of this is the developer?
And I’ll tell you, IT DEPENDS! Of course, the most obvious answer. But it depends on the composition of your team.
If the team is small, it may be that everyone is responsible for all tests. But it is common that when the application grows, some people become dedicated to testing. These are professionals we call Quality Assurance. Or more commonly known as QA analysts.
They are the professionals who create the conditions and requirements for the application.
In addition to the tests I mentioned, there are some other tests that are part of a development pipeline.
Stress tests check how much your application can handle in requests.
Penetration tests, or pentests for short, serve to check for data vulnerabilities in your application, which can be found by a malicious person and cause damage, such as stealing and/or deleting important and confidential data or crashing applications, modifying systems, diverting access, etc. The sky is the limit for malice.
You may have heard some terms of blackbox and whitebox testing.
Blackbox or blackbox testing is originally used in airplanes. They carry information inside a robust box called a blackbox. As you don’t know what’s inside, this term became known as something that you know works, but don’t know how it works on the inside. Like a car engine, for example.
You know how to turn it on and operate it, however, you don’t know how things work inside the engine.
So, back to testing, Blackbox testing is when you don’t know how the application works, but check WHAT it returns. I consider blackbox testing starting from end-to-end testing and depending on the tests, integration testing.
Whitebox testing is when you know what’s inside the application. You test HOW your application processes the information.
Knowing this testing pyramid makes it easier for you to discuss the development pipeline with your team.
Do you have any questions? Leave them in the comments. Was there a test that I didn’t mention? Leave it in the comments.