Lighting Engine Test Plan - UQcsse3200/2026-studio-2 GitHub Wiki
Overview
This document outlines the comprehensive test strategy for the lighting system implementation, covering unit tests, integration tests, and performance tests.
Test Scope
In Scope
LightingEngineinitialization and renderingLightingServiceregistration and retrievalPointLightComponentlifecycle and updatesLightFactoryentity creationLightingDefaultsconstant values- Integration with
ServiceLocator - Integration with game screens
- Arrow projectile lighting
- User settings brightness control
Out of Scope
- Box2DLights library internals
- libGDX rendering pipeline
- Physics engine behavior
Unit Tests
LightingEngine Tests
Test 1: Initialization
Test Name: testLightingEngineInitialization
- Objective: Verify that
LightingEngineproperly initializes with camera and world - Setup:
- Mock
CameraComponentwith valid projection matrix - Mock
Worldobject
- Mock
- Steps:
- Create
LightingEngine(camera, world) - Verify
RayHandleris created - Verify ambient light is set from
UserSettings - Verify blur is enabled with correct blur count
- Create
- Expected Result: Engine initializes without exceptions, all components configured
Test 2: Ambient Light Setter
Test Name: testSetAmbientLight
- Objective: Verify ambient light level can be changed
- Setup: Create initialized
LightingEngine - Steps:
- Call
setAmbientLight(0.5f) - Verify internal state updated
- Call
setAmbientLight(1.0f) - Verify state updated again
- Call
- Expected Result: Ambient light values are correctly set
Test 3: Render Method
Test Name: testRenderMethod
- Objective: Verify render method executes without exceptions
- Setup:
- Create initialized
LightingEngine - Mock projection matrix from camera
- Create initialized
- Steps:
- Call
render() - Verify no exceptions thrown
- Verify
RayHandler.setCombinedMatrix()called - Verify
RayHandler.updateAndRender()called
- Call
- Expected Result: Render completes successfully
Test 4: Dispose
Test Name: testLightingEngineDispose
- Objective: Verify proper cleanup on disposal
- Setup: Create initialized
LightingEngine - Steps:
- Call
dispose() - Verify
RayHandler.dispose()called - Attempt to render after disposal
- Call
- Expected Result: Resources released, no memory leaks
LightingService Tests
Test 5: Service Initialization with Engine
Test Name: testServiceInitializationWithEngine
- Objective: Verify
LightingServicecan be initialized with existing engine - Setup: Create mock
LightingEngine - Steps:
- Create
LightingService(lightingEngine) - Call
getEngine() - Verify returned engine matches input
- Create
- Expected Result: Service correctly stores and returns engine reference
Test 6: Service Initialization with Camera and World
Test Name: testServiceInitializationWithCameraAndWorld
- Objective: Verify
LightingServicecan create engine from camera and world - Setup:
- Mock
CameraComponent - Mock
World
- Mock
- Steps:
- Create
LightingService(camera, world) - Call
getEngine() - Verify engine is not null
- Verify engine is initialized
- Create
- Expected Result: Engine created and properly initialized
PointLightComponent Tests
Test 7: Component Initialization
Test Name: testPointLightComponentInitialization
- Objective: Verify component initializes with correct parameters
- Setup:
- Mock
RayHandler - Create test color and parameters
- Mock
- Steps:
- Create
PointLightComponent(rayHandler, 128, Color.YELLOW, 4f) - Verify parameters stored correctly
- Verify component not yet created (no light object)
- Create
- Expected Result: Component stores all parameters, ready for entity attachment
Test 8: Component Create Method
Test Name: testPointLightComponentCreate
- Objective: Verify light object is created when component attaches to entity
- Setup:
- Create component with mock
RayHandler - Mock entity with position
- Create component with mock
- Steps:
- Create test entity with position (5, 5)
- Call
component.create()with entity - Verify
PointLightobject created - Verify light position set to entity position
- Verify light properties configured (softness, xray, contact filter)
- Expected Result: Light object created and properly configured
Test 9: Component Update Positioning
Test Name: testPointLightComponentUpdatePositioning
- Objective: Verify light moves with entity
- Setup:
- Create component with entity
- Call
create() - Mock
TimeSourcewith delta time
- Steps:
- Set entity position to (5, 5)
- Call
update() - Verify light position at (5, 5)
- Set entity position to (10, 10)
- Call
update() - Verify light position at (10, 10)
- Expected Result: Light always synchronized with entity center
Test 10: Component Active/Inactive Toggle
Test Name: testPointLightComponentActiveToggle
- Objective: Verify light can be toggled active/inactive
- Setup:
- Create component and attach to entity
- Call
create()
- Steps:
- Call
setActive(false) - Call
update() - Verify light is inactive
- Call
setActive(true) - Call
update() - Verify light is active
- Call
- Expected Result: Active state correctly toggled
Test 11: Component Color Modification
Test Name: testPointLightComponentSetColor
- Objective: Verify color can be changed
- Setup:
- Create component with initial yellow color
- Steps:
- Call
setColor(Color.RED) - Verify internal color updated
- Verify light color updated
- Call
setColor(Color.BLUE) - Verify both updated
- Call
- Expected Result: Color changes applied to internal state and light
Test 12: Component Distance Modification
Test Name: testPointLightComponentSetDistance
- Objective: Verify distance can be changed
- Setup:
- Create component with distance 4f
- Steps:
- Call
setDistance(8f) - Verify distance stored
- Call
getDistance() - Verify returns 8f
- Call
- Expected Result: Distance correctly updated and retrievable
Test 13: Component Softness
Test Name: testPointLightComponentSetSoftness
- Objective: Verify softness can be configured
- Setup:
- Create component and attach to entity
- Call
create()
- Steps:
- Call
setSoftnessLength(2f) - Verify light softness updated
- Call
setSoftnessLength(0.5f) - Verify updated again
- Call
- Expected Result: Softness correctly applied to light
Test 14: Component Disposal
Test Name: testPointLightComponentDispose
- Objective: Verify proper cleanup on disposal
- Setup:
- Create component with light
- Steps:
- Call
dispose() - Verify light removed from
RayHandler - Verify internal reference set to null
- Call
dispose()again - Verify no exception thrown
- Call
- Expected Result: Light properly removed, safe to dispose multiple times
Test 15: Component Method Chaining
Test Name: testPointLightComponentMethodChaining
- Objective: Verify builder pattern works correctly
- Setup:
- Create component
- Steps:
- Call
setColor(Color.RED).setDistance(6f).setSoftnessLength(1.5f) - Verify all changes applied
- Verify returns
thisfrom setColor, setDistance, setSoftnessLength
- Call
- Expected Result: Method chaining works, all values correctly set
LightFactory Tests
Test 16: Create Point Light
Test Name: testLightFactoryCreatePointLight
- Objective: Verify factory creates point light with defaults
- Setup:
- Register
LightingServicewith mockLightingEngine - Register in
ServiceLocator
- Register
- Steps:
- Call
LightFactory.createPointLight() - Verify entity returned is not null
- Verify entity has
PointLightComponent - Verify component uses
LightingDefaultsvalues
- Call
- Expected Result: Factory creates properly configured light entity
Test 17: Factory Exception on Missing Service
Test Name: testLightFactoryExceptionOnMissingService
- Objective: Verify factory throws exception if service not registered
- Setup:
- Clear
ServiceLocator
- Clear
- Steps:
- Call
LightFactory.createPointLight() - Expect
IllegalStateException
- Call
- Expected Result: Exception thrown with clear error message
Test 18: Factory Exception on Missing Engine
Test Name: testLightFactoryExceptionOnMissingEngine
- Objective: Verify factory throws exception if engine null
- Setup:
- Register
LightingServicethat returns null engine
- Register
- Steps:
- Call
LightFactory.createPointLight() - Expect
IllegalStateException
- Call
- Expected Result: Exception thrown with clear error message
Test 19: Factory Non-Instantiable
Test Name: testLightFactoryNonInstantiable
- Objective: Verify factory cannot be instantiated
- Setup: None
- Steps:
- Try to instantiate
LightFactory()via reflection - Expect exception
- Try to instantiate
- Expected Result: Constructor throws
IllegalStateException
LightingDefaults Tests
Test 20: Constant Values
Test Name: testLightingDefaultsConstants
- Objective: Verify all constants have expected values
- Setup: None
- Steps:
- Verify
AMBIENT_LIGHT == 0.9f - Verify
BLUR_NUM == 3 - Verify
RAYS == 128 - Verify
DIST == 4f - Verify
NORMAL_COLORis valid
- Verify
- Expected Result: All constants match specifications
Test 21: Color Validity
Test Name: testLightingDefaultsColorValidity
- Objective: Verify default color is valid
- Setup: None
- Steps:
- Get
NORMAL_COLOR - Verify R, G, B in range [0, 1]
- Verify alpha in range [0, 1]
- Get
- Expected Result: Color values valid
Integration Tests
ServiceLocator Integration Tests
Test 22: Service Registration and Retrieval
Test Name: testServiceLocatorRegistration
- Objective: Verify service registers and retrieves correctly
- Setup:
- Create mock
LightingService
- Create mock
- Steps:
- Call
ServiceLocator.registerLightingService(service) - Call
ServiceLocator.getLightingService() - Verify returned service matches registered
- Call
- Expected Result: Service correctly stored and retrieved
Test 23: Service Locator Clear
Test Name: testServiceLocatorClear
- Objective: Verify service cleared when
ServiceLocator.clear()called - Setup:
- Register
LightingService
- Register
- Steps:
- Call
ServiceLocator.clear() - Call
ServiceLocator.getLightingService() - Verify returns null
- Call
- Expected Result: Service cleared properly
Game Screen Integration Tests
Test 24: MainGameScreen Lighting Integration
Test Name: testMainGameScreenLightingIntegration
- Objective: Verify lighting system integrated into main game screen
- Setup:
- Create mock game dependencies
- Mock
GdxGame, renderer, physics engine
- Steps:
- Create
MainGameScreen(game) - Verify
LightingServiceregistered - Verify
lightingEnginefield populated - Call
render(0.016f)(one frame) - Verify no exceptions
- Call
dispose() - Verify
lightingEngine.dispose()called
- Create
- Expected Result: Lighting integrated and lifecycle managed correctly
Test 25: LevelsGameScreen Lighting Integration
Test Name: testLevelsGameScreenLightingIntegration
- Objective: Verify lighting integrated into levels game screen
- Setup: Mock game dependencies
- Steps:
- Create
LevelsGameScreen(game) - Verify
LightingServiceregistered - Call
render(0.016f) - Verify no exceptions
- Call
dispose()
- Create
- Expected Result: Screen renders with lighting, proper cleanup
Test 26: Level2GameScreen Lighting Integration
Test Name: testLevel2GameScreenLightingIntegration
- Objective: Verify lighting integrated into level 2 screen
- Setup: Mock game dependencies
- Steps:
- Create
Level2GameScreen(game) - Verify service registered
- Call
render(0.016f) - Verify no exceptions
- Create
- Expected Result: Screen renders with lighting
Test 27: SandboxGameScreen Lighting Integration
Test Name: testSandboxGameScreenLightingIntegration
- Objective: Verify lighting integrated into sandbox screen
- Setup: Mock game dependencies
- Steps:
- Create
SandboxGameScreen(game) - Verify service registered
- Call
render(0.016f) - Verify no exceptions
- Create
- Expected Result: Screen renders with lighting
Renderer Integration Tests
Test 28: Renderer with Lighting
Test Name: testRendererWithLighting
- Objective: Verify renderer correctly calls lighting render
- Setup:
- Create mock renderer
- Create mock
LightingEngine
- Steps:
- Call
renderer.render(lightingEngine) - Verify lighting engine's
render()called - Verify called after batch end
- Call
- Expected Result: Lighting rendered in correct order
Projectile Lighting Integration Tests
Test 29: Fire Arrow Creates Light
Test Name: testFireArrowCreatesLight
- Objective: Verify fire arrows emit correct colored light
- Setup:
- Register lighting service
- Create shooter entity
- Steps:
- Call
ProjectileFactory.createFireArrow(shooter, pos, dir) - Verify entity has
PointLightComponent - Verify component color is orange-red (0.55, 0.05, 0.02)
- Verify light distance is default
- Verify light rays is default
- Call
- Expected Result: Fire arrow emits correct orange-red light
Test 30: Ice Arrow Creates Light
Test Name: testIceArrowCreatesLight
- Objective: Verify ice arrows emit correct colored light
- Setup: Register lighting service, create shooter
- Steps:
- Call
ProjectileFactory.createIceArrow(shooter, pos, dir) - Verify component color is blue (0.05, 0.25, 0.65)
- Call
- Expected Result: Ice arrow emits correct blue light
Test 31: Poison Arrow Creates Light
Test Name: testPoisonArrowCreatesLight
- Objective: Verify poison arrows emit correct colored light
- Setup: Register lighting service, create shooter
- Steps:
- Call
ProjectileFactory.createPoisonArrow(shooter, pos, dir) - Verify component color is purple (0.20, 0.05, 0.25)
- Call
- Expected Result: Poison arrow emits correct purple light
Test 32: Poison Potion Creates Light
Test Name: testPoisonPotionCreatesLight
- Objective: Verify poison potions emit correct colored light
- Setup: Register lighting service, create shooter
- Steps:
- Call
ProjectileFactory.createThrownPoisonPotion(shooter, pos, dir) - Verify component color is purple (0.20, 0.05, 0.25)
- Call
- Expected Result: Poison potion emits correct purple light
User Settings Integration Tests
Test 33: Brightness Setting Persistence
Test Name: testBrightnessSettingPersistence
- Objective: Verify brightness saved and loaded
- Setup: None
- Steps:
- Get
UserSettings - Set
brightnessValue = 0.5f - Save settings
- Create new settings instance
- Verify
brightnessValue == 0.5f
- Get
- Expected Result: Brightness value persisted
Test 34: LightingEngine Uses User Brightness
Test Name: testLightingEngineUsesUserBrightness
- Objective: Verify engine initializes with user brightness setting
- Setup:
- Set
UserSettings.brightnessValue = 0.7f - Mock camera and world
- Set
- Steps:
- Create
LightingEngine(camera, world) - Verify initial ambient light is 0.7f
- Create
- Expected Result: Engine reads and applies user brightness
Performance Tests
Test 35: Render Performance with Multiple Lights
Test Name: testRenderPerformanceMultipleLights
- Objective: Verify render time acceptable with many lights
- Setup:
- Create
LightingEngine - Add 50 point lights to scene
- Create
- Steps:
- Measure render time
- Call
lightingEngine.render()100 times - Record average time
- Verify average < 16ms (60 FPS requirement)
- Expected Result: Render time acceptable for target frame rate
Test 36: Memory Test Light Disposal
Test Name: testMemoryTestLightDisposal
- Objective: Verify no memory leaks on light creation/destruction
- Setup:
- Create
LightingEngine - Record initial memory
- Create
- Steps:
- Create 1000 light components
- Dispose all lights
- Run garbage collection
- Verify final memory near initial
- Expected Result: No memory leak detected
Test 37: Update Performance with Velocity
Test Name: testUpdatePerformanceWithVelocity
- Objective: Verify update time acceptable with moving lights
- Setup:
- Create 20 lights with velocity
- Mock
TimeSource
- Steps:
- Measure update time
- Call
update()1000 times - Record average time
- Verify acceptable performance
- Expected Result: Update completes in reasonable time
Edge Case Tests
Test 38: Null RayHandler Handling
Test Name: testNullRayHandlerHandling
- Objective: Verify graceful handling of null ray handler
- Setup: Create component with null ray handler
- Steps:
- Call
create() - Call
update() - Call
dispose()
- Call
- Expected Result: Methods handle null gracefully or throw clear exceptions
Test 39: Null Entity Position
Test Name: testNullEntityPosition
- Objective: Verify handling of entity without position
- Setup:
- Create component
- Create entity without position set
- Steps:
- Call
create() - Call
update()
- Call
- Expected Result: Default position or clear error
Test 40: Rapid Active/Inactive Toggle
Test Name: testRapidActiveInactiveToggle
- Objective: Verify robustness under rapid state changes
- Setup:
- Create component with light
- Steps:
- Toggle
setActive()1000 times rapidly - Call
update()after each toggle
- Toggle
- Expected Result: No exceptions, state correctly tracked
Test 41: Zero Delta Time
Test Name: testZeroDeltaTime
- Objective: Verify handling of zero delta time
- Setup:
- Create component with velocity
- Mock
TimeSource.getDeltaTime()returning 0
- Steps:
- Call
update() - Verify entity position unchanged
- Call
- Expected Result: No movement, no exceptions
Test 42: Negative Delta Time
Test Name: testNegativeDeltaTime
- Objective: Verify handling of negative delta time
- Setup:
- Create component with velocity
- Mock
TimeSource.getDeltaTime()returning -0.016f
- Steps:
- Call
update() - Verify clamped to 0
- Call
- Expected Result: Delta clamped, no backward movement
Test Data / Fixtures
Mock Objects
MockCameraComponent: Returns valid projection matrixMockWorld: Provides physics world for ray handlerMockRayHandler: Spy on light creation/disposalMockEntity: Configurable position/center positionMockTimeSource: Controllable delta timeMockLightingEngine: Spy on render callsMockLightingService: Wrapped engine reference
Test Constants
public static final Vector2 TEST_POSITION = new Vector2(5f, 5f);
public static final Vector2 TEST_DIRECTION = new Vector2(1f, 0f);
public static final Color TEST_COLOR = Color.RED;
public static final float TEST_DISTANCE = 4f;
public static final int TEST_RAYS = 128;
public static final float TEST_SOFTNESS = 1f;
public static final float DELTA_TIME = 0.016f; // 60 FPS
Test Execution Strategy
Phase 1: Unit Tests
- Execute first
- No dependencies on other systems
- Fast feedback
- Target: 100% code coverage for lighting classes
Phase 2: Integration Tests
- Execute after unit tests pass
- Verify interaction with game screens
- Verify ServiceLocator integration
- Target: All integration scenarios covered
Phase 3: Performance Tests
- Execute on final build
- Verify frame rate targets met
- Identify optimization opportunities
- Document baseline metrics
Phase 4: Edge Case Tests
- Execute throughout development
- Add new cases as issues discovered
- Regression testing for fixes
Success Criteria
- Unit Tests: 100% pass rate, ≥90% code coverage
- Integration Tests: 100% pass rate on all game screens
- Performance Tests: Render time < 16ms with 50+ lights
- Edge Case Tests: All tests pass, no critical issues
- Manual Testing: Visual verification of light rendering in-game
Regression Test Suite
Run after any changes to:
LightingEngine,LightingService,PointLightComponent- Game screen constructors or render methods
ProjectileFactoryarrow creationUserSettingsbrightness configuration