Using a table, specify a test plan for the Velocity class:
public class Velocity { private Speed speed, speedX, speedY; private Direction direction; public Velocity(); //constructor public Velocity(Speed speed, Direction direction); //constructor public Speed getSpeed(); public Speed getSpeedX(); // get speed in X direction public Speed getSpeedY(); // get speed in Y direction public Direction getDirection(); public void setSpeed(Speed speed); public void setDirection(Direction direction); public void reverse(); // reverse the direction of the puck! public void reverseX(); // reverse the direction of the puck in x-axis public void reverseY(); // reverse direction of the puck in the y-axis}
State
Description/Objectives/Reasoning
Justification
Objectives
- Accurately represent and maintain the puck’s velocity (speed and direction) - Properly calculate and update velocity components (speedX, speedY) and maintain class invariants. - Support collision physics for the puck’s interactions with walls, bricks, and player - Ensure velocity remains within acceptable bounds for gameplay - Maintain internal consistency between speed, direction, and component values
functionalities are reliable, while preserving directional semantics
Inspection requirements
- Review relationship between direction angle and speedX/speedY calculations to ensure mathematical correctness - Inspect boundary cases (e.g., direction at 0deg,90deg,180deg,270deg) to ensure proper component calculations - Verify consistency of velocity after multiple reverse operations - Review for proper encapsulation and state management
Justification: - velocity calculations involve trigonometric relationships that are error-prone and might not be fully exercised through manual testing alone. - Additionally, the class manages state that must maintain mathematical consistency across operations.
early detection in numerical abnormaly, esp. with floating points
Specification-based testing
Verify method contracts: - Constructor initializations - Getter/setter validation - Direction reversal logic per requirements - Speed/direction relationships (0deg → positive X, 90deg → positive Y) - Test behavior at edge cases (minimum/maximum values, boundary angles)
black-box testing
Interaction-based testing
Test method sequences: - reverseX() → reverseY() should equal reverse() - setDirection() → getSpeedX/Y() consistency - Multiple reverses followed by speed changes - Test for potential overflow or precision issues in calculations
Reveal potential intergrations problems between components
Code-coverage and branch-coverage to ensure no regression will be introduced in the future
2
Based on what was discussed in lectures, in terms of contracts and contract-based specification, write preconditions and postconditions for each method of Velocity (including the two constructors). Also, write a class invariant: it specifies (as a boolean expression) properties that must be true for all instances of class Velocity.
Informally define a set of test cases for the following methods:
setDirection – define exactly one test case
setSpeed – define exactly one test case
reverse – define 5 test cases
reverseX – define 5 test cases
setDirection
Case 1: Change direction from East to North
Velocity velocity = new Velocity(10, 0); // Speed 10, direction 0 (East)velocity.setDirection(90); // Change direction to 90 (North)assertEquals(90, velocity.getDirection());assertEquals(0, velocity.getSpeedX()); // cos(90°) = 0assertEquals(10, velocity.getSpeedY()); // sin(90°) = 1 * 10assertEquals(10, velocity.getSpeed()); // Speed magnitude should remain the same
setSpeed
Case 1: Change speed while in the same direction
Velocity velocity = new Velocity(5, 45); // Speed 5, direction 45 degreesvelocity.setSpeed(10); // Double the speedassertEquals(45, velocity.getDirection()); // Direction should remain unchangedassertEquals(7.07, velocity.getSpeedX(), 0.01); // (cos(45 deg) := 0.707) * 10assertEquals(7.07, velocity.getSpeedY(), 0.01); // (sin(45 deg) := 0.707) * 10assertEquals(10, velocity.getSpeed()); // Speed should be updated to 10
reverse
Case 1: Reverse direction from East
// ArrangeVelocity velocity = new Velocity(10, 0); // Speed 10, direction 0 (East)velocity.reverse();assertEquals(180, velocity.getDirection()); // Should now be WestassertEquals(-10, velocity.getSpeedX()); // Should be negatedassertEquals(0, velocity.getSpeedY()); // Should remain 0assertEquals(10, velocity.getSpeed()); // Speed magnitude should be unchanged
Case 2: Reverse direction from North
// ArrangeVelocity velocity = new Velocity(10, 90); // Speed 10, direction 90 (North)velocity.reverse();assertEquals(270, velocity.getDirection()); // Should now be SouthassertEquals(0, velocity.getSpeedX()); // Should remain 0assertEquals(-10, velocity.getSpeedY()); // Should be negatedassertEquals(10, velocity.getSpeed()); // Speed magnitude should be unchanged
Case 3: Reverse direction from NW
Velocity velocity = new Velocity(10, 135); // Speed 10, direction 135 (Northwest)velocity.reverse();assertEquals(315, velocity.getDirection()); // Should now be SoutheastassertEquals(7.07, velocity.getSpeedX(), 0.01); // Should be negated from -7.07assertEquals(-7.07, velocity.getSpeedY(), 0.01); // Should be negated from 7.07assertEquals(10, velocity.getSpeed()); // Speed magnitude should be unchanged
Case 4: Reverse direction from speed=0
Velocity velocity = new Velocity(0, 45); // Speed 0, direction 45velocity.reverse();assertEquals(225, velocity.getDirection()); // Should be oppositeassertEquals(0, velocity.getSpeedX()); // Should remain 0assertEquals(0, velocity.getSpeedY()); // Should remain 0assertEquals(0, velocity.getSpeed()); // Speed magnitude should be unchanged
Case 5: Reverse Direction Wrap-Around
Velocity velocity = new Velocity(10, 270); // Speed 10, direction 270 (South)velocity.reverse();assertEquals(90, velocity.getDirection()); // Should wrap around to 90 (North)assertEquals(0, velocity.getSpeedX()); // Should remain 0assertEquals(10, velocity.getSpeedY()); // Should be negated from -10assertEquals(10, velocity.getSpeed()); // Speed magnitude should be unchanged
reverseX
Case 1: reverseX from East
Velocity velocity = new Velocity(10, 0); // Speed 10, direction 0 (East)velocity.reverseX();assertEquals(180, velocity.getDirection()); // Should now be WestassertEquals(-10, velocity.getSpeedX()); // Should be negatedassertEquals(0, velocity.getSpeedY()); // Should remain unchangedassertEquals(10, velocity.getSpeed()); // Speed magnitude should be unchanged
Case 2: reverseX from North
Velocity velocity = new Velocity(10, 90); // Speed 10, direction 90 (North)velocity.reverseX();assertEquals(90, velocity.getDirection()); // Should remain North (no X component)assertEquals(0, velocity.getSpeedX()); // Should remain 0assertEquals(10, velocity.getSpeedY()); // Should remain unchangedassertEquals(10, velocity.getSpeed()); // Speed magnitude should be unchanged
Case 3: reverseX from Northeast
Velocity velocity = new Velocity(10, 45); // Speed 10, direction 45 (Northeast)velocity.reverseX();assertEquals(135, velocity.getDirection()); // Should become NorthwestassertEquals(-7.07, velocity.getSpeedX(), 0.01); // Should be negated from 7.07assertEquals(7.07, velocity.getSpeedY(), 0.01); // Should remain unchangedassertEquals(10, velocity.getSpeed()); // Speed magnitude should be unchanged
Case 4: reverseX from Southwest
// ArrangeVelocity velocity = new Velocity(10, 225); // Speed 10, direction 225 (Southwest)velocity.reverseX();assertEquals(315, velocity.getDirection()); // Should become SoutheastassertEquals(7.07, velocity.getSpeedX(), 0.01); // Should be negated from -7.07assertEquals(-7.07, velocity.getSpeedY(), 0.01); // Should remain unchangedassertEquals(10, velocity.getSpeed()); // Speed magnitude should be unchanged
Case 5: reverseX from Zero speed
Velocity velocity = new Velocity(0, 45); // Speed 0, direction 45velocity.reverseX();assertEquals(135, velocity.getDirection()); // Direction should changeassertEquals(0, velocity.getSpeedX()); // Should remain 0assertEquals(0, velocity.getSpeedY()); // Should remain 0assertEquals(0, velocity.getSpeed()); // Speed magnitude should be unchanged