Sprint 3 Test Plan‐Animation,item,cardupdate - UQcsse3200/2026-studio-3 GitHub Wiki

Sprint 3 Test Plan — Animation, Items and Card Upgrades

Test strategy

Sprint 3 testing combines automated unit and integration tests with live game verification. Pure logic, state transitions, boundary conditions and cross-component contracts are covered by JUnit tests. Scene2D layout, texture rendering, animation timing and input behaviour require a live LibGDX/OpenGL context, so those behaviours are verified manually in a running game.

The automated tests prioritise:

  • deterministic results through seeded random generators;
  • boundary cases such as item stacking and maximum bonus caps;
  • persistence across screen disposal and player-entity recreation;
  • integration between rewards, run state, battle effects, the shop and HUD events;
  • failure and rollback paths that must not partially mutate player state; and
  • regression coverage for component lifecycle order and null-safe popup configuration.

Offensive Attack Animations

What was tested:

Component Behaviour verified
EffectVisualStyle All fields store exactly as given; icon path can be null for a generated glow; rejects null colour, non-positive duration, non-positive scales
EffectVisualRegistry A registered style is returned unchanged on lookup; an unregistered or null type falls back to a default glow instead of null/crash; re-registering the same type replaces the earlier style; register rejects null type/style
EffectBurstComponent Damage and Sunder both resolve correctly in battle and visually match the "Card effect resolution" debug panel's resolved value
EffectProjectileComponent Pierce resolves correctly in battle and visually matches the debug panel's resolved value
BattleAnimationCoordinator Multiple resolved effects on one card (e.g. Sunder + Damage on Unseal the Breach) play staggered in sequence rather than overlapping

Test coverage: 11 dedicated unit tests across EffectVisualStyleTest.java and EffectVisualRegistryTest.java, all passing. Verified via ./gradlew core:test --tests "*EffectVisual*".

Sufficiency: Covers every boundary condition in the style/registry layer that the rest of the team's visuals depend on — null handling, fallback behaviour, and replace-on-reregister. The renderer components (EffectBurstComponent, EffectProjectileComponent) draw directly via SpriteBatch/Pixmap against a live OpenGL context, so their output can't be asserted in a headless unit test; these were verified through live builds instead, cross-checking each effect's visual against the debug panel's resolved value rather than just confirming a visual played.

Status: Merged to the team branch (commit b97073a2 / cfe3335b).

Test files:

source/core/src/test/com/csse3200/game/components/battle/EffectVisualStyleTest.java
source/core/src/test/com/csse3200/game/components/battle/EffectVisualRegistryTest.java

Item Inventory, Shop Discount & Item Library

Item names: items are shown to players under their final names. Code, enum values and test names still use the original identifiers:

Display name Code name
Shard of Fortune Lucky Coin (LUCKY_COIN)
Ember of the Divine Energy Crystal (ENERGY_CRYSTAL)
Relic of Commerce Merchant's Favor (MERCHANTS_FAVOR)
Aegis Fragment Iron Aegis (IRON_AEGIS)
Blessed Crest Warrior's Crest (WARRIORS_CREST)

Automated Test Cases

ID Component / test Why this case exists Case type Input or steps Expected result Actual result / evidence
I01 PlayerRunStateTest ownedItems is the merged implementation's durable source of truth; a separate ItemInventory class does not exist. Normal / boundary Add duplicate passive items, capture/apply to a newly created player, and read the snapshot. Order and duplicates are retained; the returned list is immutable; durable effects are rebuilt once. Pass — PR #405 unit-test checks.
I02 PlayerRunStateTest Battle consumables must have an effect before one copy is removed, and passive items must not be consumed. Normal / invalid Use Iron Aegis, Warrior's Crest, an absent item, a passive item and a player without required components. Iron Aegis grants +5 Armour; Warrior's Crest grants +1 Strength; one copy is removed only on valid use; invalid use is rejected safely. Pass — PR #405 unit-test checks.
I03 ItemEffectTest, ItemEffectApplierTest, EnergyCrystalEffectTest, MerchantsFavorEffectTest Passive effects need direct tests in addition to the PlayerRunState integration cases. Normal / boundary Apply Energy Crystal and Merchant's Favor; dispatch Energy Crystal through ItemEffectApplier; stack the passive effects. Energy Crystal raises maximum energy; Merchant's Favor contributes 10% per copy and caps at 50%; the applier dispatches the tested item correctly. Pass — PR #405 unit-test checks. Dedicated direct-dispatch tests for the two consumables remain desirable follow-up coverage.
I04 RewardGeneratorTest, RewardIntegrationTest Reward generation and claiming must use durable run state, including the current Lucky Coin multiplier. Normal / boundary Generate seeded gold and item rewards; claim a gold option with and without Lucky Coin. Gold uses round(baseReward × (1 + multiplier)); claimed gold enters PlayerRunState; an item reward adds its ItemType. Pass — PR #405 unit-test checks.
I05 ItemLibraryScreenTest The read-only Library must not open with missing item artwork or unnamed rows. Integration Load the Item Library screen's asset list. Menu/background/button assets and all five item textures are preloaded without duplicates; every item has a non-blank display name. Pass — PR #405 unit-test checks.
I06 PlayerSaveDataTest, PlayerItemEffectsSaveTest A save must preserve unconsumed items without serialising a live player entity. End-to-end / compatibility Save all item types, recreate run objects, load and restore; load a legacy save with no ownedItems; use one consumable before saving. Stable enum names round-trip; derived passive effects rebuild once; legacy data becomes an empty list; used consumables are absent and unused ones remain. Pass — PR #405 unit-test checks.
I07 Product-rule regression: Shard of Fortune (Lucky Coin) Earlier planning copy specified one consumed copy and a +20 cap based on current gold plus reward; the merged code instead stacks persistent 10% multipliers on the generated reward. The mismatch must remain visible until the team decides the intended rule. Specification discrepancy Compare the previous written rule with PlayerRunState, RewardGenerator and RewardIntegrationTest. A confirmed product rule, matching code, tests, Item Library copy and reward UI. Open — needs Team 5/7 decision and a follow-up issue or implementation change.

Manual Test Cases

ID Area Why this case exists Steps Expected result Actual result / evidence
IM01 Battle inventory popup Scene2D layout and click targets cannot be established by headless JUnit. Acquire duplicate items, open Item Inventory from a battle, then inspect names, artwork, passive-item counts and action controls. The popup aggregates items by type; passive rows show an accurate x<count> and consumable rows show USE; descriptions and artwork are readable, and the popup opens/closes without obscuring essential controls. Pending manual execution on the current main build.
IM02 Player-turn restriction The use button must not allow a battle consumable at an illegal time. Attempt to use Iron Aegis and Warrior's Crest during the player turn and outside it; use the final copy of a consumable. USE is enabled only during the player turn. A successful use visibly grants +5 Armour or +1 Strength; after the final copy, that item row disappears. Exact duplicate-count removal is covered automatically by I02. Pending manual execution on the current main build.
IM03 Battle-only scope The merged code creates InventoryPopupComponent in BattleScreen only. Documentation must not claim a Map entry point. Open the map and battle interfaces. The item popup is available in battle; the Map screen does not promise or show the shared item-popup entry. Any map entry is future work, not a completed feature. Pending manual confirmation.
IM04 Item Library Visual asset loading and navigation require a live UI check. Main Menu → Library → Item Library; inspect all five records and return. Each item shows the final player-facing name, artwork and matching effect description; Back returns safely. Pending manual execution on the current main build.
IM05 Save and relaunch The automated round trip must be corroborated through the actual UI flow. Acquire an unconsumed battle item and a passive item, save, restart, load, then enter a battle. Both owned items remain; passive effect is rebuilt; the consumable is still usable exactly once. Pending manual execution; record video or screenshots.

Run the existing automated tests from source/:

./gradlew core:test \
  --tests "*PlayerRunStateTest" \
  --tests "*ItemEffectTest" \
  --tests "*ItemEffectApplierTest" \
  --tests "*EnergyCrystalEffectTest" \
  --tests "*MerchantsFavorEffectTest" \
  --tests "*RewardGeneratorTest" \
  --tests "*RewardIntegrationTest" \
  --tests "*ItemLibraryScreenTest" \
  --tests "*PlayerSaveDataTest" \
  --tests "*PlayerItemEffectsSaveTest"

On Windows, use gradlew.bat in place of ./gradlew.

Sufficiency: The plan maps each current production component to a real test class or a manual UI case. It deliberately does not name deleted or nonexistent tests such as ItemInventoryTest, IronAegisEffectTest, WarriorsCrestEffectTest or PopupDisplayTest. Manual rows stay pending until somebody records the real result and evidence; they must not be marked passed based on unit tests alone.

Status: Inventory, Item Library, owned-item persistence and active battle-item integration are merged into main through PR #405. The Lucky Coin behaviour discrepancy in I07 remains open.

Current test files:

source/core/src/test/com/csse3200/game/maps/PlayerRunStateTest.java
source/core/src/test/com/csse3200/game/rewards/ItemEffectTest.java
source/core/src/test/com/csse3200/game/rewards/ItemEffectApplierTest.java
source/core/src/test/com/csse3200/game/rewards/EnergyCrystalEffectTest.java
source/core/src/test/com/csse3200/game/rewards/MerchantsFavorEffectTest.java
source/core/src/test/com/csse3200/game/rewards/RewardGeneratorTest.java
source/core/src/test/com/csse3200/game/rewards/RewardIntegrationTest.java
source/core/src/test/com/csse3200/game/screens/ItemLibraryScreenTest.java
source/core/src/test/com/csse3200/game/save/PlayerSaveDataTest.java
source/core/src/test/com/csse3200/game/save/PlayerItemEffectsSaveTest.java

Enemy Status Effects & Enemy Attack Animations

What was tested:

Component Behaviour covered
EnemyStatusEffectVisuals Poison, Vulnerable and Feeble use distinct four-frame textures; registration preserves other effects' styles
EnemyStatusEffectVisualComponent Application playback and fade; persistent animation loops; centred single effects and elliptical two-/three-status orbits; positioning on tall and short enemies at different scales
BattleAnimationCoordinator Correct targets and effect ordering for Poison Dagger, Expose and Sentinel's Rebuke; repeated applications do not duplicate persistent visuals; removal, cleanse, death and screen disposal clean up effects
EnemyAnimationController Attack frames and fallback lunge; return to the original position without drift; interruption and listener cleanup; completion callback runs once after attack frames and movement finish
Battle-loop integration Enemies attack sequentially without repeated damage; longer animations delay the next enemy; lethal attacks finish before defeat and prevent further enemy attacks

Live verification checks:

Area Expected result
Card targeting Status cards can be dragged onto eligible enemies and display effects on the correct targets
Status presentation Each effect remains recognisable alone and in combinations; animations follow enemies during movement and scaling
Status cleanup Persistent visuals disappear when the corresponding status expires, is removed, or the enemy dies
Enemy attacks Each enemy moves forward and returns before the next attack; repeated turns cause no position drift

Test coverage: 49 automated test methods across three files: 14 visual-component tests, 8 status-integration tests and 27 enemy-animation-controller tests.

Run from source:

./gradlew core:test \
  --tests "*EnemyStatusEffectVisualComponentTest" \
  --tests "*EnemyStatusVisualIntegrationTest" \
  --tests "*EnemyAnimationControllerTest"

Sufficiency: Automated tests cover frame selection, positioning, target routing, cleanup and attack-completion callbacks. Live checks cover readability, drag targeting and animation timing. Gameplay damage and duration rules remain owned by their respective systems. Status: Implementation and tests are present on Animation&item&cardupgrade at 1e228b21. Test execution and live-check results require confirmation for the final merged version.

Test files:

source/core/src/test/com/csse3200/game/components/battle/EnemyStatusEffectVisualComponentTest.java
source/core/src/test/com/csse3200/game/components/battle/EnemyStatusVisualIntegrationTest.java
source/core/src/test/com/csse3200/game/components/enemy/EnemyAnimationControllerTest.java
⚠️ **GitHub.com Fallback** ⚠️