Audio Manager Testing - UQcsse3200/2024-studio-2 GitHub Wiki

Overview

The AudioManager is responsible for controlling all audio-related functionalities in the game. This includes playing, stopping, and managing sound and music assets, as well as controlling their volume and muting/unmuting them. The AudioManager interacts with the ResourceService to retrieve the necessary audio assets and handle them according to user preferences (e.g., volume adjustments, muting).

Testing (jUnit) for AudioManager

Purpose of Tests

The tests aim to ensure that the core functionalities of the AudioManager work as expected, including playing/stopping music and sounds, adjusting volumes (with quadratic scaling), and handling mute/unmute operations. The tests use Mockito to mock Sound and Music objects and their interactions with the ResourceService.

Test Descriptions

shouldPlaySound

  • Purpose: This test verifies that a sound is correctly played when requested by AudioManager.

  • What it does: Mocks the Sound object retrieved from ResourceService, and calls the playSound method with a sample sound path. Verifies that the sound is played with the correct volume.

  • Why This Test: Ensures that sounds are played correctly using the AudioManager and that the system interacts properly with the ResourceService and the sound asset.

shouldStopSound

  • Purpose: This test checks whether a sound can be stopped after being played.

  • What it does: Mocks the Sound object, simulates playing a sound, then calls AudioManager.stopSound() with a sound path. It verifies that the correct sound instance is stopped using its sound ID.

  • Why This Test: Ensures that sound effects can be halted mid-play, which is important for dynamic game behavior. For instance, sound effects may need to stop when switching scenes or triggering certain in-game events.

shouldPlayMusic

  • Purpose: Verifies that a music track is played with the correct settings, including volume and looping, when requested by AudioManager.

  • What it does: Mocks the Music object retrieved from ResourceService, then calls the playMusic method with a specified path and looping option. It verifies that the music is set to the correct volume, set to loop if necessary, and then played.

  • Why This Test: Ensures that background music or any continuous music track starts correctly with the desired volume and looping settings. This is vital for creating a smooth auditory environment in the game.

shouldStopMusic

  • Purpose: This test checks that a playing music track can be stopped by the AudioManager.

  • What it does: Mocks the Music object, simulates playing a track, and calls AudioManager.stopMusic(). It verifies that the music stops correctly.

  • Why This Test: Ensures that music tracks can be stopped, which is essential for handling transitions between game scenes or when stopping audio altogether (e.g., during a pause or game over).

shouldSetMusicVolume

  • Purpose: Ensures that the volume of the currently playing music can be adjusted by the AudioManager using quadratic scaling.

  • What it does: Mocks the Music object, simulates playing a music track, then calls AudioManager.setMusicVolume() with a specific volume level. It verifies that the volume is scaled quadratically and applied to the music.

  • Why This Test: Ensures that players can control the volume of background music, and verifies that the quadratic scaling (which smooths the volume progression) is working correctly. This improves user experience with more intuitive volume control.

shouldSetSoundVolume

  • Purpose: Verifies that the volume of playing sounds can be adjusted dynamically by the AudioManager using quadratic scaling.

  • What it does: Mocks the Sound object, simulates playing a sound, and then calls AudioManager.setSoundVolume() with a specific volume level. It checks that the quadratic scaling is correctly applied to the sound's volume.

  • Why This Test: Ensures that sound effects are affected by volume adjustments during gameplay, and verifies that the quadratic scaling is applied, making the volume change smoother for a more natural listening experience.

shouldMuteAndUnmuteAudio

  • Purpose: Tests that the AudioManager can mute and unmute both music and sounds, ensuring that the volume behaves as expected when toggled.

  • What it does: Mocks both Music and Sound objects, simulates playing both, then calls AudioManager.muteAudio() to mute and AudioManager.unmuteAudio() to unmute. Verifies that the volumes are set to zero when muted and revert to their previous levels when unmuted.

  • Why This Test: Ensures that the mute functionality works correctly for both music and sound effects. This is important for players who need to quickly mute/unmute the game audio.

shouldScaleVolume

  • Purpose: Verifies that the AudioManager applies quadratic scaling when setting music and sound volumes.

  • What it does: Sets music and sound volumes using AudioManager.setMusicVolume() and AudioManager.setSoundVolume(). It then verifies that the volumes are correctly scaled quadratically (i.e., volume^2).

  • Why This Test: Ensures that the quadratic scaling for volume adjustments works correctly, providing a more natural change in perceived loudness as players adjust volume settings.

shouldReturnCorrectVolumeWhenMuted

  • Purpose: Verifies that after muting and unmuting, the music and sound volumes are restored to their previous levels.

  • What it does: Sets the music and sound volumes, mutes the audio using AudioManager.muteAudio(), and checks that the volume is set to 0 while muted. After unmuting with AudioManager.unmuteAudio(), it verifies that the volume returns to the pre-mute levels.

  • Why This Test: Ensures that the system remembers the previous volume levels when audio is muted and correctly restores them when unmuted, which is important for a smooth audio control experience.

shouldHandleMissingSoundAsset

  • Purpose: Tests that missing or null sound assets are gracefully handled without crashing the system.

  • What it does: Simulates the ResourceService returning a null sound asset, then calls AudioManager.playSound() and verifies that no crashes occur and no further interactions are made with the null asset.

  • Why This Test: Ensures that missing sound assets do not cause errors or crashes in the game, providing a robust audio management system.

shouldHandleMissingMusicAsset

  • Purpose: Tests that missing or null music assets are gracefully handled without crashing the system.

  • What it does: Simulates the ResourceService returning a null music asset, then calls AudioManager.playMusic() and verifies that no crashes occur and no further interactions are made with the null asset.

  • Why This Test: Ensures that missing music assets do not cause errors or crashes in the game, providing a robust audio management system.

shouldScaleMusicVolumeCorrectlyAtLowVolume

  • Purpose: Verifies that low music volumes are correctly scaled using the quadratic scaling system.

  • What it does: Simulates playing music, then calls AudioManager.setMusicVolume() with a low value (e.g., 0.1). Uses ArgumentCaptor to verify that the scaled volume is correctly applied (e.g., 0.1^2 = 0.01).

  • Why This Test: Ensures that even at low volume levels, the quadratic scaling system applies the correct volume, providing accurate audio control for players.

shouldScaleSoundVolumeCorrectlyAtHighVolume

  • Purpose: Verifies that high sound volumes are correctly scaled using the quadratic scaling system.

  • What it does: Simulates playing a sound, then calls AudioManager.setSoundVolume() with a high value (e.g., 0.9). Uses ArgumentCaptor to verify that the scaled volume is correctly applied (e.g., 0.9^2 = 0.81).

  • Why This Test: Ensures that at higher volume levels, the quadratic scaling system applies the correct volume, preventing abrupt jumps in loudness for players.

shouldNotSetVolumeWhenMuted

  • Purpose: Verifies that volume changes do not occur when audio is muted.

  • What it does: Mutes the audio, then attempts to change the volume using AudioManager.setMusicVolume() and AudioManager.setSoundVolume(). Verifies that the volume changes are ignored while muted.

  • Why This Test: Ensures that muting the audio prevents any further volume changes until the audio is unmuted, providing consistency in the mute functionality.

shouldReturnDesiredVolumeWhenMuted

  • Purpose: Verifies that the desired volume remains unchanged even when the audio is muted.

  • What it does: Sets the desired volumes for music and sound, then mutes the audio. It checks that the internal desired volume remains the same while the actual volume is set to 0.

  • Why This Test: Ensures that the AudioManager maintains the correct desired volume levels while the audio is muted, so they can be restored correctly when unmuted.

shouldHandleMaxVolumeScaling

  • Purpose: Verifies that the AudioManager correctly handles maximum volume (1.0) when setting both music and sound volumes.

  • What it does: Simulates playing both music and sound, then sets the volume to the maximum (1.0). Verifies that the scaled volume remains 1.0 after applying the quadratic scaling.

  • Why This Test: Ensures that the audio system can handle maximum volume values correctly, preventing distortion or clipping in the audio output.

shouldReturnCorrectDesiredVolumesWhenMuted

  • Purpose: Verifies that the desired music and sound volumes are correctly remembered when audio is muted and restored after unmuting.

  • What it does: Sets music and sound volumes, mutes the audio, and verifies that the actual playing volume becomes 0, but the desired volumes remain unchanged. After unmuting, it checks that the volumes return to their original levels.

  • Why This Test: Ensures that muting and unmuting functions do not affect the internal desired volume settings, allowing players to restore their previous volume levels accurately after muting.

shouldCorrectlyPlayLoopingMusic

  • Purpose: Verifies that the AudioManager can correctly set a music track to loop.

  • What it does: Simulates playing a music track with looping enabled, and verifies that the music is set to loop and then played.

  • Why This Test: Ensures that looping background music or ambient tracks can be correctly played without interruption, creating a seamless audio experience.

shouldNotCrashOnStopMissingSound

  • Purpose: Ensures that attempting to stop a sound that doesn't exist (or was not loaded) doesn't crash the system.

  • What it does: Simulates trying to stop a sound for which no asset exists and verifies that the system does not crash or throw errors.

  • Why This Test: Ensures robustness of the audio system when handling missing sound assets, preventing crashes or unexpected behavior.

shouldNotCrashOnStopMissingMusic

  • Purpose: Ensures that attempting to stop music that doesn't exist (or was not loaded) doesn't crash the system.

  • What it does: Simulates trying to stop music for which no asset exists and verifies that the system does not crash or throw errors.

  • Why This Test: Ensures robustness of the audio system when handling missing music assets, preventing crashes or unexpected behavior.

shouldReturnMutedState

  • Purpose: Verifies that the system correctly returns whether the audio is muted.

  • What it does: Initially checks that the audio is not muted, mutes the audio using AudioManager.muteAudio(), and verifies that the muted state is correctly reported. After unmuting, it checks that the muted state is reset.

  • Why This Test: Ensures that the system correctly tracks the muted state of the audio and can return this state when queried.

shouldReturnDesiredMusicVolume

  • Purpose: Verifies that the correct desired music volume is returned by the AudioManager.

  • What it does: Sets the music volume to a specific value using AudioManager.setMusicVolume(), then retrieves the desired volume and verifies that it matches the set value.

  • Why This Test: Ensures that the AudioManager properly tracks the desired music volume, which is important for accurately restoring volume after muting or changing volume levels.

shouldReturnDesiredSoundVolume

  • Purpose: Verifies that the correct desired sound volume is returned by the AudioManager.

  • What it does: Sets the sound volume to a specific value using AudioManager.setSoundVolume(), then retrieves the desired volume and verifies that it matches the set value.

  • Why This Test: Ensures that the AudioManager properly tracks the desired sound volume, which is important for accurately restoring volume after muting or changing volume levels.

shouldHandleNullSoundAsset

  • Purpose: Verifies that the system can gracefully handle a null sound asset without crashing.

  • What it does: Simulates the ResourceService returning null for a sound asset, then attempts to play the sound and verifies that the system handles it gracefully without attempting further interactions.

  • Why This Test: Ensures that missing or invalid sound assets are handled gracefully, preventing crashes or errors when assets are missing or unloaded.

shouldHandleNullMusicAsset

  • Purpose: Verifies that the system can gracefully handle a null music asset without crashing.

  • What it does: Simulates the ResourceService returning null for a music asset, then attempts to play the music and verifies that the system handles it gracefully without attempting further interactions.

  • Why This Test: Ensures that missing or invalid music assets are handled gracefully, preventing crashes or errors when assets are missing or unloaded.

shouldNotCrashOnStopNullSound

  • Purpose: Verifies that attempting to stop a null sound asset doesn't crash the system.

  • What it does: Simulates trying to stop a sound where the asset is null and verifies that the system does not crash or throw exceptions.

  • Why This Test: Ensures the robustness of the audio system when handling invalid or unloaded sound assets.

shouldNotCrashOnStopNullMusic

  • Purpose: Verifies that attempting to stop a null music asset doesn't crash the system.

  • What it does: Simulates trying to stop music where the asset is null and verifies that the system does not crash or throw exceptions.

  • Why This Test: Ensures the robustness of the audio system when handling invalid or unloaded music assets.