Integration Team Sprint 4 Test Plan - UQcsse3200/2023-studio-2 GitHub Wiki

General Testing

For general testing we played through the game countless times and took notes if we faced any issues throughout each playthrough. This testing allows us to create a plan of action for the sprint to prioritise which bugs and improvements we made throughout the sprint.

Quality Control

To ensure the code quality was maintained, SonarCloud was checked throughout the sprint and any recommendations were implemented for the classes we were maintaining.

Unit Testing

Since there weren't any new features implemented this sprint, the number of tests required was less than previous sprints. Most of the tests written were simply improvements to existing test classes or additions to test additional functionality implemented. We used a mixture of mock based testing and assertion testing to ensure the classes interacted with other classes as expected and maintained the correct state.

HealTool

The HealTool tests were completely rewritten to match the new functionality implemented throughout the sprint. To test the HealTool we used mocking to test its' interactions with other classes. Due to the fact that we used mocking, we utilised the white box testing methodology since we needed to know how the HealTool interacted with the CombatStatsComponent amongst many other classes. The test cases created were as follows.

  • testCanInteractWithEnoughResources which ensures that the heal tool is able to heal the clicked structure if there are enough resources. This test was run with a multitude of different values, including edge case values, to ensure it worked as intended.
  • testCanInteractWithInsufficientResources which ensures that the heal tool is unable to the clicked structure if there aren't enough resources. This test was run with a multitude of different values, including edge case values, to ensure it worked as intended.
  • testCanInteractWithInsufficientResources which ensures that the heal tool gracefully handles a situation where there is no structure to heal. This test was run with a multitude of different values, including edge case values, to ensure it worked as intended.
  • testCanInteractWithNoCost which ensures that the heal tool is able to work if the cost is empty.
  • testCanInteractWithFullHealth which ensures that the tool cannot be used if the clicked structure is already at full health. This test is run 3 different values to test different edge cases.
  • testPerformInteraction which tests that the performInteraction method successfully heals the clicked structure.

StructureToolPicker

The following test was added to the test suite for the StructureToolPicker class to test the new selectIndex functionality.

    @Test
    void testSelectedIndex() {
        when(resourceService.getAsset(any(), eq(Texture.class))).thenReturn(mock(Texture.class));
        when(renderService.getStage()).thenReturn(mock(Stage.class));

        var structurePicker = new StructureToolPicker();

        structurePicker.create();

        structurePicker.selectIndex(0);

        // ensure the first tool in the list is selected
        assertEquals(structurePicker.getSelectableTools().get(0), structurePicker.getSelectedTool());

        var outOfRange = structurePicker.getSelectableTools().size();

        // test if out of range is handled correctly.
        structurePicker.selectIndex(-1);
        structurePicker.selectIndex(outOfRange);
        assertEquals(structurePicker.getSelectableTools().get(0), structurePicker.getSelectedTool());
    }

This test ensures that the correct tool is selected based on its index in the list. It also tests that negative numbers and out of range indexes are handled gracefully using assertion testing and mocking.

ToolTest

The following test was added to the test suite for the Tool class to test the new sorting functionality.

    @Test
    void testOrdering() {
        ObjectMap<String, Integer> cost = new ObjectMap<>();
        List<Tool> tools = new ArrayList<>();
        tools.add(new MockTool(cost, 0, "image.png"));
        tools.add(new MockTool(cost, 5, "image.png"));
        tools.add(new MockTool(cost, 2, "image.png"));
        tools.add(new MockTool(cost, 12, "image.png"));
        tools.add(new MockTool(cost, 3, "image.png"));

        Collections.sort(tools);

        var prevOrder = 0;
        for (var tool : tools) {
            if (tool.getOrdering() < prevOrder) {
                fail();
           }

            prevOrder = tool.getOrdering();
        }
    }

This test ensures that the tools are correctly ordered in ascending order using assertion testing.

The following tests were also added to the Tool class testing suite when the new tool range functionality was implemented.

    @Test
    void TestCanPlaceOutOfRange() {
        ObjectMap<String, Integer> cost = new ObjectMap<>();
        var tool = new MockTool(cost, 5f, "image.png", 0);

        var player = mock(Entity.class);
        when(player.getCenterPosition()).thenReturn(new Vector2(0,0));

        // out of range by one tile
        Assertions.assertFalse(tool.canInteract(player, new GridPoint2(6, 0)).isValid());
        // out of range on the diagonal
        Assertions.assertFalse(tool.canInteract(player, new GridPoint2(4, 4)).isValid());

        var player2 = mock(Entity.class);
        when(player2.getCenterPosition()).thenReturn(new Vector2(10,10));

        // test being converted to world tile position before distance is calculated.
        Assertions.assertFalse(tool.canInteract(player, new GridPoint2(10, 10)).isValid());
    }

    @Test
    void TestCanPlaceInRange() {
        ObjectMap<String, Integer> cost = new ObjectMap<>();
        var tool = new MockTool(cost, 5f, "image.png", 0);

        var player = mock(Entity.class);
        when(player.getCenterPosition()).thenReturn(new Vector2(0,0));

        // test right in the middle
        Assertions.assertTrue(tool.canInteract(player, new GridPoint2(0, 0)).isValid());
        // test right on the edge
        Assertions.assertTrue(tool.canInteract(player, new GridPoint2(0, 5)).isValid());
        // test right on the edge diagonally
        Assertions.assertTrue(tool.canInteract(player, new GridPoint2(3, 4)).isValid());

        var player2 = mock(Entity.class);
        when(player2.getCenterPosition()).thenReturn(new Vector2(10,10));

        // test being converted to world tile position before distance is calculated.
        Assertions.assertTrue(tool.canInteract(player2, new GridPoint2(20, 20)).isValid());
    }

The TestCanPlaceOutOfRange test ensures that interacting with grid positions which are outside the tools range are invalid. It tests a multitude of cases for this including the edge case where it is out of range by only one tile.

The TestCanPlaceInRange test ensures that interacting with grid positions which are outside the tools range are deemed valid. It tests a multitude of cases for this including the edge case where it exactly in range using the Pythagorean theorem of 3 grids away on the horizontal and 4 grids away on the vertical.

⚠️ **GitHub.com Fallback** ⚠️