
In order to create high-quality software it is very important to test it qualitatively. But testing can be quite a difficult task if your project does not have special tools that facilitate testing. I want to talk about them in more detail in this article.
Unit testing
Unit testing allows you to control the quality of software at all stages of development, you can avoid a lot of errors in the early stages of development, when it is still impossible to test the code from the outside.
If you want to use unit testing in your project, then you need to think about how you will do this at the design stage. First you need to develop the core of the application and write end-to-end tests that will check its performance.
When the kernel is ready and the first tests are working, you can add new components. First, determine how the new code should work, what the input and output data will be. Then write acceptance tests for the new component. Acceptance tests check the performance of the component as a whole. At first they will not work and even compile. Begin step by step to implement the necessary functionality, until all the tests are working.
')
At each development step, write unit tests before implementing any functionality. If suddenly after the changes in the code some tests stopped working, then do not proceed to the next changes until you have fixed the tests.
Test the interaction of components with each other using integration tests.
If your code is difficult to test using unit tests, it means that it has too many dependencies and no convenient interfaces. This code will be difficult to maintain in the future, it is necessary to refactor.
Unit testing offers many benefits. You will notice that the quality of the code will be much better. Tasks will be well decomposed, components will not be strongly interconnected. Your code will be easy to maintain and expand. You will not need to debug the code for hours to find the error - the unit test will immediately point you to the right place. By running unit tests after any changes in the code, you will always be sure that you have not broken anything. Unit testing will be especially useful if you have no testers in your team.
Interfaces for Test Automation
Testing the program manually is quite a laborious process, especially when you need to perform the same actions for different sets of input data. With this approach, it is easy to miss something and not notice, it is especially difficult to find regressions. This is where automated tests come to the rescue. There are many frameworks to automate tests. But they are good mainly for GUI testing. Using them for testing the main functionality, data processing algorithms is quite expensive and inconvenient, because the changes in the GUI will lead to changes in all tests, and it is quite difficult to write such tests. In such cases, it is necessary to separate the testing functionality from the GUI. This can be done using console commands or command line arguments.
If you have a small project, the program performs one or more actions on the data, then it is possible that you will only need to restrict yourself to the command line. At the entrance, the program will receive a file with input data and output the result of execution to the output stream, for example, to a file. For large projects with diverse functionality, you can add a parser console commands. Each team will be designed to test a particular component or behavior. The tester will be able to easily automate tests by running the program using a script with different sets of input data and comparing the result obtained with the required one.
Let's look at the console in more detail.
You are starting to develop a new component. Discuss in advance with the tester how best to test it. Let's say this is a new button, by pressing which some actions will be performed on the data. You need to test the correctness of the action and check if the button is working. No need to mix these two tests. To test the functionality, add a new console command, it should duplicate the actions that occur at the touch of a button. To test the button, write a GUI test.
Agree with the tester about how the team will look, and the format of the input and output data. The data obtained through the graphical interface and the console command must be reduced to a single form, which is fed to the input of the component under test. The result is then converted to a graphical view for display on the screen or text for output to a stream.
Thus, you will need a small number of complex tests for the GUI, and you can provide functionality testing with a large number of simple text tests. With changes in the graphical interface you do not need to change the tests for functionality.
Asserts
Asserts are checks that give an error value in debug mode. Use assertions to validate the input and return values. Normally, assertions should never work. The most common cases where it is necessary to add an assertion is to check the correctness of the index, a check for NULL or a null value, an unintended value for the switch.
Dumps and logs
Write dumps to check intermediate data structure states and logs to check the correctness of the program execution. They allow you to quickly determine at what stage the error occurred. Provide startup modes that will include a log or dump of the module under test, for example, it can also be console commands.
Discuss all points with the tester
The most important thing is to discuss everything you do with the tester. Together decide how the program should work to avoid ambiguities. Consider how you will test your application before writing code. Tools for testing should be initially incorporated into the architecture. Discuss exactly what tools you need to implement. Do not be lazy to do this, then the work of the tester will become more efficient, and the product will be of higher quality.
Successful development.