A redundancy detection and removal method for random test generation tools
By introducing redundant detection and removal strategies for sequence similarity, test odor and test requirements into the random test tool, the redundancy problem of test cases generated by the random test tool is solved, and the effective reduction of the test suite and improvement of the test quality is achieved.
Patent Information
- Application Number
- CN202210265582.0
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Filing Date
- 2022-03-17
- Publication Date
- 2025-04-25
- Estimated Expiration
- 2042-03-17
AI Technical Summary
The random test tools generate a large number of test cases but not high quality, and there is a lot of redundancy, resulting in insufficient test coverage and error detection capabilities.
The test suite is reduced in size by detecting and removing redundant test cases based on sequence similarity and the characteristics of the method being tested, redundant removal strategies based on test odor, and redundant use case removal strategies based on test requirements.
Effectively reduce the size of the test suite, reduce testing costs, improve testing efficiency and readability, and improve test coverage and error detection capabilities.
Smart Images

Figure CN114546879B_ABST
Abstract
Description
Technical Field
[0001] The invention relates to a redundancy detection and removal method based on generation time information, test odor and test requirements for a random test generation tool, belonging to the technical field of software unit testing. Background Art
[0002] Unit testing is an essential task in the software development lifecycle. It verifies the smallest testable unit in the program and ensures the quality of the software. However, the time required for software testing often accounts for more than half of the entire software development time. Manually writing high-quality unit tests can improve development efficiency, but it is time-consuming and labor-intensive. This repetitive and inefficient task is expected to be replaced by automated unit test case generation tools. Java-based automated unit test case generation tools use different test generation methods, such as search-based testing, random-based testing, model-based testing, and test generation methods combined with symbolic execution technology. Search-based software testing uses search algorithms to optimize fitness functions and maximize test objectives, thereby automatically generating unit tests. Random test generation tools are scalable and easy to implement. They randomly select inputs from the input space of the program and check whether the program behaves correctly for each input. Symbolic execution uses symbolic values instead of specific values as input, and the output is the mathematical expression of these symbols. The use of symbolic execution technology can explore more different program paths, and the hybrid method that combines symbolic execution with test generation methods can, to a certain extent, complement the strengths of the two methods. Model-based testing relies on explicit behavioral models that encode the expected behavior of the system under test or its environment and automatically generates useful test cases. Because the test suite is derived from the model rather than the source code, this type of testing is often considered a form of black-box testing.
[0003] From the results of many empirical studies, it can be found that random testing tools (represented by Randoop) generate a large number of test cases for the tested classes, but the number of test cases is not proportional to the quality. Most test cases do not help to improve the overall coverage and error detection capabilities of the test, so there are many redundancies. Summary of the invention
[0004] Purpose of the invention: In view of the problems and shortcomings in the prior art, the present invention provides a redundancy detection and removal method for random test generation tools, mainly for the random test generation tool Randoop. At different stages of test construction, the mechanism of specific input parameters, the method of random selection and the standard for measuring test quality are combined to improve the test generation process, and different strategies are introduced to detect and remove redundancy in the process. A total of three strategies are used to achieve redundancy detection and removal, thereby reducing the size of the test suite, reducing testing costs, and improving testing efficiency and readability.
[0005] Technical solution: A redundancy detection and removal method for random test generation tools, including a priority selection strategy based on sequence similarity and the characteristics of the method being tested, a redundancy removal strategy based on test smells (repeated and useless test assertion statements), and a redundant use case removal strategy based on test requirements (including branch coverage and mutation killing). Specifically, it includes the following steps:
[0006] Step 1: The user gives the target class to be tested and obtains the corresponding unit test.
[0007] Step 2: Randoop-TSR proposed by the method of the present invention incrementally constructs a method sequence, generates a new test by combining the old tests generated previously, and provides a sequence input selection mechanism.
[0008] Step 3: Randoop-TSR executes the automatically generated method sequence, checks the execution results, and provides feedback, thereby preventing the method sequence that is known to have errors or throw exceptions from being further expanded.
[0009] Step 4: After obtaining the executable method sequence, implement the redundancy removal strategy based on test smell to detect, filter and remove duplicate and useless assertion statements.
[0010] Step 5: After obtaining the executable method sequence, the test suite is reduced by removing redundant cases based on the test requirements.
[0011] Step 6, Randoop-TSR outputs the executable method sequence before reduction as the original regression test file; outputs the executable method sequence after reduction as the reduced regression test file; outputs the unexecutable erroneous method sequence as an error-revealing test file to record potential errors in one or more tested classes.
[0012] In step 1, the user provides the name of the target class under test, the source code file and the compiled binary file, as well as the corresponding dependencies, time budget, test parameters of other characteristics, etc.; then the user runs the tool using the command line to obtain the corresponding unit test.
[0013] In step 2, Randoop-TSR incrementally builds method sequences, combines previously generated old tests to generate new tests, and provides a sequence input selection mechanism (i.e., --input-selection), which controls how to select tests from all newly generated test sequences. The default is UNIFORM pure random selection, but it is easy to cause repeated method sequences to enter the subsequent test generation process, resulting in redundancy. The priority selection strategy based on sequence similarity and the characteristics of the method being tested requires the user to provide UNDUPLICATED_TESTS as a parameter of the --input-selection instruction before running the tool, so that the content of the strategy can be executed; the specific implementation process is:
[0014] 21) The names of the methods under test (observer methods) that cannot change the state of data members in the class under test are extracted through the static analysis tool ReImInfer and saved in a file, which will be used as an input parameter later. The methods under test can be divided into methods under test that can change the state of data members (state-modifier methods) and methods under test that cannot change the state of data members (observer methods) according to their characteristics. However, if the observer method is frequently called during the test sequence generation process, many redundant long sequences and single object states will be created, resulting in redundancy and being detrimental to the overall growth of coverage.
[0015] 22) Component mapping. Randoop-TSR will continuously generate multiple newly generated method sequences as candidate method sequences, and select one from these candidate method sequences for the subsequent sequence expansion process. Component mapping needs to extract the three components that exist in each current candidate method sequence, namely: a) object type; b) name of the method under test; c) parameters and constant values. The three component contents of each extracted candidate method sequence are stored in three lists respectively, which contain the specific contents of the above components, and mark the state changer method and observer method in the called method under test.
[0016] 23) Randoop-TSR will store the corresponding three components of each method sequence selected from multiple candidate method sequences mentioned in 22) into the component pool, that is, the component pool stores the component contents of all previously selected method sequences. Compare the three components of each newly generated candidate method sequence with the contents of the three components in the component pool, calculate the dissimilarity between each method sequence component and the corresponding components of each sequence in the corresponding component pool, then weight the dissimilarity of the three components, and select the minimum weighted value as the dissimilarity result of the sequence, and then obtain the dissimilarity result D and the sequence weight value W; Score i (n) represents the dissimilarity between the current candidate method sequence and the three components of the i-th sequence in the pool. The calculation formula is as follows: the dissimilarity of the object type is recorded as Score(Object); the dissimilarity of the tested method is recorded as Score(Method). When calculating Score(Method), if the tested method that does not appear in the pool is a state changer method (represented by M modifier ), then this method is given a value that is better than the observer method (denoted as M observer ) double the score; Score(Parameter) is recorded as the dissimilarity between the parameter and the constant value; Num(Diff(n)) calculates the number of components that exist in the component list of the current candidate method sequence but not in the component pool; the corresponding weights a1, b1, and c1 are all 1 / 3 by default.
[0017] W=2 D
[0018] D=min{a1*Score(Object)+b1*Score(Method)+c1*Score(Parameter)}
[0019]
[0020] The larger the weight value, the higher the sequence dissimilarity and the lower the similarity. When the method under test called in the newly generated candidate method sequence is a state changer method and is not included in the component pool of the method under test, the state changer method is given a higher weight than the observer method.
[0021] 24) Select a sequence from multiple candidate method sequences according to a weighted random algorithm. The lower the similarity, the higher the weight and the easier it is to be selected. The three component contents in the selected sequence will be added to the corresponding component pool, and the sequence will be used for subsequent expansion and test generation processes.
[0022] In step 4, after obtaining an executable method sequence, a redundancy removal strategy based on test smell is implemented, which aims to detect, filter and remove duplicate and useless assertion statements. There are dozens of test smells in software projects. The present invention only selects the test smells (duplicate and useless assertion statements) that are most convenient and beneficial for removing the redundancy existing in the current state. Their existence may affect the quality, maintainability and scalability of the test suite. Before performing mutation testing and obtaining the reduced test suite, all duplicate assertions are filtered out first, which can achieve the effect of removing redundancy and reducing the cost of mutation testing. In addition, from the perspective of the granularity of use cases and assertion statements, even if the test suite is reduced, there will still be useless test assertions in a single use case. Giving up the output of such assertions helps to reduce the size of a single test case and improve the efficiency of testing in discovering potential faults and quality problems in project code. The specific steps of this strategy are as follows:
[0023] 41) Traverse the test assertions in all executable sequences (the executable sequence here is also the test case). If two test cases contain exactly the same assertion statements, it proves that the assertions are repeated. Therefore, the test cases containing repeated assertions can be excluded from subsequent mutation testing, thereby reducing the cost of mutation testing and removing redundancy.
[0024] 42) Detect the assertion statements in each test case. Useless assertions refer to assertion statements in the test method where the expected parameters and actual parameters are the same. Use the code analysis framework JavaParser to identify useless test assertions, and then remove useless assertion statements in each test case detected, thereby reducing the size of a single test case and removing redundancy.
[0025] In step 5, after obtaining the executable method sequence, the test suite is reduced by using a redundant case removal strategy based on the test requirements. First, the test requirements are clarified, including code coverage and mutation killing rate. Code coverage measures the proportion of the test coverage of the source code, including branch coverage, statement coverage, method coverage, instruction coverage, cyclomatic complexity coverage, etc. Among them, branch coverage is the most common measurement indicator, which is basically positively correlated with other indicators. Therefore, branch coverage is selected as the test requirement for the coverage part; the mutation killing rate reflects the proportion of mutation operators implanted in the source code that are killed by the test, reflecting the ability of the test to detect bugs, and is a test requirement of two different dimensions from the coverage rate. This strategy takes the union of the two test case subsets that meet the branch coverage and mutation killing rate respectively as the final test suite result. The goal of this strategy to achieve redundant detection and elimination is to obtain the minimum test case set that can cover the maximum test requirements while ensuring that the test requirements remain unchanged, while achieving the effect of removing useless cases and reducing the test suite. The specific steps of this strategy are as follows:
[0026] 51) Rewrite the if-else code block in the source code of the class under test, then perform branch insertion for the rewritten source code of the class under test, and number all branches during the branch insertion process.
[0027] 52) Execute each use case to obtain the branches it covers, obtain all branch numbers covered by all use cases (all branch numbers are represented by the set Br), and the branch numbers covered by each use case.
[0028] 53) Find the minimum set of use cases that can cover Br, and get the number of each use case in the minimum set of use cases. This problem can be regarded as a set covering problem and solved using the integer linear programming algorithm. Integer linear programming (ILP) is an optimization problem in which the variables are integer values and the objective function and equations are linear.
[0029] 54) Generate method-level and class-level mutants for the source code of the tested class. The types of mutants refer to the muJava tool, and the corresponding rules defined in the muJava-AUM tool are used to filter out mutations with equivalent relationships or duplications.
[0030] 55) Execute each use case to obtain the number of the mutant killed by it, obtain all the mutant numbers covered by all use cases, and the mutant numbers covered by each use case, where all the mutant numbers are represented by the set Mr.
[0031] 56) Find the minimum set of use cases that can cover Mr, and get the number of each use case in the minimum set of use cases. This problem can be regarded as a set covering problem and solved using an integer linear programming algorithm.
[0032] 57) The minimum set of use cases (denoted as S) that covers the maximum number of branches is obtained. b ) and the minimum set of use cases that kills the maximum number of mutations (denoted as S m ), and finally S b and S m Take the union to get the reduced set of test cases and output it to a file.
[0033] Compared with the prior art, the present invention has the following advantages:
[0034] (1) The present invention proposes three redundancy detection and removal strategies from different perspectives, namely sequence similarity, test requirements and test smell. These strategies can significantly reduce the size of the test suite while ensuring that the overall code coverage, variant killing rate and other indicators that measure the test quality remain basically unchanged. The reduction can be as high as more than 90%, thereby reducing the time and cost of unit testing and enhancing the readability and comprehensibility of the test suite.
[0035] (2) The present invention improves the existing popular random test generation tool Randoop, introduces a redundancy removal module in different stages of tool construction testing, adds a new parameter option to the --input-selection instruction to filter method sequences with high similarity during generation, and filters executable method sequences with repeated test requirements, as well as filtering repeated and useless assertion statements in test cases. Since the tool is executed through a command line, the user only needs to run the tool in the original way to obtain the original test file, the reduced test file, and the test file that reveals the error, which is easy to understand and operate, and is simple and efficient, thereby improving the user's work efficiency.
[0036] (3) The present invention considers two dimensions: coarse-grained (test suite) and fine-grained (single test case). At the coarse-grained level, test cases that implement non-redundant test requirements are selected to form a test suite; at the fine-grained level, redundant assertion statements in a single test case are removed; the size of a single test case is reduced, and the number of overall test cases is reduced, making redundancy removal more sufficient and comprehensive, thereby improving the quality and efficiency of unit testing. BRIEF DESCRIPTION OF THE DRAWINGS
[0037] Figure 1 The overall flow chart of Randoop-TSR test generation and redundancy removal according to an embodiment of the present invention;
[0038] Figure 2 A flowchart of a priority selection strategy based on sequence similarity and characteristics of a method under test according to an embodiment of the present invention;
[0039] Figure 3 It is a flow chart of a redundant removal strategy based on testing odor according to an embodiment of the present invention;
[0040] Figure 4 The flowchart of the redundant use case removal strategy based on test requirements in an embodiment of the present invention. DETAILED DESCRIPTION
[0041] The present invention is further explained below in conjunction with specific embodiments. It should be understood that these embodiments are only used to illustrate the present invention and are not used to limit the scope of the present invention. After reading the present invention, various equivalent forms of modifications to the present invention by those skilled in the art all fall within the scope defined by the claims attached to this application.
[0042] This embodiment provides a redundancy detection and removal method based on test requirements and generation information for a random test generation tool, which reduces the size of the test suite and improves the efficiency of unit testing.
[0043] In the first step, since the random test generation tool needs to be run using the command line, the --javafile directive option is added to provide the source code file of the class under test, and UNDUPLICATED_TESTS is added as a parameter option of the --input-selection directive to select the method sequence with the lowest similarity to the previous component pool during generation. Users need to give the name of the target class under test, the source code file and the compiled binary file in the specified format, as well as the corresponding dependencies, time budget, and other characteristic test parameters (such as the folder location used to save the output test file), etc., in order to run the tool correctly.
[0044] In the second step, Randoop-TSR continuously and incrementally generates method sequences, combining previously generated old tests to generate new tests.
[0045] In the third step, if the user provides UNDUPLICATED_TESTS as the --input-selection parameter option, a priority selection strategy based on sequence similarity and the characteristics of the method being tested will be executed, such as Figure 2 As shown. This strategy hopes to combine the characteristics of the tested method and the sequence similarity to select a sequence from multiple candidate method sequences that is the least similar to all previously selected method sequences. The sequence similarity is calculated based on the object type, the characteristics of the tested method, the parameters and the constant values. The code analysis framework JavaParser is used to build the abstract syntax tree of the code, and a sequence accessor inherited from VoidVisitorAdapter (a visitor provided by JavaParser that does not return anything and has a default implementation for all its access methods) is created. The above three components are extracted by accessing MethodCallExpr (method call to the object), StringLiteralExpr (text string), VariableDeclarator (variable declaration), ObjectCreationExpr (definition of call to the constructor), etc. The dissimilarity of the three components of each method sequence and the corresponding components of each sequence in the corresponding component pool is calculated, and then the dissimilarity of the three components is weighted, and the minimum weighted value is selected as the dissimilarity result of the sequence, and then the dissimilarity result D and the sequence weight value W are obtained; Score i (n) represents the dissimilarity between the current candidate method sequence and the three components of the i-th sequence in the pool. The calculation formula is as follows: the dissimilarity of the object type is recorded as Score(Object); the dissimilarity of the tested method is recorded as Score(Method). When calculating Score(Method), if the tested method that does not appear in the pool is a state changer method (represented by M modifier), then this method is given a value that is better than the observer method (denoted as M observer ) double the score; Score(Parameter) is recorded as the dissimilarity between the parameter and the constant value; Num(Diff(n)) calculates the number of components that exist in the component list of the current candidate method sequence but not in the component pool; the corresponding weights a1, b1, and c1 are all 1 / 3 by default.
[0046] W=2 D
[0047] D=min{a1*Score(Object)+b1*Score(Method)+c1*Score(Parameter)}
[0048]
[0049] Since calculating similarity takes a certain amount of time, and the time budget is provided by parameters, it is necessary to dynamically adjust the time budget during the process of tool construction of method sequence to weaken the impact of this step on test generation. In this step, candidate method sequences are continuously generated, and only the method sequences selected through this step will participate in subsequent expansion, executable judgment and other processes. After comparing and calculating the dissimilarity between each candidate method sequence and the content in the component pool, the corresponding weight is calculated, and the sequence with the larger weight is more likely to be selected.
[0050] In the fourth step, Randoop-TSR executes the automatically generated method sequence, checks the execution results and provides feedback, thereby building an executable method sequence.
[0051] In the fifth step, after obtaining the executable method sequence, a redundancy removal strategy based on test smell is implemented, which aims to detect, filter and remove repeated and useless assertion statements. Figure 3As shown, the assertion statements in all use cases are traversed first, and the use cases containing repeated assertions are filtered out. The remaining use cases are then involved in the subsequent mutation test based on the redundant use case removal strategy of the test requirements to reduce its cost. In addition, from the fine-grained level of a single use case, there are still useless test assertions in the use case. Useless assertions specifically refer to assertion statements in which the expected parameters and actual parameters contained in the test method are the same. The code analysis framework JavaParser is used to identify useless parts of JUnit assertions such as assertTrue (JUnit assertion type, asserting a condition is true), assertFalse (JUnit assertion type, asserting a condition is false), assertNotNull (JUnit assertion type, asserting a condition is non-null value), and assertNull (JUnit assertion type, asserting a condition is null value). For example, the following italic parts are two cases of useless assertions: org.junit.Assert.assertNotNull(null); or A_Class a1=null; org.junit.Assert.assertNotNull(a1); and then remove the useless assertions in each detected use case, thereby reducing the size of a single test case and removing redundancy.
[0052] In the sixth step, after obtaining the executable method sequence, the redundant case removal strategy based on the test requirements is used to reduce the test suite. At the same time, while ensuring that the test requirements remain unchanged, the minimum test case set that can cover the maximum test requirements is obtained, thereby achieving the effect of removing useless cases and reducing the test suite. The test requirements are branch coverage and mutation killing rate: branch coverage measures the proportion of branches covered by the test in the source code; the mutation killing rate reflects the proportion of mutation operators implanted in the source code that are killed by the test, reflecting the ability of the test to detect bugs. This strategy takes the union of the two test case subsets that meet the branch coverage and mutation killing rate respectively as the final test suite result. Figure 4 The specific steps of this strategy are as follows:
[0053] 1) Rewrite the if-else code blocks in the source code of the class under test. Use the code analysis framework JavaParser to create an if-else code block accessor that inherits from ModifierVisitor (an accessor provided by JavaParser that does not return anything and has a default implementation for all its access methods). For a branch statement, if it uses a Boolean expression composed of multiple relational expressions for branch judgment, split it into multiple branch statements that only use one relational expression for branch judgment. Perform branch stubbing on the rewritten source code. The branches include all if and switch statements, and number each branch that appears during stubbing (the number is of Integer type, counting from 1). Save the rewritten and instrumented source code of the class under test as a new file.
[0054] 2) Execute each use case to obtain the branches it covers, obtain all branch numbers covered by all use cases (all branch numbers are represented by the set Br), and the branch numbers covered by each use case. The process of executing the use case uses org.mdkt.compiler.InMemoryJavaCompiler and other external libraries, so that the test case source code can be compiled into bytecode and executed. At the same time, the custom class loader SpecialClassLoader is used to dynamically load the rewritten class under test with the same name. When the fully qualified name of the class is detected as the name of the class under test, the custom class loader SpecialClassLoader will replace the parent class loader to load the byte stream code of the new plugged-in class under test.
[0055] 3) Find the minimum set of use cases that can cover Br, and get the number of each use case in the minimum set of use cases. This problem can be regarded as a set covering problem, and is solved using an integer linear programming algorithm. The solver uses SCPSolver with the GLPK solving package. Integer linear programming (ILP) is an optimization problem in which the variables are integer values, and the objective function and equations are linear. The two formulas for solving the objective and constraints are as follows, where m is the number of test sequences, n is the total number of branches, and the A matrix is the test coverage branch situation. The solution goal is to obtain the minimum number of use cases and the index of these use cases. The constraints are simply to require that each known branch has at least one test sequence that can cover it.
[0056] Solution goal:
[0057] Constraints:
[0058] 4) Generate method-level and class-level mutants for the source code of the tested class. The types of mutants refer to the muJava tool, and the corresponding rules defined in the muJava-AUM tool are used to filter out mutations with equivalent relationships or duplications.
[0059] Generate 19 method-level variants and 28 class-level variants for the source code, and generate different numbers of variants for different tested classes. Check whether the variant code has the same effect as the original code to determine whether it is equivalent, and check whether the variant effects achieved by the two variant codes are the same to determine whether they are repeated. By removing these equivalent or repeated variants, it is possible to reduce time and cost and improve efficiency while ensuring the quality of mutation testing.
[0060] 5) Execute each use case to obtain the mutant number killed by it, and obtain all the mutant numbers covered by all use cases, where all the mutant numbers are represented by the set Mr, as well as the mutant numbers covered by each use case. The custom class loader JMutationLoader is used to dynamically load the tested class with the same name after the mutant is implanted. The process is as follows: when the fully qualified name of the class is detected as the tested class name, the custom class loader JMutationLoader will replace the parent class loader to load the byte stream code of the new tested class with the mutant implanted.
[0061] 6) Find the minimum set of use cases that can cover Mr, and get the number of each use case in the minimum set of use cases. This problem can be regarded as a set covering problem and solved using an integer linear programming algorithm in the same way as step 3) above.
[0062] 7) Take the union of the minimum set of test cases that covers the maximum number of branches and the minimum set of test cases that kills the maximum number of mutations to obtain the final reduced test case set, and write it into a file for output.
[0063] In the seventh step, Randoop-TSR will eventually output the reduced executable method sequence as a reduced regression test file (ReducedTest*.java); output the executable method sequence before reduction as the original regression test file (RegressionTest*.java); and output the unexecutable erroneous method sequence as an error disclosure test file (ErrorTest*.java).
Claims
1. A redundancy detection and removal method for a random test generation tool, characterized in that: The specific steps include: Step 1: The user gives the target class to be tested and obtains the corresponding unit test; Step 2: Randoop-TSR is proposed to incrementally build method sequences, generate new tests by combining previously generated old tests, and provide a sequence input selection mechanism; Step 3: Randoop-TSR executes the automatically generated method sequence, checks the execution results, and provides feedback; Step 4: After obtaining the executable method sequence, implement the redundancy removal strategy based on test smell to detect, filter and remove duplicate and useless assertion statements; Step 5: After obtaining the executable method sequence, the test suite is reduced by using a redundant case removal strategy based on test requirements; Step 6, Randoop-TSR outputs the executable method sequence before reduction as the original regression test file; and outputs the executable method sequence after reduction as the reduced regression test file; Output the sequence of methods that cannot be executed and have errors as error-revealing test files, recording the potential errors in one or more tested classes; In step 2, Randoop-TSR incrementally builds method sequences, generates new tests by combining previously generated old tests, and provides a sequence input selection mechanism. The specific implementation process is as follows: 21) Use static analysis to extract the tested methods that cannot change the state of data members in the tested class; the tested methods are divided into tested methods that can change the state of data members and tested methods that cannot change the state of data members according to their characteristics; the tested methods that can change the state of data members are state changer methods, and the tested methods that cannot change the state of data members are observer methods; 22) Component mapping; Extract the three components existing in each current candidate method sequence, which are: a) object type; b) name of the method under test; c) parameter and constant value; store the three components of each extracted candidate method sequence into three lists, which contain the specific contents of the above components and mark the state changer method and observer method in the called method under test; 23) Compare the three components of the current candidate method sequence with the contents of the component pool consisting of the three components of all previously selected method sequences, calculate the similarity and dissimilarity of each candidate sequence, and then obtain the weighted weight value; when the method under test called in the newly generated candidate method sequence is a state changer method and is not included in the component pool of the method under test, it is given a higher weight than the observer method; 24) Select a sequence from multiple candidate method sequences based on the weight; the three components in the selected sequence will be added to the corresponding component pool, and the sequence will be used in the subsequent expansion and test generation process; The step 5 comprises the following steps: 51) Rewrite the if-else code block in the source code of the class under test, then perform branch insertion for the rewritten source code of the class under test, and number all branches during the branch insertion process; 52) Execute each use case to obtain the branches it covers, obtain all branch numbers covered by all use cases, and the branch numbers covered by each use case, and all branch numbers are represented by the set Br; 53) Find the minimum use case set that can cover Br, and get the number of each use case in the minimum use case set; 54) Generate method-level and class-level variants for the source code of the tested class. The variant types refer to the muJava tool, and the corresponding rules defined in the muJava-AUM tool are used to filter variants with equivalent relationships or duplications; 55) Execute each use case to obtain the number of the mutant killed by it, obtain all the mutant numbers covered by all use cases, and the mutant numbers covered by each use case, where all the mutant numbers are represented by the set Mr; 56) Find the minimum use case set that can cover Mr, and get the number of each use case in the minimum use case set; 57) The minimum set of use cases S that covers the maximum number of branches will be obtained b And the minimum set of use cases S that kills the maximum number of mutations m , and finally S b and S m Take the union to get the reduced set of test cases and output it to a file.
2. The redundancy detection and removal method for a random test generation tool according to claim 1, characterized in that: In step 1, the user provides the name of the target class under test, the source code file and the compiled binary file, as well as the corresponding dependencies, time budget, and test parameters of other characteristics; then the user runs the tool using the command line to obtain the corresponding unit test.
3. The redundancy detection and removal method for random test generation tools according to claim 1, characterized in that: In step 4, after obtaining the executable method sequence, a redundancy removal strategy based on test smell is implemented, which is designed to detect, filter and remove repeated and useless assertion statements. The specific steps of the strategy are as follows: 41) Traverse the test assertions in all use cases. If two use cases contain exactly the same assertion statements, it proves that the assertions are duplicated. Do not allow the use cases containing duplicate assertions to participate in subsequent mutation testing. 42) Detect the assertion statements in each use case; useless assertions refer to assertion statements in the test method where the expected parameters and actual parameters are the same. Use the code analysis framework JavaParser to identify useless test assertions, and then remove useless assertion statements in each detected use case.
4. The redundancy detection and removal method for a random test generation tool according to claim 1, characterized in that: In step 5, after obtaining the executable method sequence, the test suite is reduced by using a redundant case removal strategy based on test requirements; first, the test requirements are clarified, including code coverage and mutation killing rate; branch coverage is selected as the test requirement of the coverage part; this strategy takes the union of the two parts of test case subsets that meet the branch coverage and mutation killing rate respectively as the final test suite result; The goal of this strategy to achieve redundant detection and elimination is to obtain the minimum set of test cases that can cover the maximum test requirements while ensuring that the test requirements remain unchanged, while achieving the effect of removing useless cases and reducing the test suite.
5. The redundancy detection and removal method for random test generation tools according to claim 1, characterized in that: In step 21, the name of the method under test that cannot change the state of the data member in the class under test is extracted by the static analysis tool ReImInfer, and is saved in a file, which will be used as an input parameter later.
6. The redundancy detection and removal method for random test generation tools according to claim 1, characterized in that: In step 22, the code analysis framework JavaParser is used to construct abstract syntax trees of different method sequences, and a sequence visitor inherited from VoidVisitorAdapter is created to extract the types, names of the tested methods, parameters and constant values of all generated objects.
7. The redundancy detection and removal method for random test generation tools according to claim 1, characterized in that: In step 23, the dissimilarity between each method sequence component and the corresponding component of each sequence in the corresponding component pool is calculated, and then the dissimilarity of the three components is weighted, and the minimum weighted value is selected as the dissimilarity result of the sequence, thereby obtaining the dissimilarity result D and the sequence weight value W; Score i (n) represents the dissimilarity between the current candidate method sequence and the three components of the i-th sequence in the pool. The calculation formula is as follows: the dissimilarity of the object type is recorded as Score(Object); the dissimilarity of the tested method is recorded as Score(Method). When calculating Score(Method), if the tested method that does not appear in the pool is a state changer method M modifier , then this method is given compared to the observer method M observer Double score; Score(Parameter) is recorded as the dissimilarity between the parameter and the constant value; Num(Diff(n)) calculates the number of components that exist in the component list of the current candidate method sequence but not in the component pool; the corresponding weights a1, b1, and c1 are all 1 / 3 by default; 。
Citation Information
Patent Citations
Code and combination coverage-based test case priority ranking method and test system
CN110134588A
Fuzzy test case generation method based on machine learning method
CN110443045A