QA Tool Stack

It is not always clear what the purpose of different technologies and layers of testing is. For example, the difference between unit testing and integration testing may be quite fuzzy, and so I want to share my view of relevant areas.
Integrated Development Environment (IDE)
IDE is your main development tool and you have a wide variety of options of free editors such as Visual Studio Code and Sublime or paid professional tools such as Microsoft Visual Studio and IntelliJ IDEA.
The advantage of a good IDE lies in the integrated tools providing a static analysis of your code that can catch early simple issues such are missing imports or calls to undefined functions. Not to mention that IDE is the integration hub of other tools that make many parts of your development easier from version control to refactoring automation.
Linting
Installation of linter tools and their use in your development process is the most basic and simple step that you can take. There are specific linting plugins for your IDE for everything from HTML to your C# code.
Basic linters govern best practices and validity of your code. For example, you can define that there should always be empty space between the name of a function and its opening bracket or that if conditions always must use curly brackets.
More advanced linting tools such as https://www.sonarlint.org also provide you static analysis that can uncover various issues with your code.
Advanced static analysis
Static analysis is a powerful tool that can show even subtle issues with your code. They can come in the form of tool in your IDE (IntelliSense in Visual Studio), linter (SonarLint) or continuous code quality service (SonarCloud).
There are plugins that can also provide code review as comments for your pull requests on GitHub or Bitbucket.
These tools simply make you write better code and even teach you development practices. They can discover that you are using weak encryption, that your method is too long or that you have an issue with separation of concerns.
Unit testing
Unit testing might be the synonym of code testing. It is worth a while to read about test-driven development and investing your time in understanding unit testing best practices about separation of units and mocking. Make your code more robust by making it testable.
However, choose the right testing technique for the right part of your system. Writing tests and learning how to design tests takes time but it makes your releases safer.
Read my post about making a testable code that highlights some common challenges and proposes how to approach them.
Integration testing
Your systems will interact with other systems, create side effects, use services and work with data. These things should be covered by integration tests and they are also where your logic is most likely to break in production.
There are different ways to tests your integrations that are based on your own technologies and you may end up developing custom code that corresponds to your dependencies. You should not be just making sure that the system works but also how it behaves when part of your environment stops working. It is better to find out what happens when your external service goes down during designing tests than finding out in production.
Behavioural testing
Behavioural tests focus on a black box of your system and it is focused on functional attributes. That means that your test does not know and does not care how your system works, instead it focuses on whether business requirements are correctly implemented.
Test automation for web application in this case typically uses Selenium based technology for your system. Your tests will open a browser and it will navigate through your site while checking the results of its actions. It cares whether if you click on a submit button and that you are shown a thank you page, but it does not care how that happens.
Behavioural tests can be combined with integration tests or play the role of integration tests. For example, your test can fill out a form in a browser and then verify submitted data in a database.
Visual testing
The problem of behavioural tests based on Selenium is that they don’t put into account the actual visuals and work directly with DOM. Your tests will pass even though the page is breaking apart and buttons are invisible. To save the day, visual tests come to play.
You can base your technology on a service such as Applitools or Storybook and support differential visual testing. Your tests will be able to verify your user interface under various resolutions and point out every time something changes between runs. It also avoids common issues coming from changing CSS classes where one change can negatively affect a different part of the application. Issues caused by CSS are hard to catch across the application and they can have a major impact on the user.
Test Coverage
Test coverage tools provide you with important information highlighting whether your team is writing tests. However, 100 % test coverage over your whole system should not be the ultimate goal as it does not relay information about the quality of these tests,
Read my post Say “No” to code coverage for these 3 reasons to find more information.
Code reviews
Code reviews should be an integral part of your development process for peer reviews that allow your developers to provide feedback to each other as well as a system to promote accountability for test coverage and documentation.
Continuous Integration
Continuous integration is a logical step towards better product quality. You have the ability to simply setup pipelines and builds to run linter tools as well as automated tests and provide quick feedback making sure that critical bugs are not making it to production. They are also crucial for the agility of your team as they allow provide iterative feedback throughout your development cycle instead of being dependent on manual testing at the end of development.
Don’t make testing an afterthought but evaluate it for every task of your development team. Don’t follow a waterfall approach where systems are developed and then we are trying to cover them by tests. Such activities are hard to estimate both the effort to write the tests as well as fix the found issues especially if the tests uncover issues in the system architecture, not just cosmetic bugs. I can again offer you my post about making testable code that discusses these challenges.






