A method and system for evaluating test coverage based on java call links

By constructing a Java call chain evaluation method, the scope of impact of code changes is identified, and multi-dimensional coverage metrics are generated. This solves the problem of incomplete test coverage evaluation in existing technologies and achieves more accurate and efficient test coverage evaluation.

CN121144214BActive Publication Date: 2026-02-24BEIJING YULORE INNOVATION TECH
View PDF 1 Cites 0 Cited by

Patent Information

Application Number
CN202511699703.2
Authority / Receiving Office
CN · China
Patent Type
Patents(China)
Current Assignee / Owner
Filing Date
2025-11-19
Publication Date
2026-02-24
Estimated Expiration
2045-11-19

AI Technical Summary

Technical Problem

Existing test coverage assessment methods mainly focus on directly modified lines of code, ignoring the potential impact of these modifications on other parts of the system. They cannot assess the extent to which the modified code affects the overall system functionality, resulting in incomplete testing and the potential omission of potential risks.

Method used

By obtaining the project code of the test version, parsing the bytecode file and constructing the method call relationship graph, identifying the difference functions and constructing the call chain tree structure, identifying the relevant code line where each call point is located, and combining code coverage statistics tools to collect and parse coverage data, multi-dimensional coverage metric data is generated.

Benefits of technology

It enables more comprehensive test coverage assessment, accurately identifies the scope of impact of code changes, improves the comprehensiveness and accuracy of test coverage, systematically organizes test objectives, provides clear priority and path guidance, reduces redundant testing work, and saves test resources.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN121144214B_ABST
    Figure CN121144214B_ABST
Patent Text Reader

Abstract

The application discloses a method and system for evaluating test coverage based on Java call link, and relates to the field of software testing.The method comprises the following steps: identifying a difference function according to a first comparison result, and constructing a call link tree structure with the difference function as a root node based on a code call relationship graph; analyzing the difference function to obtain direct code change lines of the difference function, identifying relevant code lines on a call link of each call point based on the call link tree structure, taking the relevant code lines as call point code lines, and summarizing the direct code change lines and the call point code lines; analyzing code coverage data to obtain actually covered code lines, comparing to-be-tested code lines with the actually covered code lines, determining coverage index data based on the call link according to a second comparison result, and determining a test coverage evaluation result according to the coverage index data.The application can more comprehensively and accurately evaluate test coverage.
Need to check novelty before this filing date? Find Prior Art

Description

TECHNICAL FIELD

[0001] The present application relates to the field of software testing, and in particular to a method and system for evaluating test coverage based on Java call links. BACKGROUND

[0002] Software test coverage evaluation is an important part of software quality assurance, especially in the development environment of object-oriented languages such as Java. Accurate evaluation of test coverage is crucial to ensuring software quality. Traditional test coverage analysis mainly focuses on code line coverage, branch coverage, and path coverage.

[0003] The current industry's common test coverage evaluation methods mainly include the method based on instrumentation and the method based on bytecode analysis. For example, the widely used JaCoCo tool in the Java field collects runtime coverage data by inserting probes in the bytecode; Cobertura modifies the compiled class files to achieve coverage statistics. These tools can provide detailed reports on code execution, including line coverage, branch coverage, and other indicators.

[0004] Existing test coverage evaluation methods mainly focus on version difference code (diff code) for coverage statistics, i.e., calculating the proportion of newly added and modified code lines covered by testing. During testing, the system identifies the code differences between versions, takes all difference code lines as the denominator, and takes the actual covered difference code lines in testing execution as the numerator, and calculates the coverage percentage by the ratio of the two. This method focuses on directly modified code parts and is simple and clear.

[0005] However, this traditional test coverage evaluation method has obvious shortcomings. First, it only focuses on directly modified code lines, ignoring the impact of these modifications on other parts of the system; second, modified code is usually called by upper-level code, and these call links also belong to the affected range and should be included in the test coverage but are not; finally, it cannot evaluate the impact of modified code on the overall system function, leading to incomplete testing and potential risk points may be missed. Therefore, the existing technology cannot accurately evaluate test coverage. SUMMARY

[0006] The purpose of the present application is to provide a method and system for evaluating test coverage based on Java call links, which not only considers the coverage of directly modified code parts, but also considers the coverage of code affected by the modified code on the call chain, thereby more comprehensively and accurately evaluating test coverage.

[0007] In a first aspect, the present application provides a method for evaluating test coverage based on Java call links, comprising:

[0008] The method comprises the following steps: obtaining engineering code of a test version, parsing the engineering code into bytecode files, and extracting method call relationships of the entire project based on the bytecode files, and generating a code call relationship graph from the method call relationships;

[0009] Comparing the engineering code of the test version with previously obtained code of an online master version, identifying difference functions according to a first comparison result, and constructing a call chain tree structure with the difference functions as root nodes based on the code call relationship graph;

[0010] Parsing the difference functions to obtain direct code change lines of the difference functions, identifying relevant code lines on a call chain of each call point based on the call chain tree structure as call point code lines, and summarizing the direct code change lines and the call point code lines to generate test code lines;

[0011] Obtaining a code coverage statistical tool, configuring a corresponding test execution environment according to the code coverage statistical tool, testing test cases corresponding to the test code lines in the test execution environment, and collecting code coverage data in the test process;

[0012] Parsing the code coverage data to obtain actually covered code lines, comparing the test code lines with the actually covered code lines, determining coverage index data based on the call chain according to a second comparison result, and determining a test coverage evaluation result according to the coverage index data.

[0013] In some embodiments, the parsing of the engineering code into bytecode files and the extraction of the method call relationships of the entire project based on the bytecode files to generate the code call relationship graph comprise:

[0014] Using a preset Java compilation tool to compile the engineering code of the test version into a bytecode file to be processed, loading the bytecode file to be processed into a preset JVM running environment, outputting the bytecode file, obtaining a bytecode analysis framework, configuring an analysis depth and an analysis range of an analysis tool in the bytecode analysis framework, scanning the bytecode file using the analysis tool in the bytecode analysis framework, analyzing method instructions in each class file according to the analysis depth and the analysis range, identifying method call relationships between methods based on the method instructions, constructing a global call relationship graph based on the method call relationships, and determining the code call relationship graph based on the global call relationship graph, wherein each node in the global call relationship graph represents a method, and an edge in the global call relationship graph represents the method call relationships.

[0015] In some embodiments, comparing the test version's project code with the pre-obtained online master version's code, identifying the difference function based on the first comparison result, and constructing a call chain tree structure with the difference function as the root node based on the code call relationship graph, includes:

[0016] Using a preset version control tool, the project code of the test version is compared with the code of the online master version. Based on the first comparison result, newly added, modified, and / or deleted files and code segments are extracted from the project code to mark the corresponding difference functions and their corresponding function positions. The difference functions include modified functions and newly added functions. Based on the function positions, the corresponding difference functions are located in the code call relationship graph. A call relationship tree is constructed with each modified function as the root node. The call relationship tree is used to indicate the objects that call the modified functions. For the call relationship tree, a preset recursive algorithm is used to trace the call relationship layer by layer upwards to generate an initial call tree structure. The initial call tree structure is used to indicate the path information of the call relationship. In the initial call tree structure, the call tree is traced upwards from each modified function until the preset outermost entry function is reached. The call chain tree structure is formed based on the call chain of all modified functions.

[0017] In some embodiments, parsing the difference function to obtain the direct code change lines of the difference function, identifying the relevant code lines on the call chain of each call point based on the call chain tree structure, using these as call point code lines, and summarizing the direct code change lines and the call point code lines to generate the code lines to be tested, includes:

[0018] The difference function is parsed, and the newly added and modified code lines in each of the changed functions are extracted as direct code change lines. The code position of each direct code change line is recorded, and a list of direct code change lines for the changed function is output. The list of direct code change lines contains at least one direct code change line and its code position. All call paths in the call chain tree structure are traversed, and the code line where the call point is located is identified as the call point code line. Based on the call point and the corresponding call point code line, a list of related code lines on the call chain is output. The list of direct code change lines and the list of related code lines on the call chain are merged, duplicate code lines are removed, and the lines are sorted by file name and line number to obtain the code line to be tested.

[0019] In some embodiments, the code coverage statistics tool is configured with a corresponding test execution environment, and test cases corresponding to the lines of code to be tested are performed in the test execution environment to collect code coverage data during the testing process, including:

[0020] Evaluate multiple Java code coverage tools and select the appropriate code coverage statistics tool based on project characteristics. Configure the core parameters of the code coverage statistics tool in a preset project build system to output the configured project build file according to the core parameters, which include exclusion rules and output format. Based on the project build file, configure coverage proxy parameters and set the storage location and format of coverage data. Based on the coverage proxy parameters, the storage location and format of coverage data, create a startup script and determine a suitable test execution environment. The startup script is used to instruct the collection of coverage data during test execution. In the test execution environment, execute tests on test cases corresponding to the lines of code to be tested to obtain code coverage data during the test process.

[0021] In some embodiments, comparing the test version's project code with the pre-obtained online master version's code, identifying the difference function based on the first comparison result, and constructing a call chain tree structure with the difference function as the root node based on the code call relationship graph, further includes:

[0022] The pre-defined call chain tracing problem is transformed into a constraint satisfaction problem, and the set of variables and constraints are determined. Based on the constraint satisfaction problem, the set of variables, and the constraints, a constraint satisfaction problem model is constructed. The set of variables consists of functions that form a call relationship with the modified function, and the constraints include call relationship constraints between functions in the set of variables and constraints requiring the modified function to be on the call chain. A pre-defined heuristic fast approximation algorithm is used to process the constraint satisfaction problem, and a pre-defined Arc consensus algorithm is applied during the processing to narrow down the variable domain. A minimum conflict heuristic is used to find an approximate solution, and a possible set of call chains is generated based on the approximate solution. Based on the set of call chains, the optimal set of call chains is gradually approximated through incremental adjustments, and the call chain tree structure is optimized and integrated based on the optimal set of call chains.

[0023] In some embodiments, the step of processing the constraint satisfaction problem using a preset heuristic fast approximation algorithm, and applying a preset Arc consensus algorithm to narrow the variable domain during the processing, and using a minimum conflict heuristic to find an approximate solution includes:

[0024] A core extender interface is created, which adapts to various extender types, including direct method call extenders, reflection call extenders, lambda expression extenders, and interface implementation call extenders. Based on the core extender interface, extenders are chained together to form a call analysis pipeline, constructing an extender-based code parsing architecture. Building upon this code parsing architecture and the call analysis pipeline, a pre-defined call chain search task is decomposed into independent subtasks using a pre-defined Fork / Join framework. For each subtask, call chain analysis of the modified function is performed in parallel, and a pre-defined work-stealing algorithm is used to balance the computational load during parallel processing. The call relationships are decoded layer by layer according to a pre-defined call depth. During this decoding process, weight analysis is performed on each call chain node to identify critical paths, and a pre-defined sparse matrix storage is used to optimize memory usage, yielding an approximate solution.

[0025] In some embodiments, the step of summarizing the direct code change lines and the call point code lines to generate the code lines to be tested further includes:

[0026] Based on the call chain tree structure, a depth-first traversal model is constructed, and a depth-first search traversal framework is established based on the depth-first traversal model. The node representation of the model nodes in the depth-first traversal model includes function information, call point location, and depth information. Based on the frequency of the model node in multiple call chains, the distance between the model node and the modified function, the complexity of the function containing the model node, and the historical defect density determined by the depth-first search traversal framework, the influence weight of each model node is calculated. According to a preset graph theory critical path algorithm, the test critical path in the call chain is identified. Based on the preset depth-first search traversal order and the test critical path, a DFS number is generated, and a line of code to be tested carrying the DFS number is generated. The DFS number format includes the modified function identifier, call depth, sibling sequence number, and test priority.

[0027] In some embodiments, generating a DFS number based on a preset depth-first search traversal order and the test critical path, and generating a line of code to be tested carrying the DFS number, includes:

[0028] Based on the lines of code to be tested carrying the DFS number, a coverage target roadmap is determined. A test progress tracking mechanism is established by prioritizing the DFS numbers. A test coverage guidance strategy is constructed based on the coverage target roadmap, the priority of the DFS numbers, and the test progress tracking mechanism. A coverage growth curve analysis tool is built based on the test coverage guidance strategy, and test efficiency is evaluated using this tool. An adaptive test strategy is created based on the test efficiency, which instructs for dynamically adjusting test resource allocation and optimizing test execution order. Historical test data for each DFS number is recorded. When code changes are detected, the tested DFS numbers affected by the changes are analyzed based on the historical test data, and a set of DFS numbers requiring regression testing is recommended, thus achieving incremental testing and regression analysis.

[0029] In some embodiments, parsing the code coverage data to obtain the actually covered code lines, comparing the code lines to be tested with the actually covered code lines, determining coverage metric data based on the call chain according to a second comparison result, and determining the test coverage evaluation result based on the coverage metric data include:

[0030] The code coverage data is parsed to extract information on all lines of code actually covered by the test. Coverage information irrelevant to the lines of code under test is filtered out to generate the actually covered lines of code. The actually covered lines of code are compared with the lines of code under test to calculate the coverage of directly changed code, the coverage of call chain related lines of code, and the overall coverage. Multi-dimensional coverage metrics are output based on the coverage of directly changed code, the coverage of call chain related lines of code, and the overall coverage. Uncovered lines of code are selected and categorized into corresponding changed functions and call chains. The importance and risk level of the selected lines of code are analyzed to identify uncovered code regions. The actually covered lines of code, the coverage metrics data, and the uncovered code regions are summarized to obtain the test coverage evaluation result.

[0031] Secondly, the present invention also provides a system for evaluating test coverage based on Java call chain, comprising:

[0032] The data acquisition module is used to acquire the project code of the test version, parse the project code into bytecode files, extract the method call relationship of the entire project based on the bytecode files, and generate a code call relationship graph from the method call relationship.

[0033] The model building module is used to compare the project code of the test version with the code of the pre-obtained online master version, identify the difference function based on the first comparison result, and build a call chain tree structure with the difference function as the root node based on the code call relationship graph.

[0034] The data processing module is used to parse the difference function to obtain the direct code change line of the difference function, identify the relevant code line on the call chain of each call point based on the call chain tree structure, take it as the call point code line, and summarize the direct code change line and the call point code line to generate the code line to be tested.

[0035] The testing module is used to obtain code coverage statistics tools, configure the corresponding test execution environment according to the code coverage statistics tools, test test cases corresponding to the lines of code to be tested in the test execution environment, and collect code coverage data during the testing process.

[0036] The parsing and evaluation module is used to parse the code coverage data to obtain the actually covered code lines, compare the code lines to be tested with the actually covered code lines, determine the coverage metric data based on the call chain according to the second comparison result, and determine the test coverage evaluation result based on the coverage metric data.

[0037] The method for evaluating test coverage based on Java call chains provided by this invention accurately identifies the scope of impact of code changes by analyzing the code call chain, expanding the scope of test coverage and improving the comprehensiveness and accuracy of test coverage evaluation. Furthermore, by constructing a call chain tree structure, it systematically organizes test objectives, making the testing process more targeted and organized. Through multi-dimensional coverage metrics, it comprehensively evaluates test quality and more accurately identifies test deficiencies. Moreover, through a depth-first search numbering mechanism, it provides clear priority and path guidance for test execution, improving testing efficiency. Finally, through incremental testing and regression analysis functions, it reduces repetitive testing work and saves testing resources. Attached Figure Description

[0038] Figure 1 A flowchart illustrating a method for evaluating test coverage based on Java call chain, provided in an embodiment of the present invention;

[0039] Figure 2 This is a schematic diagram of the structure of a system for evaluating test coverage based on Java call chain, provided as an embodiment of the present invention. Detailed Implementation

[0040] To make the objectives, technical solutions, and advantages of the present invention clearer, the present invention will be further described in detail below with reference to specific embodiments and accompanying drawings.

[0041] like Figure 1 As shown, this embodiment of the invention provides a method for evaluating test coverage based on Java call chain, the method including the following steps S101 to S105.

[0042] S101. Obtain the project code of the test version, parse the project code into bytecode files, extract the method call relationship of the entire project based on the bytecode files, and generate a code call relationship graph from the method call relationship.

[0043] In this application, the project code of the test version is obtained. The test version refers to the software version prepared for testing, typically a code version that has been developed but not yet fully tested and verified. The acquisition process is usually completed through checkout or clone operations of a version control system (such as Git, SVN, etc.) to ensure the acquisition of complete project code, including source code, configuration files, and dependency definitions. After acquisition, this Java source code is compiled into bytecode files using a compiler (such as javac). Bytecode files are .class files generated after compiling Java source code, containing a set of instructions that the Java Virtual Machine can understand and execute, and are key to Java's cross-platform capabilities. Bytecode is an intermediate code form between source code and machine code, possessing platform independence. After compilation, this application uses bytecode analysis technology to extract the method call relationships of the entire project. The method call relationship refers to the call dependencies between various methods in a Java program, including information about method A calling method B, and the calling method (such as direct call, interface call, reflection call, etc.). During the extraction process, this application scans method instructions in the bytecode file, paying particular attention to invocation instructions such as `invokevirtual`, `invokespecial`, `invokestatic`, and `invokeinterface`, which directly reflect the calling relationships between methods. Therefore, based on the extracted method calling relationships, this application constructs a code calling relationship graph, represented as a directed graph data structure. In this graph, nodes represent methods, and edges represent calling relationships. Specifically, each node contains the complete signature of the method (such as class name, method name, parameter types, and return type), and each edge represents the calling relationship from the calling method to the called method, facilitating subsequent analysis of the scope of code influence.

[0044] S102. Compare the project code of the test version with the code of the pre-obtained online master version, identify the difference function according to the first comparison result, and construct a call chain tree structure with the difference function as the root node based on the code call relationship graph.

[0045] In this application, after obtaining the code call graph, the code differences between the test version and the online master version are compared. The online master version refers to the stable version of code currently running in the production environment, usually the code on the main branch (master branch). The comparison process uses the difference comparison function of the version control system (such as Git's diff command) to accurately identify the added, modified, and deleted code between the two versions. This application focuses on function / method level changes, marking the changed methods as diff functions.

[0046] Specifically, the difference functions fall into two categories: modified functions (where existing functions are altered) and newly added functions. Identifying the difference functions is the first step in determining the test scope, as these functions directly reflect code changes. After identifying the difference functions, this application constructs a call chain tree structure based on the code call relationship graph generated in the previous step, with each difference function as the root node. The call chain tree structure is a special tree-like data structure used to represent the complete path of how a difference function is called by upper-level code. In this tree, the root node is the difference function, each parent node calls its child nodes, and the leaf nodes are the outermost entry functions (such as the main method, request handling methods in the Controller layer, etc.). The construction process uses a recursive or iterative algorithm, starting from the difference function and tracing backwards along the call relationship until reaching the entry function from which further upward tracing is impossible. The construction process of the call chain tree structure needs to handle various complex cases, such as circular calls, polymorphic calls, and interface implementations, to ensure that all possible call paths are captured.

[0047] S103. The difference function is parsed to obtain the direct code change line of the difference function. Based on the call chain tree structure, the relevant code line on the call chain where each call point is located is identified as the call point code line. The direct code change line and the call point code line are summarized to generate the code line to be tested.

[0048] In this application, after constructing the call chain tree structure, the differencing functions are analyzed in a fine-grained manner to extract the lines of direct code change. Lines of direct code change refer to the specific lines of code that are added or modified in the differencing functions, identified by their filenames and line numbers (e.g., UserService.java:156). These lines of code are the core of the changes and must be included in the test coverage. Simultaneously, based on the call chain tree structure constructed in the previous step, the line of code containing each call point is identified. A call point refers to the specific location in the code where the differencing function is called, and the line of code containing these call points is the line of code containing those call points.

[0049] For example, if method A calls the modified method B, then the line of code in method A that calls method B is the call point line.

[0050] During the identification process, this application traverses all paths in the call chain tree, recording the source code location corresponding to each call relationship. Finally, this application summarizes and deduplicates the directly modified lines and call point lines (because the same line of code may appear in multiple call chains), forming a complete list of lines of code to be tested. This list comprehensively considers the directly modified code and the call chain code affected by the changes, providing a more comprehensive test coverage target than traditional methods.

[0051] S104. Obtain the code coverage statistics tool, configure the corresponding test execution environment according to the code coverage statistics tool, test the test cases corresponding to the lines of code to be tested in the test execution environment, and collect code coverage data during the test process.

[0052] In this application, after determining the lines of code to be tested, a suitable code coverage statistics tool is acquired. This tool is specialized software used to collect and analyze code execution data; commonly used in the Java domain include JaCoCo, Cobertura, and Clover. These tools typically use bytecode instrumentation to record whether each line of code is executed and the number of times it is executed during code execution. After selecting a suitable tool, this application configures tool parameters according to project characteristics, such as exclusion rules (specifying code regions that do not require coverage statistics) and output formats (e.g., HTML, XML, CSV). After configuration, this application creates a corresponding test execution environment, including setting coverage agent parameters (e.g., JaCoCo's javaagent parameter), coverage data storage location, and startup scripts. In the prepared test environment, this application executes test cases related to the lines of code to be tested. Optionally, these test cases can be automated tests (e.g., unit tests, integration tests) or manual tests, with the goal of covering as many lines of code as possible. During test execution, code coverage data is collected in real time using the coverage tool, recording the execution status of each line of code.

[0053] S105. The code coverage data is parsed to obtain the actual covered code lines, and the code lines to be tested are compared with the actual covered code lines. The coverage index data based on the call chain is determined according to the second comparison result, and the test coverage evaluation result is determined according to the coverage index data.

[0054] In this application, after testing, the collected code coverage data is parsed to extract the information of the actually covered lines of code. The actually covered lines of code refer to the lines of code actually executed during the test, identified by filename and line number. During parsing, this application filters out coverage information unrelated to the lines of code under test (such as the test framework's own code), ensuring that only coverage relevant to the current change is considered. Then, the actually covered lines of code are compared with the previously generated lines of code under test, and multi-dimensional coverage metrics are calculated based on the comparison results. For example, these metrics include: coverage of directly changed code (the proportion of directly modified and newly added lines of code in the changed function that are covered), coverage of call chain-related lines of code (the proportion of call point lines of code that are covered), and overall coverage (the overall coverage proportion of the lines of code under test). Based on these coverage metrics, this application ultimately determines the test coverage evaluation results, including not only percentage values ​​for various coverage rates, but also detailed information on uncovered code areas, risk assessments, and supplementary test reports, providing the testing team with comprehensive quality assessment and improvement guidance.

[0055] In some embodiments, parsing the project code into bytecode files, extracting the method call relationships of the entire project based on the bytecode files, and generating a code call relationship graph from the method call relationships include:

[0056] Using a preset Java compiler, the test version of the project code is compiled into a bytecode file to be processed, and the bytecode file is loaded into a preset JVM runtime environment to output the bytecode file. A bytecode analysis framework is obtained, and the analysis depth and scope of the bytecode analysis tools in the bytecode analysis framework are configured. The analysis tools in the bytecode analysis framework are used to scan the bytecode file, and the method instructions in each class file are analyzed according to the analysis depth and the analysis scope. The method call relationship between methods is identified based on the method instructions. Based on the method call relationship, a global call relationship graph is constructed, and the code call relationship graph is determined based on the global call relationship graph. Each node in the global call relationship graph represents a method, and the edges in the global call relationship graph represent the method call relationship.

[0057] In this embodiment, firstly, the test version of the project code is compiled into bytecode files to be processed using preset Java compilation tools. These Java compilation tools are tools capable of converting Java source code into bytecode, primarily including: the javac compiler in the Java Development Kit (JDK), used to directly compile single or multiple Java source files; the Maven build tool, which batch compiles the entire project via the maven-compiler-plugin; and the Gradle build tool, which handles compilation tasks via a Java plugin. These tools are used to convert human-readable Java source code (.java files) into bytecode instructions executable by the Java Virtual Machine (.class files).

[0058] Specifically, the compilation process includes multiple stages such as syntax analysis, semantic analysis, and bytecode generation, ultimately generating a sequence of bytecode instructions containing opcodes and operands. After compilation, this embodiment loads these bytecode files into a preset JVM runtime environment. The JVM runtime environment is a container for running Java programs, including components such as the class loading subsystem, runtime data area, and execution engine. In this embodiment, the loading operation is mainly completed by the class loading subsystem, which loads the bytecode files into memory and stores the class structure information in the method area. The loading process ensures that all dependent classes are also loaded correctly, providing a complete class information environment for subsequent analysis. Finally, the processed bytecode file set is output, which contains the complete logic and behavior of the program.

[0059] Next, this embodiment acquires a suitable bytecode analysis framework and performs the necessary configuration. Bytecode analysis frameworks are tool libraries specifically designed for parsing and analyzing Java bytecode. These mainly include: the ASM framework, a lightweight Java bytecode manipulation and analysis framework capable of directly processing bytecode instructions; the Javassist library, which provides a higher-level API, simplifying bytecode manipulation; and ByteBuddy, a more modern bytecode generation and manipulation library. These frameworks are used to read bytecode files, parse their instructions and data structures, and provide programming interfaces for analysis and manipulation.

[0060] Specifically, during the configuration process, this embodiment sets two key parameters: analysis depth and analysis scope. Analysis depth defines the maximum level of call chain tracing to prevent infinite recursion in complex projects; analysis scope defines the set of packages or classes to be analyzed, usually specified by package name prefixes or regular expressions, which can exclude third-party libraries or non-business code. After configuration, the analysis framework scans all bytecode files, focusing on the method instructions in each class file. Method instructions are the parts of bytecode that represent operations, especially invocation instructions, such as `invokevirtual` (invoking instance methods), `invokespecial` (invoking special methods, such as constructors), `invokestatic` (invoking static methods), and `invokeinterface` (invoking interface methods). This embodiment identifies the call relationships between methods by parsing these instructions and their operands, including complete information about the caller and callee (class name, method name, parameter types, and return type).

[0061] Next, based on the method call relationships identified in the previous step, a global call relationship graph is constructed. A global call relationship graph is a directed graph data structure used to represent the call dependencies between methods throughout the entire project. In this global call relationship graph, each node represents a method, containing information such as class name, method name, parameter list, and return type; each edge represents a call relationship, pointing from the caller to the callee.

[0062] For example, the build process needs to handle various complex situations, including: method overriding and invocation under class inheritance relationships, requiring consideration of dynamic binding characteristics; polymorphic invocation under interface implementation relationships, requiring identification of all possible implementation classes; method invocation in inner classes and anonymous classes; and functional invocation introduced by Java 8 features such as lambda expressions and method references. To handle these complexities, this embodiment employs type inference and resolution techniques, combined with class hierarchy analysis, to ensure the accuracy of call relationships. After the build is completed, the final code call relationship graph is determined based on the global call relationship graph, which may be optimized and filtered, such as removing irrelevant nodes, merging duplicate paths, or marking special call types. The final code call relationship graph is a concise yet information-rich data structure, facilitating subsequent differential function analysis and call chain tracing.

[0063] In some embodiments, comparing the test version's project code with the pre-obtained online master version's code, identifying the difference function based on the first comparison result, and constructing a call chain tree structure with the difference function as the root node based on the code call relationship graph, includes:

[0064] Using a preset version control tool, the project code of the test version is compared with the code of the online master version. Based on the first comparison result, newly added, modified, and / or deleted files and code segments are extracted from the project code to mark the corresponding difference functions and their corresponding function positions. The difference functions include modified functions and newly added functions. Based on the function positions, the corresponding difference functions are located in the code call relationship graph. A call relationship tree is constructed with each modified function as the root node. The call relationship tree is used to indicate the objects that call the modified functions. For the call relationship tree, a preset recursive algorithm is used to trace the call relationship layer by layer upwards to generate an initial call tree structure. The initial call tree structure is used to indicate the path information of the call relationship. In the initial call tree structure, the call tree is traced upwards from each modified function until the preset outermost entry function is reached. The call chain tree structure is formed based on the call chain of all modified functions.

[0065] In this embodiment, a preset version control tool is used to compare the test version with the online master version. Version control tools are software systems used to manage the history of source code changes and are widely used in software development, primarily including Git, Subversion (SVN), and Mercurial. These tools are used to track the modification history of files, support collaborative development by multiple developers, and provide branch management and version comparison functions. In this embodiment, the difference comparison function of the version control tool (such as Git's diff command) is mainly used. This function can accurately identify the changes in files and code between two versions.

[0066] Specifically, the comparison process first compares file-level differences to identify newly added, modified, and deleted files. Then, within the modified files, it further compares line-level differences to pinpoint specific code changes. Based on this difference information, all newly added, modified, and / or deleted files and code segments are extracted. Subsequently, this embodiment performs function-level analysis, marking the affected difference functions and their precise locations. It should be noted that function location includes information such as file path, class name, method name, start line number, and end line number, used to uniquely identify a function's position in the codebase. Difference functions are mainly divided into two categories: modified functions refer to functions that have been modified, including changes to function signatures (such as parameter lists or return types) and function implementations; new functions refer to newly added functions that do not exist in the baseline version. The output of this step is a detailed list of difference functions, containing the type (modified or added) and location information for each function.

[0067] Next, based on the marked function location information, each differing function is located in the constructed code call relationship graph. This requires mapping the function location information (file path, class name, method name, etc.) to nodes in the call relationship graph. After location, a call relationship tree is constructed with each changed function as the root node. It should be noted that the call relationship tree is a special tree-like data structure used to show who called the changed function, in the opposite direction to the traditional call tree. The root node is the changed function, the child nodes are the functions that called the root node, and so on. This bottom-up structure intuitively shows how the changed function is called by the upper-level code, which is key to understanding the scope of the code change's impact. The construction process identifies the direct caller by querying the incoming edges (edges pointing to the changed function) in the call relationship graph, and then recursively finds the callers of these callers, forming a multi-level tree structure. For complex call relationships, such as a function being called by multiple other functions, the call relationship tree will contain multiple branches, each representing a possible call path.

[0068] Furthermore, based on the call relationship tree constructed in the previous step, a pre-defined recursive algorithm is applied to trace the call relationships upwards layer by layer. The recursive algorithm is an algorithmic pattern that solves problems by calling itself, and is particularly suitable for handling problems with self-similar structures, such as tree traversal. In this context, the recursive algorithm starts from each modified function node, first identifying the parent function that directly calls it, and then recursively applying the same process to each parent function to find the even higher-level functions that call these parent functions, and so on, until it is impossible to trace upwards any further. During the recursive process, it is necessary to handle circular calls, which is usually avoided by maintaining a set of visited nodes. The algorithm terminates when no function calls a node (such as the application's entry point) or when a pre-defined maximum recursion depth is reached. This process generates an initial call tree structure, containing complete information from the modified function to all possible call paths. Compared to the call relationship tree, the initial call tree structure is more standardized and structured, containing richer path information, such as call level, call frequency, and call context.

[0069] Finally, based on the initial call tree structure, this embodiment starts from each modified function and continues tracing upwards along the call tree until it reaches the preset outermost entry function. The outermost entry function refers to the function directly exposed to external systems or users, typically including: the main program entry point (such as the `main` method); controller methods in web applications (such as the `@RequestMapping` method in Spring MVC); remote service interfaces (such as RPC and Web Service interfaces); and event listeners and callback functions. These functions represent the boundary between external systems or users and the application; tracing to this layer ensures the capture of the complete call path. During the tracing process, complex situations such as multi-level inheritance, interface implementations, and dynamic proxies may need to be handled, requiring the combination of static analysis and type inference techniques. After tracing is complete, the call chain tree structure is formed based on the call chains of all modified functions. The final generated "call chain tree structure" is an optimized tree data structure that clearly shows how all modified functions affect the entire system through various call paths, facilitating subsequent identification of call point lines of code and evaluation of test coverage.

[0070] In some embodiments, parsing the difference function to obtain the direct code change lines of the difference function, identifying the relevant code lines on the call chain of each call point based on the call chain tree structure, using these as call point code lines, and summarizing the direct code change lines and the call point code lines to generate the code lines to be tested, includes:

[0071] The difference function is parsed, and the newly added and modified code lines in each of the changed functions are extracted as direct code change lines. The code position of each direct code change line is recorded, and a list of direct code change lines for the changed function is output. The list of direct code change lines contains at least one direct code change line and its code position. All call paths in the call chain tree structure are traversed, and the code line where the call point is located is identified as the call point code line. Based on the call point and the corresponding call point code line, a list of related code lines on the call chain is output. The list of direct code change lines and the list of related code lines on the call chain are merged, duplicate code lines are removed, and the lines are sorted by file name and line number to obtain the code line to be tested.

[0072] In this embodiment, the identified difference functions are analyzed in detail, and the newly added and modified lines of code in each change function are extracted as direct code change lines. Direct code change lines refer to the specific lines of code directly added or modified in this code change, and are the most basic unit of code change. The extraction process involves multiple technical means: version control system-based difference comparison (such as Git's diff command), which can accurately identify line-level changes between two versions; parser technology, which can understand the structure and semantics of the code and identify valid lines of code (excluding comments, blank lines, etc.); and abstract syntax tree (AST) analysis, which can identify changes in syntax structure, such as modifications to statements, expressions, and code blocks. For each direct code change line, its precise code location is recorded, including the file path, class name, method name, and line number. The code location is a multi-dimensional identifier used to uniquely locate a specific line in the source code, such as "com / example / UserService.java:156", which represents line 156 of the UserService class. During the recording process, various special cases are handled, such as multi-line statements (e.g., long method call chains), cross-line expressions, and code format changes (e.g., changes only indentation). Ultimately, this embodiment outputs a complete list of lines of direct code change. This is a structured dataset containing at least one line of direct code change and its corresponding code location. This list is the primary focus of traditional test coverage analysis and is also the foundation of the method of this invention.

[0073] Next, based on the constructed call chain tree structure, this embodiment traverses all possible call paths and identifies the line of code containing the call point, which is then designated as the call point line of code. The call point refers to the specific location in the code where the modified function is directly called, typically represented by a method call expression such as "userService.updateUser(user)". The call point line of code is the complete line of code containing the call point and is crucial for understanding the scope of the code change's impact. The traversal process employs either Depth-First Search (DFS) or Breadth-First Search (BFS) algorithms, systematically visiting each node and edge in the call chain tree. For each call relationship (a call from function A to function B), the specific call point needs to be located in the source code of function A. This involves code matching and pattern recognition techniques: by analyzing the source code of function A, all call expressions to function B are found; for complex cases, such as calls via variable calls, method chaining, or lambda expressions, more in-depth context analysis and type inference are required. After identifying the call point, its line of code information is recorded, including the file path, class name, method name, and line number. Based on these call points and their corresponding lines of code, a "list of relevant lines of code on the call chain" is output. This list contains all upper-level call points that may be affected by the changed function. Unlike traditional methods, this invention pays special attention to these call points because they are key nodes in the spread of the change's impact and should be included in the test coverage.

[0074] Finally, the list of directly modified lines of code and the list of related lines of code in the call chain are merged to form the final list of lines of code to be tested. It should be noted that the merging process is not a simple concatenation but requires intelligent processing: First, this embodiment needs to remove duplicate lines of code. Duplicates typically occur in two situations: one, the same line of code may be both a directly modified line and a call point line (e.g., calling another modified function within a modified function); two, the same line of code may appear in multiple call chains (e.g., a public method is called by multiple paths). The deduplication process uses a hash table or set data structure to ensure that each unique line of code appears only once. Second, the lines of code are sorted and organized by filename and line number to make the result more organized and readable. The sorting criteria are usually first sorted alphabetically by file path, then sorted numerically by line number. The organized list of lines of code to be tested is a comprehensive and precise set of test targets, containing directly modified code and call chain code affected by the changes, providing clear targets for subsequent test coverage and making the testing more comprehensive and effective.

[0075] In some embodiments, the code coverage statistics tool is configured with a corresponding test execution environment, and test cases corresponding to the lines of code to be tested are performed in the test execution environment to collect code coverage data during the testing process, including:

[0076] Evaluate multiple Java code coverage tools and select the appropriate code coverage statistics tool based on project characteristics. Configure the core parameters of the code coverage statistics tool in a preset project build system to output the configured project build file according to the core parameters, which include exclusion rules and output format. Based on the project build file, configure coverage proxy parameters and set the storage location and format of coverage data. Based on the coverage proxy parameters, the storage location and format of coverage data, create a startup script and determine a suitable test execution environment. The startup script is used to instruct the collection of coverage data during test execution. In the test execution environment, execute tests on test cases corresponding to the lines of code to be tested to obtain code coverage data during the test process.

[0077] In this embodiment, various Java code coverage tools are evaluated, and the most suitable tool is selected based on the project characteristics. Java code coverage tools are software tools specifically designed to collect and analyze code coverage during Java program execution. Common examples include JaCoCo, Cobertura, Clover, and Emma. These tools collect execution information during program runtime using different techniques (such as bytecode instrumentation), recording which code is executed and how many times. It's important to note that the evaluation process considers multiple dimensions: coverage type support (e.g., line coverage, branch coverage, method coverage, etc.), with JaCoCo supporting the most comprehensive coverage types; performance impact, with Emma and JaCoCo typically having minimal impact on runtime performance; ease of integration, with JaCoCo having high integration with mainstream build tools and CI systems; and richness of report formats, with Clover and JaCoCo offering multiple report formats. The most suitable tool is selected based on the specific characteristics of the project (e.g., scale, technology stack, performance requirements, etc.). For most Java projects, JaCoCo is recommended due to its comprehensive functionality, good performance, and extensive integration support. After selecting a tool, configure it within a pre-defined project build system (such as Maven, Gradle, or Ant). A project build system is an automated tool that manages the software build process, responsible for tasks such as compiling code, running tests, and packaging software. The configuration process mainly sets the core parameters of the coverage tool, including: exclusion rules, specifying code areas that do not need coverage statistics, typically including generated code, test code itself, and third-party libraries, defined using package name patterns or class name wildcards; and output format, specifying the format of the coverage report, such as HTML (visual browsing), XML (machine processing), CSV (data analysis), etc. After configuration, this embodiment generates an updated project build file (such as Maven's pom.xml or Gradle's build.gradle), containing complete configuration information for the coverage tool, preparing for subsequent coverage data collection.

[0078] Next, based on the updated project build file, configure the coverage proxy parameters. Coverage proxy parameters are configuration options that control the behavior of the coverage tool, typically set via JVM startup parameters (such as `-javaagent`). The configuration process varies depending on the tool, but the core is specifying how coverage data is collected: On-the-fly mode collects and updates coverage data in real-time during program execution; Offline mode saves coverage data all at once when the program ends. This embodiment also requires setting the storage location and format of the coverage data. The storage location is usually a file path or URL specifying where the coverage data file is saved; the storage format is the data encoding method, such as JaCoCo's .exec binary format or Emma's .em format. Setting these parameters ensures that coverage data can be correctly collected, saved, and subsequently processed. Based on these configurations, create a "startup script," which is an executable file containing all the commands and parameters needed to start the test execution environment. The startup script is typically a shell script (Unix / Linux) or a batch file (Windows), containing information such as the JVM startup command, coverage proxy parameters, classpath settings, and program entry point. In addition, this embodiment also needs to determine a suitable test execution environment. The test execution environment is the software and hardware platform for running the test, including the operating system, JVM version, memory configuration and other necessary environment variables. The selection of the environment needs to take into account factors such as similarity to the production environment, resource availability and test isolation.

[0079] Subsequently, in the configured test execution environment, this embodiment executes the test cases corresponding to the lines of code to be tested. A test case is a set of inputs, execution conditions, and expected results that verify a specific function or behavior of the software. In a Java environment, test cases typically exist in the form of unit tests (such as JUnit tests), integration tests, or end-to-end tests. Testing refers to the automated testing process executed by a program, requiring no manual intervention, and enabling rapid and consistent verification of software functionality. The execution process is usually initiated through a test framework (such as JUnit, TestNG) or build tool (such as the Maven Surefire plugin), running all test cases related to the lines of code to be tested.

[0080] For example, relevance assessment is based on multiple strategies: method-level correlation (the direct correspondence between test methods and methods under test), class-level correlation (the correspondence between test classes and classes under test), package-level correlation (the correspondence between test packages and packages under test), and historical execution data (which tests historically covered specific lines of code). During test execution, the coverage tool automatically collects code coverage data based on previous configurations. This data records whether each line of code was executed, how many times it was executed, and the execution path, among other information. Data collection employs "instrumentation," which involves inserting additional instructions into the original code to trace the execution flow. Instrumentation can be performed at different stages: compile-time instrumentation (modifying the source code or compilation process), load-time instrumentation (modifying bytecode during class loading), or runtime instrumentation (dynamically modifying at runtime through a JVM proxy). JaCoCo primarily uses load-time instrumentation, modifying bytecode and inserting tracing instructions when the class is loaded into the JVM. After testing, coverage data is saved to a specified location, providing raw data for subsequent coverage analysis.

[0081] In some embodiments, comparing the test version's project code with the pre-obtained online master version's code, identifying the difference function based on the first comparison result, and constructing a call chain tree structure with the difference function as the root node based on the code call relationship graph, further includes:

[0082] The pre-defined call chain tracing problem is transformed into a constraint satisfaction problem, and the set of variables and constraints are determined. Based on the constraint satisfaction problem, the set of variables, and the constraints, a constraint satisfaction problem model is constructed. The set of variables consists of functions that form a call relationship with the modified function, and the constraints include call relationship constraints between functions in the set of variables and constraints requiring the modified function to be on the call chain. A pre-defined heuristic fast approximation algorithm is used to process the constraint satisfaction problem, and a pre-defined Arc consensus algorithm is applied during the processing to narrow down the variable domain. A minimum conflict heuristic is used to find an approximate solution, and a possible set of call chains is generated based on the approximate solution. Based on the set of call chains, the optimal set of call chains is gradually approximated through incremental adjustments, and the call chain tree structure is optimized and integrated based on the optimal set of call chains.

[0083] In this embodiment, the call chain tracing problem is first transformed into a constraint satisfaction problem (CSP). It should be noted that constraint satisfaction problems are a class of problems in artificial intelligence and computer science, whose goal is to find a set of variable assignments that satisfy all predefined constraints. In this context, this transformation allows the complex call chain tracing problem to leverage mature CSP solving techniques, improving processing efficiency and accuracy. The transformation process first determines the set of variables, i.e., all functions that may have call relationships with the modified function. Each variable represents a function, and its value range is the position or state of the function in the call chain (e.g., on / off the chain, or a specific call depth). Then, two key types of constraints are defined: the first type is the call relationship constraint between functions, indicating that if function A calls function B, then in any valid call chain, A must be upstream of B. This constraint is based on the edge relationships in the code call graph, ensuring that the generated call chain follows the actual code call logic. The second type is the constraint that the modified function must be on the call chain, ensuring that the constructed call chain must contain at least one modified function. These constraints are the core requirement of the problem, ensuring that the generated call chain is directly related to code changes. Based on these definitions, this embodiment constructs a constraint satisfaction problem model, a formal mathematical representation that includes all variables, their ranges, and constraints. The model construction process involves several techniques: symbolic representation for precisely describing variables and constraints; graph theory models for representing call relationships between functions; and logical expressions for expressing complex constraints. This model transformation makes the call chain tracing problem more suitable for applying efficient solution algorithms, especially for complex, large codebases.

[0084] Furthermore, a pre-defined heuristic fast approximation algorithm is used to process the constructed constraint satisfaction problem. Heuristic algorithms guide the search process through rules of thumb; while they don't guarantee finding the optimal solution, they can find a near-optimal solution within a reasonable timeframe, making them particularly suitable for complex combinatorial optimization problems. During processing, the Arc Consistency Algorithm is applied to narrow down the variable domain. Arc Consistency is a preprocessing technique for constraint satisfaction problems; by examining the constraints between each pair of related variables, it removes values ​​from the variable domain that cannot appear in any solution, thereby reducing the search space. Specific implementations typically use AC-3 or AC-4 algorithms, which manage the pairs of variables to be examined through queues or priority queues, systematically applying constraints until a consistency state is reached or the problem is found to be unsolvable. After narrowing the variable domain, the Minimum Conflicts Heuristic is used to find an approximate solution. The Minimum Conflicts Heuristic is a local search algorithm that starts from an initial assignment, iteratively selects the variable that violates the most constraints, and modifies its value to minimize the conflict. This method is more efficient than traditional backtracking search, especially when dealing with large-scale problems with multiple constraints. For example, the key steps of the algorithm include: selecting initial assignments, which can be random or based on some heuristic rule; evaluating the conflict situation of the current assignments and calculating the number of constraint conflicts for each variable; selecting the variable with the most conflicts for adjustment; for the selected variable, evaluating all possible assignments and selecting the value that minimizes the total number of conflicts; repeating the above steps until a conflict-free solution is found or a preset number of iterations is reached. Based on the obtained approximate solution, this embodiment generates a set of possible call chains. This set of call chains represents different paths through which the modified function is called by other functions. Each call chain starts from an entry function, passes through a series of intermediate functions, and finally reaches the modified function.

[0085] Finally, based on the set of possible call chains generated in the previous step, incremental adjustments are made to gradually approach the optimal solution. Incremental adjustments are an iterative optimization strategy that improves the quality of the solution through small, continuous changes, similar to the application of gradient descent in continuous optimization problems. In this context, incremental adjustments include several operations: expanding call chains by adding branches or lengthening paths; merging similar call chains to reduce redundancy; removing unnecessary nodes to simplify call paths; and adjusting path priorities to highlight important call relationships. After each adjustment, the quality of the new solution is evaluated, considering multiple metrics: coverage (how many changed functions are included), simplicity (path length and complexity), usability (ease of testing the path), etc. This process is similar to simulated annealing, allowing for the acceptance of certain temporary changes. Adjustments were made to reduce quality to avoid getting trapped in local optima. Through repeated adjustments and evaluations, this embodiment ultimately found the optimal call chain set, a set of call paths that most comprehensively and accurately represents the scope of impact of the changed function. Finally, based on the optimal call chain set, the original call chain tree structure was optimized and integrated. The integration process included: updating the tree structure to ensure that all optimal call chains were included; optimizing the tree organization to make the structure clearer and more hierarchical; marking important nodes and paths for easier subsequent analysis; and calculating and adding additional information, such as call frequency and path depth. Therefore, this optimized call chain tree structure is a more accurate and practical model that can better guide subsequent test coverage work, ensuring that tests cover all potentially affected code paths.

[0086] In some embodiments, the step of processing the constraint satisfaction problem using a preset heuristic fast approximation algorithm, and applying a preset Arc consensus algorithm to narrow the variable domain during the processing, and using a minimum conflict heuristic to find an approximate solution includes:

[0087] A core extender interface is created, which adapts to various extender types, including direct method call extenders, reflection call extenders, lambda expression extenders, and interface implementation call extenders. Based on the core extender interface, extenders are chained together to form a call analysis pipeline, constructing an extender-based code parsing architecture. Building upon this code parsing architecture and the call analysis pipeline, a pre-defined call chain search task is decomposed into independent subtasks using a pre-defined Fork / Join framework. For each subtask, call chain analysis of the modified function is performed in parallel, and a pre-defined work-stealing algorithm is used to balance the computational load during parallel processing. The call relationships are decoded layer by layer according to a pre-defined call depth. During this decoding process, weight analysis is performed on each call chain node to identify critical paths, and a pre-defined sparse matrix storage is used to optimize memory usage, yielding an approximate solution.

[0088] In this embodiment, a core extender interface (CallChainExtender) is created. The core extender interface is an interface abstraction in software design patterns, defining a standard set of methods for extending call chain analysis capabilities. In object-oriented programming, an interface is a specification that defines a set of methods but does not implement them; the concrete implementation is provided by the classes that implement the interface. In this embodiment, this interface typically contains methods such as extendCallChain(CallChainchain) and supportMethodType(MethodType type) to unify the behavior of different types of extenders. Based on this interface, various types of extenders are implemented to handle various complex calling methods in Java. The direct method call extender (DirectMethodCallExtender) handles the most common direct method calls, such as calls in the form of obj.method() or ClassName.staticMethod(). This extender identifies call relationships by analyzing the invokevirtual, invokespecial, and invokestatic instructions in the bytecode, forming the foundation of call analysis. The ReflectionCallExtender handles indirect calls made through the Java Reflection API, such as calls of the form `Method.invoke()`. Reflection is a high-level feature of Java that allows programs to inspect and manipulate classes, interfaces, fields, and methods at runtime. Due to the dynamic nature of reflection calls, this extender requires a combination of static analysis and type inference techniques to analyze possible reflection targets. The LambdaExpressionExtender handles lambda expressions and functional interfaces introduced in Java 8, such as code of the form `stream.map(x -> x.process())`. Lambda expressions create anonymous functions whose implementations involve `invokedynamic` instructions and method references; the analysis process requires special handling of these new features. The InterfaceImplementationExtender handles concrete implementation calls to interface methods, involving polymorphism and dynamic binding mechanisms. When a method is called through an interface reference, the method in the implementing class is actually executed. This extender needs to analyze class inheritance relationships and interface implementation relationships to determine possible call targets. This interface-based design enables the system to flexibly handle various complex calling scenarios and supports new calling patterns by adding new extender types, thus improving the system's scalability.

[0089] Subsequently, based on the core extender interface, various extenders are chained together in a specific order to form a complete call analysis pipeline. This call analysis pipeline is a software architecture pattern employing the Chain of Responsibility pattern, linking multiple processing components together. Each component is responsible for a specific type of processing task, and the processing results are passed sequentially. In this embodiment, call analysis requests pass through each extender sequentially, with each extender attempting to handle a specific type of call relationship. If an extender cannot handle a certain call type, the request is passed to the next extender in the chain. In this embodiment, the chained structure effectively improves flexibility and scalability: new extenders can be easily added to the chain without affecting existing components; processing logic can be dynamically adjusted, configuring the most suitable extender combination according to project characteristics; each extender can focus on a specific type of call analysis, achieving separation of concerns. When configuring the pipeline, extenders are typically ordered according to processing frequency and complexity: direct method call extenders are usually placed at the beginning of the chain because they handle the most common call cases; extenders for special call types (such as reflection and lambda) are placed later and activated only when necessary. In this way, an extender-based code parsing architecture is constructed. This architecture modularizes call analysis capabilities, with each extender responsible for a specific analysis task, while the overall architecture coordinates the work of each component through interfaces and pipeline mechanisms. This design not only improves the maintainability and scalability of the system but also enables call chain analysis to adapt to various complex Java code patterns.

[0090] Then, based on the above architecture, parallel processing is achieved using Java's Fork / Join framework. The Fork / Join framework, introduced in Java 7, is designed for parallel task processing, specifically for decomposable tasks, and employs a divide-and-conquer strategy. It should be noted that large tasks are recursively decomposed into smaller tasks, these smaller tasks are executed in parallel, and then the results are merged. The key components of the framework include ForkJoinPool (a thread pool that manages worker threads) and RecursiveTask / RecursiveAction (representing decomposable tasks). In this embodiment, the call chain search task is defined as a decomposable task, which is decomposed into multiple independent subtasks using the Fork / Join framework. The decomposition strategy is based on several factors: grouping by change functions, with each change function serving as the starting point for a subtask; layering by call depth, limiting the search depth of each subtask; or dividing by code modules, grouping related functional areas together. After decomposition, call chain analysis of the change functions is performed for each subtask. Multiple subtasks can be processed in parallel, greatly improving processing speed. During parallel processing, a work-stealing algorithm is employed to balance the computational load. The work-stealing algorithm is a dynamic load balancing technique where, once a worker thread completes its own task queue, it steals tasks from the queues of other threads that still have tasks available. This ensures efficient utilization of computing resources and avoids situations where some threads are overloaded while others are idle. Optionally, the Fork / Join framework has a built-in work-stealing mechanism implemented using a double-ended queue (Deque): threads retrieve tasks from the front of their own queue and steal tasks from the back of other threads' queues. This parallel processing strategy is particularly effective for large projects, significantly reducing the time required for call chain analysis.

[0091] Finally, the results obtained from parallel processing are decoded layer by layer according to a preset call depth. Call depth refers to the number of levels in the method call chain, representing the nesting depth from the initial call to the current method. For example, if A calls B, and B calls C, then the call depth of C is 2. The layer-by-layer decoding process is a bottom-up analysis method, starting from the changing function and parsing its upper-level callers level by level until the top of the call chain is reached. During the decoding process, weight analysis is performed on each call chain node to calculate the importance of each node.

[0092] Specifically, the weight calculation considers several factors: the node's call frequency, i.e., the number of times the method is called; higher frequency indicates greater importance. The node's code complexity, usually measured by cyclomatic complexity, is also considered; more complex code is more prone to errors. The node's historical problem rate, based on historical data from the control system and defect tracking system, indicates that code areas with high problem rates are at greater risk. Based on these weight analyses, critical paths are identified—those call paths most likely to be affected by changes, or those with the greatest impact. Simultaneously, to optimize memory usage for large-scale call networks, sparse matrix storage technology is employed. A sparse matrix is ​​a matrix where most elements are zero. When representing large call networks (such as in adjacency matrix form), traditional two-dimensional arrays consume significant memory. Sparse matrix storage only records non-zero elements (i.e., actual call relationships), typically using compressed row storage (CRS) or compressed column storage (CCS) formats, significantly reducing memory usage. Therefore, through these processing steps, a high-quality approximate solution is finally obtained—a comprehensive and accurate set of possible call chains, providing precise guidance for subsequent test coverage.

[0093] In some embodiments, the step of summarizing the direct code change lines and the call point code lines to generate the code lines to be tested further includes:

[0094] Based on the call chain tree structure, a depth-first traversal model is constructed, and a depth-first search traversal framework is established based on the depth-first traversal model. The node representation of the model nodes in the depth-first traversal model includes function information, call point location, and depth information. Based on the frequency of the model node in multiple call chains, the distance between the model node and the modified function, the complexity of the function containing the model node, and the historical defect density determined by the depth-first search traversal framework, the influence weight of each model node is calculated. According to a preset graph theory critical path algorithm, the test critical path in the call chain is identified. Based on the preset depth-first search traversal order and the test critical path, a DFS number is generated, and a line of code to be tested carrying the DFS number is generated. The DFS number format includes the modified function identifier, call depth, sibling sequence number, and test priority.

[0095] In this embodiment, a depth-first search (DFS) model is first constructed based on the previously built call chain tree structure. It should be noted that Depth-First Search (DFS) is a graph traversal algorithm that starts from the root node and delves as deep as possible along a path until it can no longer proceed, then backtracks to the previous node and continues exploring other paths. In this embodiment, the DFS model is a special data structure used to systematically represent the depth-first access order of the call chain tree. Each model node in this model contains rich information, forming a complete node representation: First, function information, including the fully qualified name of the class (e.g., com.example.UserService), method name, parameter type list, and return type, which uniquely identify a method; second, the call point location, i.e., the specific code location where the function is called, including the caller's file path, class name, and line number; and finally, depth information, representing the node's level in the call chain, counted from the root node (usually the modified function). Based on this model, this embodiment establishes a depth-first search traversal framework (DFS Framework). It should be noted that this framework is a software component that implements a systematic access and processing of the depth-first traversal model. The core functionalities of the framework include: a node access mechanism, defining the order and method of node access; backtracking control, managing backtracking behavior during traversal; state management, maintaining the access status of nodes (e.g., unvisited, being visited, visited); and event hooks, allowing the execution of custom logic when specific traversal events (e.g., starting to visit a node, completing a node visit) occur. Therefore, this traversal framework provides a structured foundation for subsequent analysis and numbering systems, ensuring that each part of the call chain can be systematically processed.

[0096] Next, based on a depth-first search traversal framework, the importance of each model node is analyzed, and its influence weight is calculated. The influence weight is a numerical value representing the relative importance of a node in test coverage; a higher weight indicates that the node needs to be tested more frequently. Specifically, the calculation process considers several factors: First, frequency, i.e., the number of times the node appears in multiple call chains. Nodes with high frequency of occurrence are usually common components or core functions, with a wider impact and should be tested first. This metric is quantified by counting the number of times each node appears in different call paths. Second, distance, i.e., the distance between the node and the call chain of the changed function. The closer the distance, the stronger the correlation, and the greater the likelihood of being affected by the change. For the changed function itself, the distance is 0; for nodes that directly call the changed function, the distance is 1; and so on. Third, complexity, i.e., the code complexity of the function containing the node. Complexity is usually measured using "cyclomatic complexity," which calculates the number of decision points in the code (such as if statements, loops, and conditional expressions). The higher the complexity, the more prone the function is to errors and the more difficult it is to fully test. Finally, historical defect density is evaluated based on historical version control and defect tracking data. Code regions that have historically had frequent issues typically carry higher risks and require more thorough testing. Therefore, this embodiment combines the above factors and uses a weighted formula to calculate the final impact weight of each node. Then, based on a pre-defined graph theory critical path algorithm, such as Dijkstra's algorithm or Critical Path Analysis, critical paths for testing are identified. These critical paths refer to call paths containing high-weight nodes, having the greatest impact, or posing the highest risk; these paths require priority testing to minimize the risk of changes introducing defects.

[0097] Furthermore, based on the preset depth-first search traversal order and the critical test path identified in the previous step, a unique DFS number is generated for each node. The DFS number is a special identifier used to uniquely identify each node during the depth-first traversal and to reflect the hierarchical and sequential relationships between nodes. In this embodiment, the DFS number adopts a specific format: <Change Function Identifier>.<Call Depth>.<Sibling Number>.<Test Priority>. The change function identifier is an alphanumeric code that uniquely identifies each change function, such as "F1" representing the first change function. The call depth indicates the node's level in the call chain, such as "2" representing the second-level call. The sibling number is the order in which nodes at the same level are visited during the depth-first traversal, such as "3" representing the third node visited at that level. "Test priority is a priority level calculated based on the influence weight of nodes, usually divided into multiple levels (e.g., 1-5, where 1 represents the highest priority). The advantages of this numbering system are: it intuitively reflects the call relationship, allowing for quick understanding of the node's position and relationship in the call chain; it supports sorting and grouping, facilitating the organization of test work according to logical relationships; and it includes priority information, guiding the allocation of test resources and the arrangement of test order. After generating DFS numbers, this embodiment associates these numbers with the corresponding lines of code to be tested, generating a list of lines of code to be tested carrying DFS numbers. This list is a structured data set, where each record contains code line information (file path, line number, code content) and the corresponding DFS number. By configuring the numbered list, the testing process becomes more organized, facilitating the tracking of test progress and the management of test resources."

[0098] In some embodiments, generating a DFS number based on a preset depth-first search traversal order and the test critical path, and generating a line of code to be tested carrying the DFS number, includes:

[0099] Based on the lines of code to be tested carrying the DFS number, a coverage target roadmap is determined. A test progress tracking mechanism is established by prioritizing the DFS numbers. A test coverage guidance strategy is constructed based on the coverage target roadmap, the priority of the DFS numbers, and the test progress tracking mechanism. A coverage growth curve analysis tool is built based on the test coverage guidance strategy, and test efficiency is evaluated using this tool. An adaptive test strategy is created based on the test efficiency, which instructs for dynamically adjusting test resource allocation and optimizing test execution order. Historical test data for each DFS number is recorded. When code changes are detected, the tested DFS numbers affected by the changes are analyzed based on the historical test data, and a set of DFS numbers requiring regression testing is recommended, thus achieving incremental testing and regression analysis.

[0100] In this embodiment, a coverage target roadmap is determined based on the generated lines of code to be tested carrying DFS numbers. It should be noted that a coverage target roadmap is a planning tool that details all code points that need to be covered during the testing process, the coverage order, and the coverage goals. This coverage target roadmap is similar to a route map in a navigation system, providing clear guidance to the testing team and ensuring that the testing work proceeds in an orderly manner. The roadmap is constructed based on multiple dimensions: code structure dimension, organizing the test path according to the hierarchical structure of the call chain; importance dimension, prioritizing the testing of high-risk areas; dependency dimension, considering calls and data dependencies between code to ensure a reasonable test order; and resource constraint dimension, considering the availability of test resources and time constraints. Therefore, this coverage target roadmap is usually presented in a visual form, such as a call graph, heatmap, or Gantt chart, to intuitively display the entire test plan.

[0101] Simultaneously, a test progress tracking mechanism is determined based on the priority of the DFS numbers. This mechanism is a system for monitoring and managing the test execution status, recording the status changes of each test item in real time. It defines the lifecycle states of test items, such as "not tested," "in testing," "test completed," and "test failed," and provides triggering conditions and operations for state transitions. The tracking system typically uses a database or distributed storage to record detailed information for each test item corresponding to each DFS number: current status, test start and completion times, test results, coverage data, and related issues. Based on the coverage target roadmap, the priority of DFS numbers, and the test progress tracking mechanism, this embodiment constructs a complete test coverage guidance strategy. It should be noted that the test coverage guidance strategy is a high-level decision-making framework that guides the testing team on how to most effectively execute testing work, ensuring that important code areas are prioritized for coverage. The strategy includes: a test order strategy to guide the team to execute tests along the optimal path; resource allocation guidelines, including how to allocate testers and computing resources; key point monitoring prompts to identify code areas requiring special attention; and coverage goals and milestones to set coverage targets for each stage.

[0102] Next, based on the test coverage guidance strategy, a coverage growth curve analysis tool is constructed. The coverage growth curve is a dynamic visualization tool that shows how coverage changes as testing progresses. This curve plots time or test execution volume on the horizontal axis and coverage percentage on the vertical axis, reflecting the efficiency and progress of the testing process. The core functions of the analysis tool include: real-time data collection, continuously monitoring test execution and coverage changes; trend analysis, calculating the rate and pattern of coverage growth; predictive modeling, predicting future coverage development based on current trends; and anomaly detection, identifying abnormal situations in coverage growth, such as stagnant growth or sudden declines. By analyzing the shape and characteristics of the coverage growth curve, the system evaluates testing efficiency. Testing efficiency is an indicator that measures the return on investment in testing work, usually defined as the coverage growth achieved per unit of testing resources (such as man-hours or machine-hours). An efficient testing process should be represented by a continuous and stable upward curve, while inefficient processes will be represented by a flat or fluctuating curve. Evaluation metrics include: coverage growth rate, i.e., the increase in coverage per unit time; marginal coverage benefit, i.e., the additional coverage gained from each additional test case; and critical path coverage speed, i.e., the coverage completion rate of high-priority paths. Based on these evaluation results, an adaptive testing strategy is created. An adaptive testing strategy is a dynamically adjusted test execution plan that automatically adjusts testing focus and methods based on real-time feedback and environmental changes. Unlike static test plans, adaptive strategies can optimize in real time based on test progress, concentrating resources on the areas most in need of testing. Key features of the strategy include: dynamic resource allocation, adjusting the allocation of human and computing resources based on coverage feedback; test order optimization, adjusting the execution order of test cases, prioritizing tests that may bring higher coverage gains; test depth adjustment, increasing the depth and comprehensiveness of testing in critical or problem areas; and automatic learning, continuously optimizing the decision model based on historical test results.

[0103] Finally, record the historical test data for each DFS number. Historical test data is a detailed record of test execution, including test time, test environment, test results, coverage data, and issues found. This data is stored in a dedicated test database or test management system to provide a basis for future testing decisions. Key recorded information includes: execution timestamps, recording the exact time of the test; test environment configuration, including hardware, operating system, and software version information; test result status, such as pass, fail, or block; coverage, recording which lines of code were executed and the number of times; and associated defects, recording the relevant defect identifiers if the test found issues.

[0104] Subsequently, when the system detects new code changes (e.g., through continuous integration systems or version control hooks), it analyzes historical test data to identify the tested code numbers affected by the changes. For example, this analysis process involves several techniques: code dependency analysis to identify areas potentially affected by code changes; call chain tracing to determine the upstream and downstream call relationships of the changed functions; and historical correlation analysis to identify code areas that frequently change together or experience issues together, based on historical data. After the analysis is complete, a set of code numbers requiring regression testing is recommended. Regression testing refers to retesting previously tested functions after a software change to ensure that the change does not break existing functionality. The recommendation algorithm considers several factors: the direct impact of the change (code that is directly modified or may be directly affected by the modification); historical relevance (identifying code areas highly related to the current change based on historical data); risk assessment (considering the importance, complexity, and historical problem rate of the code); and testing cost (balancing test coverage and test resource consumption). This approach achieves incremental testing and regression analysis, avoiding the inefficient practice of performing full testing for every change. It only tests the parts that truly need re-verification, significantly improving the efficiency of test iteration, making it particularly suitable for frequent code changes and continuous integration scenarios in agile development environments.

[0105] In some embodiments, parsing the code coverage data to obtain the actually covered code lines, comparing the code lines to be tested with the actually covered code lines, determining coverage metric data based on the call chain according to a second comparison result, and determining the test coverage evaluation result based on the coverage metric data include:

[0106] The code coverage data is parsed to extract information on all lines of code actually covered by the test. Coverage information irrelevant to the lines of code under test is filtered out to generate the actually covered lines of code. The actually covered lines of code are compared with the lines of code under test to calculate the coverage of directly changed code, the coverage of call chain related lines of code, and the overall coverage. Multi-dimensional coverage metrics are output based on the coverage of directly changed code, the coverage of call chain related lines of code, and the overall coverage. Uncovered lines of code are selected and categorized into corresponding changed functions and call chains. The importance and risk level of the selected lines of code are analyzed to identify uncovered code regions. The actually covered lines of code, the coverage metrics data, and the uncovered code regions are summarized to obtain the test coverage evaluation result.

[0107] In this embodiment, the collected code coverage data is parsed to extract information on all lines of code actually covered by the test. The code coverage data is raw data about code execution collected during test execution, typically generated by coverage tools (such as JaCoCo) and stored in a specific format (such as a binary .exec file or an XML / HTML report). For example, the parsing process involves several steps: first, data loading, reading the raw coverage data file from the storage location; then, format parsing, extracting structured information based on the data format (such as JaCoCo's binary format); next, metadata association, associating the coverage data with source code files and line number information; and finally, data transformation, converting the raw data into a standardized internal representation.

[0108] After parsing, code line information is extracted. This is a detailed record of the execution status of each line of code, typically including: file path (the full path to the source code file); line number (the precise location of the code within the file); execution status (marking whether the line of code was executed (covered); execution count (the total number of times the line of code was executed); and coverage type, such as line coverage, branch coverage, or path coverage. From this information, coverage information irrelevant to the lines of code being tested needs to be filtered out. Irrelevant information mainly includes: code execution information of the testing framework itself, such as internal calls of the JUnit framework; execution status of auxiliary code and utility classes, such as logging tools or general libraries; and code execution of system-level components and third-party libraries. The filtering process usually uses package name prefixes or class name pattern matching to retain only coverage information directly related to the lines of code being tested. After filtering, a list of actually covered code lines is generated. This is a concise and accurate dataset containing all relevant code lines actually executed during the test, providing foundational data for subsequent coverage analysis.

[0109] Next, the actual covered code lines obtained in the previous step are compared in detail with the generated code lines to be tested, and coverage metrics across multiple dimensions are calculated. The comparison process is a set operation, calculating the intersection and difference of the two sets of code lines to determine which code lines to be tested are covered and which are not.

[0110] For example, based on the comparison results, three key coverage metrics are calculated: Direct change code coverage refers to the coverage of directly modified and newly added lines of code within the changed function. Optionally, the calculation formula is: (Number of covered directly changed lines of code ÷ Total number of directly changed lines of code) × 100%. This metric is similar to the traditional coverage concept, reflecting the adequacy of testing the directly changed portion. Call chain related code line coverage refers to the coverage of the lines of code (call points) that call the changed function. The calculation formula is: (Number of covered call point lines of code ÷ Total number of call point lines of code) × 100%. This innovative metric reflects the degree of testing on the scope of the change's impact. Overall coverage is the overall coverage considering the above two aspects. The calculation formula is: (Total number of covered lines of code ÷ Total number of lines of code to be tested) × 100%. This metric provides a global perspective on coverage, comprehensively evaluating the comprehensiveness of the test. In addition to these three basic metrics, this embodiment may also calculate more granular coverage data: function-level coverage, calculating the coverage of each changed function individually; call chain depth coverage, calculating coverage at different levels of the call chain; and module-level coverage, calculating coverage by code module or package. These multi-dimensional coverage metrics provide a comprehensive and in-depth basis for test quality assessment, far exceeding traditional single coverage metrics.

[0111] Next, this embodiment filters out all lines of code not covered by the tests, i.e., those lines of code not executed in the actual tests. These uncovered lines of code represent blind spots or deficiencies in the testing and require special attention. These lines of code are categorized into corresponding modified functions and call chains, forming a structured mapping of uncovered code. The categorization process is based on the source information of the lines of code, determining which modified function or call chain each line of uncovered code belongs to, facilitating targeted supplementary testing later. Next, the importance and risk level of these uncovered lines of code are analyzed. Importance assessment considers several factors: the functional criticality of the code, such as core business logic, data processing, or security verification, which are generally more important; usage frequency, as frequently executed code has a wider impact; and business value, as code related to high-value business functions is more important. Risk level assessment considers: code complexity, as complex code is more prone to errors; density of historical issues, as areas with a history of problems are at higher risk; scope of changes, as code that has undergone significant modifications is generally at greater risk; and exception handling, as error handling and boundary condition-related code are often high-risk areas. Based on these analyses, the system uses a hierarchical system (such as three levels: high, medium, and low, or five levels: 1-5) to label the importance and risk level of each uncovered code region. Ultimately, based on these ratings, uncovered code regions are identified, especially those that simultaneously possess both high importance and high risk levels. These regions represent major deficiencies in testing and require priority for supplementary testing.

[0112] Finally, this embodiment summarizes the results of the preceding steps to form a complete test coverage evaluation result. For example, this evaluation result is a comprehensive report containing several key components: First, a list of actually covered lines of code, detailing all lines of code executed by the tests, including file paths, line numbers, and execution counts; second, coverage metric data, including multi-dimensional metrics such as direct change code coverage, call chain coverage, and overall coverage, presented as percentages, and possibly including historical trend comparisons; third, an analysis of uncovered code areas, highlighting important and high-risk uncovered code and providing detailed location and context information; and finally, improvement measures, proposing specific test improvement measures based on the analysis results, such as the types of test cases that need to be added, testing techniques, or areas that should be prioritized for testing.

[0113] Specifically, the evaluation results can be presented in several forms: a detailed technical report containing complete data and analysis; a visual dashboard using charts and heatmaps to intuitively display coverage; and an executive summary providing management with a high-level quality assessment. This comprehensive evaluation not only provides numerical coverage figures but also includes in-depth analysis and improvement strategies for test quality, enabling the testing team to clearly understand current testing deficiencies and design targeted supplementary test cases to improve the comprehensiveness and effectiveness of testing. In this way, the test coverage evaluation method of this invention provides a more comprehensive and in-depth quality assurance mechanism than traditional methods, making it particularly suitable for complex Java application development environments.

[0114] like Figure 2 As shown, this embodiment of the invention provides a system for evaluating test coverage based on Java call chains. The system includes:

[0115] The data acquisition module 201 is used to acquire the project code of the test version, parse the project code into bytecode files, extract the method call relationship of the entire project based on the bytecode files, and generate a code call relationship graph from the method call relationship.

[0116] The model building module 202 is used to compare the project code of the test version with the code of the pre-obtained online master version, identify the difference function according to the first comparison result, and build a call chain tree structure with the difference function as the root node based on the code call relationship graph.

[0117] The data processing module 203 is used to parse the difference function to obtain the direct code change line of the difference function, identify the relevant code line on the call chain of each call point based on the call chain tree structure, take it as the call point code line, and summarize the direct code change line and the call point code line to generate the code line to be tested.

[0118] Test module 204 is used to obtain code coverage statistics tools, configure corresponding test execution environments according to the code coverage statistics tools, test test cases corresponding to the lines of code to be tested in the test execution environment, and collect code coverage data during the test process;

[0119] The parsing and evaluation module 205 is used to parse the code coverage data to obtain the actual covered code lines, compare the code lines to be tested with the actually covered code lines, determine the coverage index data based on the call chain according to the second comparison result, and determine the test coverage evaluation result according to the coverage index data.

[0120] In this embodiment, the data acquisition module is responsible for acquiring the project code of the test version and parsing it into bytecode files. Then, bytecode analysis tools (such as ASM) are used to analyze these files and extract the call relationships between all methods in the entire project. Based on these call relationships, a complete code call relationship graph is constructed as the basis for subsequent analysis.

[0121] Next, the model building module is responsible for comparing the code of the test version with the online master version, identifying all changed and added functions (difference functions). Then, based on the code call relationship graph generated by the data acquisition module, a complete call chain tree structure is built with each difference function as the root node, showing how these functions are called by the upper-level code.

[0122] Next, the data processing module is responsible for parsing the difference functions and extracting the directly changed lines of code. Simultaneously, based on the call chain tree structure of the model building module, it identifies the relevant lines of code (call points) on the call chain. Then, these two sets of lines of code are aggregated and deduplicated to form a complete list of lines of code to be tested.

[0123] Furthermore, the testing module is responsible for selecting and configuring a suitable code coverage statistics tool (such as JaCoCo), and setting the collection method and storage format for coverage data. Then, it executes test cases in the configured test environment to ensure that these test cases cover the lines of code to be tested and collects coverage data during the testing process.

[0124] Furthermore, the parsing and evaluation module is responsible for parsing the coverage data collected by the testing module and extracting the lines of code that were actually covered by the tests. Then, these actually covered lines of code are compared with the lines of code to be tested generated by the data processing module to calculate multi-dimensional coverage metrics (such as direct change code coverage, call chain coverage, etc.). Simultaneously, uncovered code regions are identified and categorized according to their importance and risk level. Finally, a complete test coverage evaluation result is generated, providing the testing team with a comprehensive quality assessment.

[0125] In the system described in the above embodiment, the data flow between modules is clear and explicit: the output of the data acquisition module (code call relationship graph) is the input of the model building module; the output of the model building module (call chain tree structure) is the input of the data processing module; the output of the data processing module (code lines to be tested) guides the test execution of the testing module; and the output of the testing module (coverage data) is the input of the parsing and evaluation module. This modular design gives the system good maintainability and scalability, enabling it to adapt to Java projects of different sizes and complexities.

[0126] The method and system for evaluating test coverage based on Java call chains provided in this invention comprehensively identify the impact scope of code changes by analyzing code call relationships and constructing a call chain tree structure; it provides more comprehensive coverage targets for testing by statistically analyzing directly changed code lines and call point code lines; it provides more accurate test quality assessment through multi-dimensional coverage metric calculation; and it optimizes test execution order and resource allocation through a depth-first search numbering mechanism. These innovations extend test coverage evaluation beyond simple code line coverage to include impact analysis of the entire call chain, significantly improving the comprehensiveness and effectiveness of testing and providing stronger support for software quality assurance.

[0127] The above description is merely a specific embodiment of the present invention, but the scope of protection of the present invention is not limited thereto. Any variations or substitutions that can be easily conceived by those skilled in the art within the technical scope disclosed in the present invention should be included within the scope of protection of the present invention. Therefore, the scope of protection of the present invention should be determined by the scope of the claims.

Claims

1. A method for evaluating test coverage based on Java call chain, characterized in that, include: Obtain the project code of the test version, parse the project code into bytecode files, extract the method call relationship of the entire project based on the bytecode files, and generate a code call relationship graph from the method call relationship; By comparing the project code of the test version with the code of the pre-obtained online master version, the difference function is identified based on the first comparison result, and a call chain tree structure is constructed with the difference function as the root node based on the code call relationship graph. The difference function is parsed to obtain the direct code change line of the difference function. Based on the call chain tree structure, the relevant code line on the call chain where each call point is located is identified as the call point code line. The direct code change line and the call point code line are summarized to generate the code line to be tested. Obtain a code coverage statistics tool, configure the corresponding test execution environment according to the code coverage statistics tool, test the test cases corresponding to the code lines to be tested in the test execution environment, and collect code coverage data during the test process; The code coverage data is parsed to obtain the actual covered code lines, and the code lines to be tested are compared with the actual covered code lines. The coverage metric data based on the call chain is determined according to the second comparison result, and the test coverage evaluation result is determined according to the coverage metric data. The step of comparing the test version's project code with the pre-obtained online master version's code, identifying the difference function based on the first comparison result, and constructing a call chain tree structure with the difference function as the root node based on the code call relationship graph includes: The pre-defined call chain tracing problem is transformed into a constraint satisfaction problem, and the set of variables and constraints are determined. Based on the constraint satisfaction problem, the set of variables, and the constraints, a constraint satisfaction problem model is constructed. The set of variables consists of functions that form a call relationship with the modified function, and the constraints include the call relationship constraints between functions in the set of variables and the constraints that the modified function must be on the call chain. The constraint satisfaction problem is processed using a pre-defined heuristic fast approximation algorithm, and the variable domain is narrowed by applying a pre-defined Arc consensus algorithm during the processing. An approximate solution is found using the minimum conflict heuristic, and a possible call chain set is generated based on the approximate solution. Based on the call chain set, the optimal call chain set is gradually approximated through incremental adjustments, and the call chain tree structure is optimized and integrated based on the optimal call chain set. The process of using a pre-defined heuristic fast approximation algorithm to handle the constraint satisfaction problem, applying a pre-defined Arc consensus algorithm to narrow the variable domain during the process, and using a minimum conflict heuristic to find an approximate solution includes: Create a core extender interface, wherein the core extender interface is used to adapt to multiple extender types, including direct method invocation extenders, reflection invocation extenders, lambda expression extenders, and interface implementation invocation extenders; Based on the core extender interface, extenders are chained together to form a call analysis pipeline, and an extender-based code parsing architecture is constructed. Based on the code parsing architecture and the call analysis pipeline, the preset call chain search task is decomposed into independent subtasks through the preset Fork / Join framework. For the decomposed subtasks, the call chain analysis of each modified function is performed in parallel, and a preset work-stealing algorithm is used to balance the computational load during the parallel processing. According to the preset call depth, the call relationship of the parallel processing results is decoded layer by layer. During the layer-by-layer decoding process, weight analysis is performed on each call chain node to identify critical paths. Memory usage is optimized by using a preset sparse matrix storage to obtain an approximate solution.

2. The method according to claim 1, characterized in that, The process of parsing the project code into bytecode files, extracting the method call relationships of the entire project based on the bytecode files, and generating a code call relationship graph from the method call relationships includes: Using a preset Java compilation tool, the project code of the test version is compiled into a bytecode file to be processed, and the bytecode file to be processed is loaded into a preset JVM runtime environment and the bytecode file is output. Obtain a bytecode analysis framework and configure the analysis depth and scope of the bytecode analysis tools in the bytecode analysis framework. Use the analysis tools in the bytecode analysis framework to scan the bytecode file and analyze the method instructions in each class file according to the analysis depth and the analysis scope. Identify the method call relationship between methods based on the method instructions. Based on the method call relationship, a global call relationship graph is constructed, and the code call relationship graph is determined based on the global call relationship graph. Each node in the global call relationship graph represents a method, and the edges in the global call relationship graph represent the method call relationship.

3. The method according to claim 2, characterized in that, The process involves comparing the test version's project code with the pre-obtained online master version's code, identifying the difference functions based on the first comparison result, and constructing a call chain tree structure with the difference functions as root nodes based on the code call relationship graph, including: Using a preset version control tool, the project code of the test version is compared with the code of the online master version. Based on the first comparison result, newly added, modified and / or deleted files and code segments are extracted from the project code to mark the corresponding difference functions and their corresponding function positions. The difference functions include modified functions and newly added functions. Based on the function location, the corresponding difference function is located in the code call relationship graph. With each of the changed functions as the root node, a call relationship tree is constructed. The call relationship tree is used to indicate the object that calls the changed function. For the called relationship tree, a preset recursive algorithm is used to trace the calling relationship upwards layer by layer to generate an initial calling tree structure, which is used to indicate the path information of the calling relationship; In the initial call tree structure, starting from each of the modified functions, the call tree is traced upwards until the preset outermost entry function is reached, and the call chain tree structure is formed based on the call chain of all the modified functions.

4. The method according to claim 3, characterized in that, The process involves parsing the difference function to obtain its direct code change lines. Based on the call chain tree structure, relevant code lines on the call chain of each call point are identified as call point code lines. The direct code change lines and call point code lines are then aggregated to generate the code lines to be tested, including: The difference function is parsed, and the newly added and modified code lines in each change function are extracted as direct code change lines. The code position of each direct code change line is recorded, and the list of direct code change lines of the change function is output. The list of direct code change lines includes at least one direct code change line and its code position. Traverse all call paths in the call chain tree structure, identify the line of code where the call point is located, and use it as the line of code for the call point. Based on the call point and the corresponding line of code for the call point, output a list of relevant lines of code on the call chain. The direct code change line list and the related code line list on the call chain are merged, duplicate code lines are removed, and sorted by file name and line number to obtain the code line to be tested.

5. The method according to claim 4, characterized in that, The code coverage statistics tool is configured with a corresponding test execution environment, and test cases corresponding to the lines of code to be tested are performed in the test execution environment to collect code coverage data during the testing process, including: Evaluate multiple Java code coverage tools, and select the corresponding code coverage statistics tool based on project characteristics. Configure the core parameters of the code coverage statistics tool in a preset project build system, and output the configured project build file according to the core parameters. The core parameters include exclusion rules and output format. Based on the project build file, configure the coverage proxy parameters and set the storage location and format of the coverage data. Based on the coverage proxy parameters, the storage location and format of the coverage data, create a startup script and determine the appropriate test execution environment. The startup script is used to instruct the collection of coverage data during test execution. In the test execution environment, test cases corresponding to the lines of code to be tested are executed to obtain code coverage data during the test process.

6. The method according to claim 1, characterized in that, The process of summarizing the direct code change lines and the call point code lines to generate the code lines to be tested also includes: Based on the call chain tree structure, a depth-first traversal model is constructed, and a depth-first search traversal framework is established based on the depth-first traversal model. The node representation of the model node in the depth-first traversal model includes function information, call point position, and depth information. Based on the frequency of the model node in multiple call chains, the distance between the model node and the modified function, the complexity of the function containing the model node, and the historical defect density determined by the depth-first search traversal framework, the influence weight of each model node is calculated, and the test critical path in the call chain is identified according to the preset graph theory critical path algorithm. Based on the preset depth-first search traversal order and the test critical path, a DFS number is generated, and a line of code to be tested carrying the DFS number is generated. The number format of the DFS number includes the change function identifier, call depth, sibling sequence number and test priority.

7. The method according to claim 6, characterized in that, Based on the preset depth-first search traversal order and the test critical path, a DFS number is generated, and a line of code to be tested carrying the DFS number is generated, including: Based on the lines of code to be tested carrying the DFS number, a coverage target roadmap is determined, a test progress tracking mechanism is determined according to the priority of the DFS number, and a test coverage guidance strategy is constructed based on the coverage target roadmap, the priority of the DFS number, and the test progress tracking mechanism. Based on the test coverage guidance strategy, a coverage growth curve analysis tool is constructed, and the test efficiency is evaluated through the coverage growth curve analysis tool. An adaptive test strategy is created based on the test efficiency. The adaptive test strategy is used to indicate the dynamic adjustment of test resource allocation and optimization of test execution order. Record historical test data for each DFS number, and when a code change is detected, analyze the tested numbers affected by the change based on the historical test data, and recommend a set of numbers that need regression testing, thus realizing incremental testing and regression analysis.

8. The method according to claim 7, characterized in that, The process of parsing the code coverage data to obtain the actually covered code lines, comparing the code lines to be tested with the actually covered code lines, determining coverage metric data based on the call chain based on the second comparison result, and determining the test coverage evaluation result based on the coverage metric data includes: The code coverage data is parsed to extract information on all lines of code actually covered by the test. Coverage information that is irrelevant to the lines of code to be tested is filtered out from the code line information to generate the lines of code actually covered. The actual covered lines of code are compared with the lines of code to be tested. The coverage of directly changed code, the coverage of call chain related lines of code, and the overall coverage are calculated. Multi-dimensional coverage metrics are output based on the coverage of directly changed code, the coverage of call chain related lines of code, and the overall coverage. Filter out lines of code that have not been covered by the test, categorize the filtered lines of code into the corresponding change functions and call chains, and identify uncovered code areas based on the importance and risk level of the filtered lines of code. The test coverage evaluation results are obtained by summarizing the actual lines of code covered, the coverage metric data, and the uncovered code regions.

9. A system for evaluating test coverage based on Java call chain, characterized in that, include: The data acquisition module is used to acquire the project code of the test version, parse the project code into bytecode files, extract the method call relationship of the entire project based on the bytecode files, and generate a code call relationship graph from the method call relationship. The model building module is used to compare the project code of the test version with the pre-obtained online master version code, identify the difference functions based on the first comparison result, and construct a call chain tree structure with the difference functions as the root nodes based on the code call relationship graph, including: The pre-defined call chain tracing problem is transformed into a constraint satisfaction problem, and the set of variables and constraints are determined. Based on the constraint satisfaction problem, the set of variables, and the constraints, a constraint satisfaction problem model is constructed. The set of variables consists of functions that form a call relationship with the modified function, and the constraints include the call relationship constraints between functions in the set of variables and the constraints that the modified function must be on the call chain. The constraint satisfaction problem is processed using a pre-defined heuristic fast approximation algorithm, and the variable domain is narrowed by applying a pre-defined Arc consensus algorithm during the processing. An approximate solution is found using the minimum conflict heuristic, and a possible call chain set is generated based on the approximate solution. Based on the call chain set, the optimal call chain set is gradually approximated through incremental adjustments, and the call chain tree structure is optimized and integrated based on the optimal call chain set. The process of using a pre-defined heuristic fast approximation algorithm to handle the constraint satisfaction problem, applying a pre-defined Arc consensus algorithm to narrow the variable domain during the process, and using a minimum conflict heuristic to find an approximate solution includes: Create a core extender interface, wherein the core extender interface is used to adapt to multiple extender types, including direct method invocation extenders, reflection invocation extenders, lambda expression extenders, and interface implementation invocation extenders; Based on the core extender interface, extenders are chained together to form a call analysis pipeline, and an extender-based code parsing architecture is constructed. Based on the code parsing architecture and the call analysis pipeline, the preset call chain search task is decomposed into independent subtasks through the preset Fork / Join framework. For the decomposed subtasks, the call chain analysis of each modified function is performed in parallel, and a preset work-stealing algorithm is used to balance the computational load during the parallel processing. According to the preset call depth, the call relationship of the parallel processing results is decoded layer by layer. During the layer-by-layer decoding process, weight analysis is performed on each call chain node to identify critical paths. A preset sparse matrix storage is used to optimize memory usage and obtain an approximate solution. The data processing module is used to parse the difference function to obtain the direct code change line of the difference function, identify the relevant code line on the call chain of each call point based on the call chain tree structure, take it as the call point code line, and summarize the direct code change line and the call point code line to generate the code line to be tested. The testing module is used to obtain code coverage statistics tools, configure the corresponding test execution environment according to the code coverage statistics tools, test test cases corresponding to the lines of code to be tested in the test execution environment, and collect code coverage data during the testing process. The parsing and evaluation module is used to parse the code coverage data to obtain the actual covered code lines, compare the code lines to be tested with the actually covered code lines, determine the coverage index data based on the call chain based on the second comparison result, and determine the test coverage evaluation result based on the coverage index data.

Citation Information

Patent Citations

  • Source code change analysis method, system and equipment

    CN119597657A