Skip to content

Empty else-block in case of possibly nullable expected value in parametrized test generation #518

Closed
@sofurihafe

Description

@sofurihafe

Description

Generating test for streamOfExample method results in different outcomes when generating in runIde and as a sample.
RunIde version has empty else branch.
Also, it's important to notice that there are different actual and expectedResult types (Object vs. Stream).

To Reproduce

  1. Run runIde, generate parametrized test for streamOfExample,
  2. Run BaseStreamExampleTest as a sample (not in runIde),
  3. Compare generated tests.

Actual behavior

in runIde:
image

public class BaseStreamExampleTest {
    ///region Test suites for executable playground.BaseStreamExample.streamOfExample

    ///region Parameterized test for method streamOfExample(java.lang.Integer[])

    @ParameterizedTest
    @MethodSource("provideDataForStreamOfExample")
    public void parameterizedTestsForStreamOfExample(BaseStreamExample baseStreamExample,
                                                     Integer[] values,
                                                     Object expectedResult,
                                                     Class expectedError
    ) {
        try {
            Object actual = baseStreamExample.streamOfExample(values);

            if (expectedResult == null) {
                assertNull(actual);
            } else {
            }
        } catch (Throwable throwable) {
            assertTrue(expectedError.isInstance(throwable));
        }
    }
    ///endregion

    ///endregion

    ///region Data providers and utils methods

    public static ArrayList provideDataForStreamOfExample() throws Exception {
        ArrayList argList = new ArrayList();

        <...>

        return argList;
    }

    <...>
}

as a sample:

public class BaseStreamExampleGeneratedTest {
    ///region Test suites for executable org.utbot.examples.stream.BaseStreamExample.streamOfExample
    
    ///region Parameterized test for method streamOfExample(java.lang.Integer[])
    
    @ParameterizedTest
    @MethodSource("provideDataForStreamOfExample")
    public void parameterizedTestsForStreamOfExample(BaseStreamExample baseStreamExample, java.lang.Integer[] integerArray, Stream expectedResult) {
        Stream actual = baseStreamExample.streamOfExample(integerArray);
        
        if (expectedResult == null) {
            assertNull(actual);
        } else {
            assertTrue(deepEquals(expectedResult, actual));
        }
    }
    ///endregion
    
    ///endregion
    
    ///region Data providers and utils methods
    
    public static java.util.ArrayList provideDataForStreamOfExample() {
        ArrayList argList = new ArrayList();
        
        <...>
        
        return argList;
    }

    <...>
}

Additional details
Cause reason is generic execution selection heuristics. When selecting it we do not depend on result type fullness (whether it is empty array or filled array, it does not matter right now). In our case we have three collected executions, but we select execution with empty values array. That is why the else-branch is empty. Deep equals does not know how to compare empty arrays, lists, etc.
As suggestions there are two options:

  1. Adapt generic execution selection,
  2. Render assertTrue(deepEquals(expectedResult, actual)) or assertNotNull(actual) every time,
  3. If possible, check else-branch body absence beforehand, and choose not empty if there is one among all executions.

Metadata

Metadata

Labels

comp-codegenIssue is related to code generatorctg-bugIssue is a bug

Type

No type

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions