[Python] Merging two Java unit test classes into one [closed]

Discussão em 'Python' iniciado por Stack, Abril 7, 2025.

  1. Stack

    Stack Membro Participativo

    I am working on a unit test generation for Java code, but in Python. I am generating unit tests in two iterations. First one is the initial generation, second one is coverage-guided generation. When done, I want to merge them into one fully working unit test. E.g, if one helper class exists in one or two of them, we keep only one version of it. Same goes for helper methods, and helper fields. If a test case already exists in unit test 1, I'd want to add 'Enhanced' suffix to its name, so it'll compile. I tried doing it just so:

    """
    Merges two Java unit test class strings, considering imports, class-level variables, and test methods.
    If a method in java_test_2 has the same name as one in java_test_1, it appends 'Enhanced' to its name.

    Parameters:
    - java_test_1 (str): The first Java test class as a string.
    - java_test_2 (str): The second Java test class as a string.

    Returns:
    - str: The merged Java test class.
    """
    # Extract imports
    imports_1 = set(re.findall(r'^import .*?;', java_test_1, re.MULTILINE))
    imports_2 = set(re.findall(r'^import .*?;', java_test_2, re.MULTILINE))
    merged_imports = sorted(imports_1 | imports_2) # Merge and sort imports


    # Extract class-level variables (fields)
    fields_1 = set(re.findall(r'(private|protected|public)?\s+\w+\s+\w+\s*;', java_test_1))
    fields_2 = set(re.findall(r'(private|protected|public)?\s+\w+\s+\w+\s*;', java_test_2))
    merged_fields = sorted(fields_1 | fields_2)

    # Function to extract full Java methods, handling nested brackets
    def extract_test_methods(java_code):
    method_pattern = re.compile(r'@Test\s+public\s+void\s+\w+\s*\(.*?\)\s*\{', re.MULTILINE)
    methods = []
    for match in method_pattern.finditer(java_code):
    start = match.start()
    open_braces = 0
    end = start
    for i in range(start, len(java_code)):
    if java_code == '{':
    open_braces += 1
    elif java_code == '}':
    open_braces -= 1
    if open_braces == 0:
    end = i + 1
    break
    methods.append(java_code[start:end])
    return methods

    # Extract test methods properly with full bodies
    test_methods_1_full = extract_test_methods(java_test_1)
    test_methods_2_full = extract_test_methods(java_test_2)

    # Extract method names
    test_method_names_1 = set(re.findall(r'@Test\s+public\s+void\s+(\w+)\s*\(', java_test_1))
    test_methods_2_dict = {}

    for method in test_methods_2_full:
    method_name_match = re.search(r'@Test\s+public\s+void\s+(\w+)\s*\(', method)
    if method_name_match:
    method_name = method_name_match.group(1)
    if method_name in test_method_names_1:
    # Rename conflicting test methods
    new_method_name = method_name + "Enhanced"
    method = re.sub(rf'(@Test\s+public\s+void\s+){method_name}(\s*\()', rf'\1{new_method_name}\2', method)
    test_methods_2_dict[new_method_name] = method
    else:
    test_methods_2_dict[method_name] = method

    # Merge test methods, avoiding duplicates
    merged_test_methods = list(set(test_methods_1_full + list(test_methods_2_dict.values())))
    merged_test_methods.sort() # Sort for consistency

    # Construct the merged Java test class
    merged_java_test = "\n".join(merged_imports) + "\n\n"
    merged_java_test += f"public class {class_name} {{\n\n"

    # Add merged fields
    for field in merged_fields:
    merged_java_test += f" {field}\n"

    merged_java_test += "\n"

    # Add merged test methods
    for method in merged_test_methods:
    merged_java_test += f" {method}\n\n"

    merged_java_test += "}"

    return merged_java_test


    Though for many cases it does not merge it good, and seems to lack the robustness. E.g it nests two tests one inside another, etc. Any ideas how can I modify it to achieve my desired output? Thanks

    Continue reading...

Compartilhe esta Página