Sprint 3 Test Plan‐Animation,item,cardupdate - UQcsse3200/2026-studio-3 GitHub Wiki
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.
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 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) |
| 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. |
| 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
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