Abstract: Unit testing is the basis of software testing. This article discusses in detail the two steps of unit testing, manual static inspection and dynamic execution, the work items to be executed and related strategies and methods.
How to conduct unit testing with white box testing method, keywords: unit testing, manual inspection, white box testing, test cases, debugging

1 Overview

Unit testing is the testing work to check the correctness of the smallest unit of software design - the program module. Its purpose is to find possible errors inside each program module.

Unit testing is also a basic responsibility of programmers. Programmers must maintain a serious and responsible attitude towards the code they write, which is also one of the basic professional qualities of programmers. At the same time, unit testing ability is also a basic ability of programmers, and the level of ability directly affects the work efficiency of programmers and the quality of software.

The cost of unit testing during coding is minimal, and the rewards are particularly generous. Thinking about testing as you code will result in better code, because that’s when you know best what it’s supposed to do. If you don’t do this and wait until a module crashes, by then you may have forgotten how the code works. Even under intense work pressure, you have to figure it out all over again, which again takes a lot of time. Further, the corrections made in this way tend to be less thorough and may be more fragile because the understanding you recall may not be as complete.

Usually qualified code should have the following properties: correctness, clarity, normativeness, consistency, efficiency, etc. (sorted according to priority).

  1. Correctness means that the code logic must be correct and be able to achieve the expected functions.
  2. Clarity means that the code must be concise and easy to understand, and the comments must be accurate and unambiguous.
  3. Normativeness means that the code must conform to the common specifications defined by the enterprise or department, including naming rules, code style, etc.
  4. Consistency means that the code must maintain unity in naming (for example, variables with the same function use the same identifier as much as possible) and in style.
  5. Efficiency means that the code must not only meet the above properties, but also need to reduce the execution time of the code as much as possible.

2 unit test steps

After the code is written, the unit testing work is mainly divided into two steps: manual static inspection and dynamic execution.

Manual static inspection is the first step of testing. The work at this stage mainly focuses on the logical correctness of the code algorithm (try to find logical errors in the code through manual inspection), clarity, standardization, consistency, and algorithm efficiency. And try to find errors that are not found in the program.

The second step is to find errors by designing test cases and executing the program under test to compare the actual results with the expected results. Experience has shown that 30% to 70% of logic design and coding errors can be effectively found using manual static inspection. However, there will still be a large number of hidden errors in the code that cannot be found through visual inspection, and must be carefully analyzed through debugging methods to catch them. Therefore, the dynamic debugging method has become the focus and difficulty of unit testing.

3 manual inspection

Normally during the manual inspection phase the activities of the following items must be performed:

First, check the logical correctness of the algorithm; determine whether the written code algorithm and data structure definition (such as: queue, stack, etc.) have realized the functions required by the module or method.

Second, check the correctness of the module interface; determine whether the number, data type, and order of formal parameters are correct; determine the return value type and the correctness of the return value.

Third, whether the input parameters have been checked for correctness; if no correctness check has been done, check whether the parameter is correct or not, otherwise, please add a correctness check for the parameters. Experience has shown that code lacking parameter correctness checks is one of the main causes of software system instability.

Fourth, call the correctness of the interface of other methods; check whether the type of the actual parameter is correct, whether the value of the parameter passed in is correct or not, and whether the number is correct or not, especially the method with polymorphism. Whether the return value is correct or not, there is no meaning indicated by the return value. It is best to check the correctness of the return value of each called method with explicit codes. If the called method has an exception or an error program, feedback should be given, and appropriate error handling codes should be added.

Fifth, error handling; the module code requires that the error conditions can be foreseen, and appropriate error handling should be set, so that once the program fails, the error program can be redone. For the correctness of its logic, this kind of error handling should be part of the module function. If any of the following situations occurs, it indicates that the error handling function of the module contains errors or defects: the description of the error is difficult to understand; the description of the error is not enough to locate the error or determine the cause of the error; The reason does not match; the handling of the error condition is not correct; the error condition has caused the intervention of the system before the error is handled, etc.

Sixth, the correctness of expressions and SQL statements; check the correctness of the syntax and logic of the written SQL statements. There should be no ambiguity in the expression. For expressions or operator priorities that are prone to ambiguity (such as: “, =, “, &&, , ++, –, etc.), you can use the expansion mark “()” operation Symbols avoid ambiguity, so that on the one hand, the code can be correct and reliable, and at the same time, it can also improve the readability of the code.

Seventh, check the correctness of the use of constants or global variables; determine the value, value, and data type of the constant or global variable used; the consistency of each reference to a constant with its value, value, and type.

Eighth, the standard consistency of the indicator definition; variable naming can be understood by the name, and concise but should not be too long or too short, standardized, easy to remember, and preferably spellable. And try to use the same symbol to represent the same function, do not use the same symbol to represent different functions; let alone use the same symbol to represent different functional meanings.

Ninth, the consistency and standardization of the program style; the code must conform to the enterprise specification, and all the code styles are consistent, standardized and neat. For example, when looping an array, don’t use the method of subscripting variables from bottom to top (such as: for(I=0;I++;I<10)) for a while, and then use the method from top to bottom (such as: for(I =10;I–;I>0)); Should try to adopt a unified way, or unified from bottom to top, or unified from top to bottom. Use for loops and While loops, do not use do{}while loops, etc.

Tenth, check whether the mysterious numbers used in the program are defined by symbols. Mysterious numbers include various, array sizes, characters, conversion factors, and other literal values ​​that appear in programs. In program source code, a number in its original form does not provide any information about its own significance or role, and they also make the program difficult to understand and modify. For this kind of mysterious number, the corresponding scalar must be used to represent it; if the number may be used throughout the system, it must be defined as a global constant; if the mysterious number is used in a class, it can be defined as an attribute of the class ( Attribute), if the mysterious number only appears in one method, be sure to define it as a local variable or constant.

Eleventh, check whether the code can be optimized and whether the algorithm efficiency is the highest. For example: whether the SQL statement can be optimized, whether the function of multiple SQL statements in the program can be replaced by one SQL statement, whether the loop is necessary, whether the statement in the loop can be extracted outside the loop, etc.

Twelfth, check whether your program is clear, concise and easy to understand. Note: lengthy procedures are not necessarily ambiguous.
Thirteenth, check whether the internal annotations of the method are complete; whether they are clear and clean; whether they correctly reflect the function of the code, wrong annotations are worse than no annotations; whether there are many redundant annotations; you can understand the simple ones at a glance The code does not have to be commented.

Fourteenth, check whether the annotation document is complete; whether the annotations on packages, classes, attributes, functions, parameters, and return values ​​are correct and easy to understand; whether there will be missing or more annotations for a certain parameter, whether the parameter type is correct, Whether the limit value of the parameter is correct. Especially for annotations about mysterious values ​​in shape parameters and return values, such as: type parameters should indicate what 1. represents, 2. represents, 3. represents, etc. For the annotation of the returned result set (ResultSet), it should be noted which word segments are included in the result set, the type of word segment, the order of word segments, etc.

Link: https://juejin.cn/post/6844904192381812743
Source: Rare Earth Nuggets