software unit testing

Purpose and significance of unit testing

For unofficial software (which is characterized by relatively few functions, and no new features will be added in the future, and no maintenance is required), we can use debug to perform single-step execution, memory modification, and check whether the corresponding observation points meet the requirements for unit testing. This method is faster and more convenient to use. If you use a unit test framework to write unit test case tests, the efficiency is very low.
However, for formal commercial software, it often has a large number of features. Using agile development will go through multiple iterations, and new features will be added in each iteration. And after the release, we will often receive user needs and carry out incremental development of features. How to ensure that newly added features and problem modifications will not affect existing features. At this time, it is more useful to write unit test cases.

First of all, unit testing can ensure code quality. Through unit testing, not only can the normal function of the function be tested, but also some abnormal scenarios that are difficult to construct during system testing can be covered. Effectively guarantee code quality.
Second, ensure the maintainability and scalability of the code. Write unit test cases for each feature change, so that the unit test cases will cover all features, so that subsequent code refactoring and optimization, as well as the addition of new feature codes, can observe the impact on old features.
In Test-Driven Development (TDD), you can consider writing unit test code before writing formal code, which can ensure the completeness of functions and better optimize the code structure.

Unit testing ideas and methods

The time the unit test started

In the process of software development, unit testing and coding belong to the implementation stage. Before dynamic unit testing, static analysis (such as PCLint, etc.) and code review should be performed on the program.
Because the use of dynamic testing technology requires the preparation of test cases, the recording and analysis of results, the workload is heavy, and the efficiency of dynamic testing will be reduced if too many errors are found; therefore, using static analysis and code review technology first can give full play to the advantages of human judgment and thinking , to detect errors that are difficult for machines to find. Typically, it includes the consistency of code and design specifications, and the correctness of code logic expressions. Once an error is found, the nature and location of the error are known, and the debugging cost is low;

Structure of unit test code

Unit testing is generally a function-level test, testing the input and output of the purpose function, and checking whether the corresponding output meets the expected value under a specific input situation. Its input may be the parameters of the function, or it may be the data obtained from other modules in the function. The output of a function may be a return value, output parameters, or data provided to other modules.

Since the unit test is aimed at the program unit, and the program unit is not an independently runnable program, it often requires the system API, or other modules to provide dynamic libraries or network communication support. Therefore, when considering the test module, it must also be considered. Connections with other modules, using some auxiliary modules to simulate other modules associated with the module under test.
Therefore, the unit test code structure is divided into two types. One is the stub code, which simulates the code of other modules. The stub code can provide information such as function interface and initialization data for simulating the external module interface. The other is the test code. The test code observes whether the result meets the expectation by calling the function under test.
If you find that when testing a function, you need to do a lot of stub code to simulate the input, or you need to check the information in other modules when checking the output, it means that the coupling of the corresponding function is too high, and you need to consider adding The function of the corresponding function is separated from other modules. The data provided by other modules is input as the parameter of the function, and the function parameter or return value outputs the result. Other modules obtain the corresponding data from outside the function.
Officially released code structure
insert image description here
Unit test code structure
insert image description here
The unit test code needs to be isolated from the released code, the released code cannot be polluted, and the released code cannot be filled with a large number of unit test codes. This will not only make it difficult for subsequent code development and maintenance personnel to understand unit test cases , and it is easy to cause the unit code to be wrongly called in the release version, resulting in abnormal function. Generally, you can add a new unit test project and use the project's compilation macro to control different header files to achieve the isolation effect.

Design of unit test cases

The idea of ​​unit test case design can be carried out from two aspects. One is related to function realization, that is, to design from the outside, considering what functions the corresponding modules need to realize, and what input and output each function will have. To achieve functional coverage, it can be done before and after the release code is written. The other is internal logic correlation, that is, consider internally, design from the logical branch of the released code, and achieve branch coverage. After the release code is written.
When testing a certain unit, the following steps can be carried out according to the priority:
the first step is to design basic functional test cases, and check that the unit under test can return the expected results at least at the required function level;
the second step is to design functional positive test cases , check that the unit under test needs to return the expected result for the correct input of the design requirements; the
third step is to design a functional negative test case, check that the unit under test needs to return the expected result for the wrong input of the design requirements;
the last step is to design a performance test case, check the tested The execution efficiency of the unit in the case of large amounts of data.

The purpose of unit testing is to test the function of the function, so it is not necessary to test all the functions during the test, it needs to be selected. If there is a relatively complex logic code in the corresponding function, it must be tested. If there is basically nothing in the function logic, there is no need to test.
When writing test code, you need to pay attention to the maintainability and readability of the code. For recurring code, such as constructing the initial environment, try to extract routine functions or macros, and try to encapsulate a certain test into a statement. Add comment information when necessary, and try to know from the unit test code what feature to test and what the input and output of the corresponding feature are.

Unit testing cost and efficiency

Unit testing inevitably increases the workload of development, but by definition, unit testing only tests the functionality of the program unit itself. Therefore, it cannot find integration bugs, performance problems, or other system-level problems. Unit tests can only show detected problems, not the absence of untested bugs. So unit testing cannot replace the work of system testing.
The significance of unit testing lies in the testing of abnormal functions and the guarantee of subsequent code maintenance and development.

Supongo que te gusta

Origin blog.csdn.net/p309654858/article/details/132145094
Recomendado
Clasificación