Many people believe that software quality should be based on testing the code delivered by each developer but we at Paradigma think this is not correct. Quality is built up from the earliest stages and should not be ignored in any phase – until the last day of the project.
If we were to ask people working for many companies that boast about the quality of their products, they probably would not know what to tell us about what they really do to work on that quality.
Paradigma not only encourages us to work with the latest technologies but also us to do so striving to achieve more quality at all times.
That is why we at the QA team have defined 6 key points that help us turn our projects into success cases.
Defining the requirements
This is the first step in any development project. It is when we define what we want to achieve and why.
At Paradigma we endorse using the so-called “Sprint 0”. It is a phase prior to the project that allows us to identify the objectives and reduce the uncertainty with regard to the scope.
Thanks to it we can produce everything we need to start working according to an agile approach.
Regardless of whether there is a “Sprint 0” phase or not, we nevertheless work together with the Product Owner to set the requirements during all sprints. This will help us to:
- Detect and define stranger cases.
- View requirements from more technical perspective.
- Detect and clear any doubts and obstacles before the development phase.
One of the problems that I have run into in my past work is that requirements often have vague definitions which later take form during the sprint.
Requirements must be clear and not have open-ended definitions that might create doubt. Failure to do so can lead to misunderstandings during development and end up causing bugs and faults at both the code and the functional level.
There are techniques that can help us with this; BDD (Behaviour Driven Development), which consists in defining functionalities in a common language for both the business and the development team, stands out among them.
This is commonly achieved by coming up with examples in each functionality and its different cases, which makes them easier to understand by people in any area.
Bear in mind that in agile, all teams must work with a DOR (Definition Of Ready), ie the collection of minimum requirements that a backlog task has to meet before it can be added in a Sprint. One of these requirements could be: “The acceptance criteria are clearly defined and have been validated by the PO.”
Given the size of today’s applications, it is virtually impossible to manually test an entire application after every code change. This is why manual testing is usually reserved for testing new developments.
This often leads to mistakes, as a simple change can affect many parts of our code that might not be necessarily directly related to that change.
Manual tests help and are sometimes necessary, but it is much more important to have good automated testing coverage. For example, at Paradigma we work with a SonarQube Quality Gate that does not allow us to upload code with a code coverage percentage below 65%, although we recommend working with a percentage greater than 80%.
Automated tests guarantee both the new development, which has been covered by new tests, and past developments, which already had their own, will work perfectly. All with a much shorter runtime than when they are done by hand.
The number of automated tests notwithstanding, it should be stressed that they must be well developed and make sense. Before we sit down to develop them, we must stop and think about the flows we want and must cover.
A lot of times we work to expand the coverage of tests – but greater coverage not always guarantee that you will end up a product that is less prone to bugs.
To help us with this, there are techniques such as TDD (Test-Driven Development). It is a practice that consists in writing the tests first and then writing the source code in order for it to be able to pass them with flying colours.
Developing automatic flows
There is a lot of information on the Internet about continuous integration (CI) flows, but what do they really do for us? How can they help us to prevent bugs?
When we development our products we must have as many phases automated as possible, such as:
- Code analysis
- Code delivery
The number of phases will depend on the project’s technical needs and characteristics.
Having a complete automated flow ranging from the creation or approval of a merge request to deployment in the appropriate environment has the following advantages:
Cutting down times
When everything is automated, everything flows much faster. We do not need wait for a person who may be busy when we need them the most to perform a manual step.
This is important, because any time we save is time that we can spend doing other tasks that can contribute toward reaching the goal.
Avoiding unstable environments and configurations
If every team member had to perform these tasks manually, they would end up doing them differently, in different environments and possibly with different configurations.
Manual steps can result in false positives in some phase and make us think that we have everything under control when this is not the case.
The ideal thing is to have automated flows that raise Docker instances every time they are run. These instances are always raised according to the same configurations, variables, versions, etc., which gives us great stability and prevents potential bugs to go undetected owing to “failures” in local environments.
It is often said that there are two types of code – code that works and code that does not – but this is not true. At the very least, it could be said that there is good code and bad code. Code not only has to work properly. It also has to be of quality to avoid having bugs in the future.
In order to achieve this, we must work on aspects such as duplicate code, dead code, coding standards, cyclomatic complexity, comments and so on.
We at the QA team are in charge of managing SonarQube. This is the main tool that development teams use to analyze their code. With it we can check, among many other things, the aspects mentioned above.
In SonarQube we have quality profiles for different languages that have been defined and reviewed by members of different areas, such as QA or Architecture. Thanks to it, we can make sure that the rules that have been assigned to each language have been analysed and validated.
At Paradigma we are highly committed to SonarQube and we organize workshops, meetups and seminars about it all the time.
Meeting the deadlines
Irrespective of their importance on their own, the above aspects have one thing in common. They all require a level of dedication that must be observed from the first to the last minute.
In my opinion, time cuts are the main enemy of a quality product because they create a lot of problems and bugs during the different phases.
The time-quality ratio is something that can be extrapolated to any sphere of our lives. If you do something quickly, you will probably end up with a worse result than otherwise.
You might even end up spending more time fixing the errors you made by being hasty. All this can be avoided if you devote the necessary time to it from the very first moment.
Quality is everybody’s responsibility
If you have read this far down, you have surely thought about the QA manager role – but this is a very common mistake. It is true that the QA manager is the visible face when we talk about the quality of a project, but things are different in reality. Each and every team member is responsible for quality.
Some companies work with a quality team that is external to the development team. This team gets involved at a later stage, which is contrary to what I said before. The best thing to do is for the whole team to feel responsible for quality throughout the development process and focus on trying to prevent and avoid mistakes instead of trying to find them.
We have already talked on the blog about the consequences of teams not feeling involved in quality throughout the process and how large corporations such as NASA, Microsoft and Amazon have suffered serious consequences as a result of errors that could have been prevented.
Preventing and finding them in pre-production phases is essential and necessary, since failing to do so can lead to disastrous consequences. These consequences can range from the loss of millions of euros to the loss of human lives.
Talking about products with zero bugs might seem like an exaggeration. No matter whether we achieve perfection or not, these 6 key things I have talked about will help us – a lot – to get closer to our goal.
“Quality is never an accident. It is always the result of intelligent effort.” John Ruskin