Skip to content

Symbolic execution cannot generate tests in case of specific Random usage #2520

Closed
@tyuldashev

Description

@tyuldashev

Description
In some cases when random numbers are generated in fixed loop, symbolic engine cannot generate any test.

To Reproduce

  1. Install UnitTestBot plugin built from main in IntelliJ IDEA
  2. In settings set Symbolic = 100%
  3. Generate tests for following code
    public int randomSum(int n) {
        List<Integer> weight = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            weight.add(new Random().nextInt(n));
        }

        return weight.size();
    }

Expected behavior
Tests are generated, similar to what is listed in 'Additional context' section.

Actual behavior
No tests are generated.

Additional context
In case loop statement changed to

for (int i = 0; i < n; i++)

then it starts working similar to what is expected:

public final class RecursionTest {
    ///region Test suites for executable org.example.Recursion.randomSum

    ///region SYMBOLIC EXECUTION: SUCCESSFUL EXECUTIONS for method randomSum(int)

    /**
     * @utbot.classUnderTest {@link Recursion}
     * @utbot.methodUnderTest {@link Recursion#randomSum(int)}
     * @utbot.returnsFrom {@code return weight.size();}
     */
    @Test
    @DisplayName("randomSum: -> return weight.size()")
    public void testRandomSum_ReturnWeightSize() {
        Recursion recursion = new Recursion();

        int actual = recursion.randomSum(0);

        assertEquals(0, actual);
    }

    /**
     * @utbot.classUnderTest {@link Recursion}
     * @utbot.methodUnderTest {@link Recursion#randomSum(int)}
     * @utbot.iterates iterate the loop {@code for(int i = 0; i < n; i++)} once
     * @utbot.returnsFrom {@code return weight.size();}
     */
    @Test
    @DisplayName("randomSum: RandomNextInt -> return weight.size()")
    public void testRandomSum_ListAdd() {
        MockedConstruction mockedConstruction = null;
        try {
            mockedConstruction = mockConstruction(Random.class, (Random randomMock, Context context) -> (when(randomMock.nextInt(anyInt()))).thenReturn(0));
            /* WARNING!!! Automatically used "Mockito static mocking" framework for mocking statics
            because execution encountered flaky methods
            To change this behaviour edit [Settings -> UtBot -> Force static mocking] */
            Recursion recursion = new Recursion();

            int actual = recursion.randomSum(1);

            assertEquals(1, actual);
        } finally {
            mockedConstruction.close();
        }
    }

Metadata

Metadata

Assignees

Labels

comp-symbolic-engineIssue is related to the symbolic execution enginectg-bugIssue is a bug

Type

No type

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions