Minigame Leaderboard Testing - UQcsse3200/2024-studio-2 GitHub Wiki
1. Overview
The PlayFab class handles user registration, login, and leaderboard management via PlayFab's client API. It allows for initializing the PlayFab client with a Title ID, and provides methods for user registration, login, updating leaderboards, andsubmitting scores.
2. Test Cases
2.1 Initial Set Up
As almost the functions in PlayFab are using APIs, it could cause throttling when users call these functions multiple times within a short period. Therefore, the leaderboard tests will mainly use mockito to test.
Firstly, we need to initialize 3 different leadboards and assign some values to them. Then we need to mock that when the PlayFabClientAPI.GetLeaderboard()
is called, it will return one of the leaderboards that we defined before based on the given leaderboardName.
mockedAPI = mockStatic(PlayFabClientAPI.class);
mockedAPI.when(() -> PlayFabClientAPI.GetLeaderboard(any(GetLeaderboardRequest.class)))
.thenAnswer(invocation -> {
String leaderboardName = ((GetLeaderboardRequest) invocation.getArgument(0)).StatisticName;
switch (leaderboardName) {
case "Snake":
return mockSnakeLeaderboardResult;
case "Bird":
return mockBirdLeaderboardResult;
case "Fish":
return mockFishLeaderboardResult;
default:
throw new IllegalArgumentException("Unknown leaderboard: " + leaderboardName);
}
});
Besides, we also need to mock the PlayFabClientAPI.UpdatePlayerStatistics, which used for submitting player' scores to ensure that the score is added to the leaderboard.
mockedAPI.when(() -> PlayFabClientAPI.UpdatePlayerStatistics(any(UpdatePlayerStatisticsRequest.class)))
.thenAnswer(invocation -> {
UpdatePlayerStatisticsRequest request = invocation.getArgument(0);
int score = request.Statistics.get(0).Value;
String leaderboardName = request.Statistics.get(0).StatisticName; // Get the leaderboard type from the request
GetLeaderboardResult result;
switch (leaderboardName) {
case "Snake":
result = mockSnakeLeaderboardResult.Result;
break;
case "Bird":
result = mockBirdLeaderboardResult.Result;
break;
case "Fish":
result = mockFishLeaderboardResult.Result;
break;
default:
throw new IllegalArgumentException("Unknown leaderboard: " + leaderboardName);
}
// Check if the new user already exists in the leaderboard
PlayerLeaderboardEntry existingEntry = null;
for (PlayerLeaderboardEntry entry : result.Leaderboard) {
if (newUser.equals(entry.DisplayName)) {
existingEntry = entry;
break;
}
}
// If the user does not exist, then add them to the leaderboard
if (existingEntry == null) {
PlayerLeaderboardEntry newEntry = new PlayerLeaderboardEntry();
newEntry.DisplayName = newUser;
newEntry.StatValue = score;
result.Leaderboard.add(newEntry);
}
return mockSuccessResult;
});
Finally, we need to close the mockAPI after running each test. Thus, we need to use @AfterEach
method.
@AfterEach
public void closeMockedAPI() {
if (mockedAPI != null) {
mockedAPI.close();
}
}
2.2 Update Snake Leaderboard
-
Purpose: This test verifies that the snake leaderboard is updated when the user give a "Snake" String into the update function.
-
What it does: Mocks the
PlayFabClientAPI.GetLeaderboard()
and returns the leaderboard based on the given string. -
Why This Test: Ensures that the correct leaderboard is returned.
-
Code:
@Test
public void testUpdateSnakeLeaderboard() {
// Act
PlayFab.updateLeaderboard("Snake");
// Assert
assertEquals(3, playFab.getUsernames().size());
assertEquals(3, playFab.getHighscores().size());
assertEquals("User0", playFab.getUsernames().get(0));
assertEquals("10", playFab.getHighscores().get(0));
assertEquals("User1", playFab.getUsernames().get(1));
assertEquals("9", playFab.getHighscores().get(1));
assertEquals("User2", playFab.getUsernames().get(2));
assertEquals("8", playFab.getHighscores().get(2));
}
2.3 Update Bird Leaderboard
-
Purpose: This test verifies that the bird leaderboard is updated when the user give a "Bird" String into the update function.
-
What it does: Mocks the
PlayFabClientAPI.GetLeaderboard()
and returns the leaderboard based on the given string. -
Why This Test: Ensures that the correct leaderboard is returned.
-
Code:
@Test
public void testUpdateBirdLeaderboard() {
// Act
PlayFab.updateLeaderboard("Bird");
// Assert
assertEquals(3, playFab.getUsernames().size());
assertEquals(3, playFab.getHighscores().size());
assertEquals("User3", playFab.getUsernames().get(0));
assertEquals("7", playFab.getHighscores().get(0));
assertEquals("User4", playFab.getUsernames().get(1));
assertEquals("6", playFab.getHighscores().get(1));
assertEquals("User5", playFab.getUsernames().get(2));
assertEquals("5", playFab.getHighscores().get(2));
}
2.4 Update Fish Leaderboard
-
Purpose: This test verifies that the fish leaderboard is updated when the user give a "Fish" String into the update function.
-
What it does: Mocks the
PlayFabClientAPI.GetLeaderboard()
and returns the leaderboard based on the given string. -
Why This Test: Ensures that the correct leaderboard is returned.
-
Code:
@Test
public void testUpdateFishLeaderboard() {
// Act
PlayFab.updateLeaderboard("Fish");
// Assert
assertEquals(2, playFab.getUsernames().size());
assertEquals(2, playFab.getHighscores().size());
assertEquals("User6", playFab.getUsernames().get(0));
assertEquals("4", playFab.getHighscores().get(0));
assertEquals("User7", playFab.getUsernames().get(1));
assertEquals("3", playFab.getHighscores().get(1));
}
2.5 New User Submit Score To Snake Leaderboard
-
Purpose: This test verifies that the snake leaderboard is added one more entry when logged user submits new score
-
What it does: Mocks the
PlayFabClientAPI.UpdatePlayerStatistics()
to send the request to PlayFab, which submits score for the logged user. -
Why This Test: Ensures that a new value is added to the right leaderboard.
-
Code:
@Test
public void testSubmitSnakeScoreNewUser() {
PlayFab.isLogin = true;
// Act
PlayFab.submitScore("Snake", 20);
PlayFab.updateLeaderboard("Snake");
// Assert
assertEquals(4, mockSnakeLeaderboardResult.Result.Leaderboard.size()); // New user added
assertEquals(newUser, playFab.getUsernames().get(3));
assertEquals("20", playFab.getHighscores().get(3));
}
2.6 New User Submit Score To Bird Leaderboard
-
Purpose: This test verifies that the bird leaderboard is added one more entry when logged user submits new score
-
What it does: Mocks the
PlayFabClientAPI.UpdatePlayerStatistics()
to send the request to PlayFab, which submits score for the logged user. -
Why This Test: Ensures that a new value is added to the right leaderboard.
-
Code:
@Test
public void testSubmitBirdScoreNewUser() {
PlayFab.isLogin = true;
// Act
PlayFab.submitScore("Bird", 20);
PlayFab.updateLeaderboard("Bird");
// Assert
assertEquals(4, mockBirdLeaderboardResult.Result.Leaderboard.size()); // New user added
assertEquals(newUser, playFab.getUsernames().get(3));
assertEquals("20", playFab.getHighscores().get(3));
}
2.7 New User Submit Score To Fish Leaderboard
-
Purpose: This test verifies that the fish leaderboard is added one more entry when logged user submits new score
-
What it does: Mocks the
PlayFabClientAPI.UpdatePlayerStatistics()
to send the request to PlayFab, which submits score for the logged user. -
Why This Test: Ensures that a new value is added to the right leaderboard.
-
Code:
@Test
public void testSubmitFishScoreNewUser() {
PlayFab.isLogin = true;
// Act
PlayFab.submitScore("Fish", 20);
PlayFab.updateLeaderboard("Fish");
// Assert
assertEquals(3, mockFishLeaderboardResult.Result.Leaderboard.size()); // New user added
assertEquals(newUser, playFab.getUsernames().get(2));
assertEquals("20", playFab.getHighscores().get(2));
}