• ↑↓ pour naviguer
  • pour ouvrir
  • pour sélectionner
  • ⌘ ⌥ ↵ pour ouvrir dans un panneau
  • esc pour rejeter
⌘ '
raccourcis clavier

1

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
}
StateDescription/Objectives/ReasoningJustification
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,270deg0\deg, 90\deg, 180\deg, 270\deg) 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 testingVerify method contracts:
- Constructor initializations
- Getter/setter validation
- Direction reversal logic per requirements
- Speed/direction relationships (0deg0\deg → positive X, 90deg90\deg → positive Y)
- Test behavior at edge cases (minimum/maximum values, boundary angles)
black-box testing
Interaction-based testingTest 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
Implementation-based testingValidate internal logic:
- Angle normalization (e.g., 450deg90deg450\deg \to 90\deg)
- Negative speed handling
- Float-to-integer conversion precision
- Edge cases (0deg,90deg,180deg,270deg0\deg, 90\deg, 180\deg, 270\deg directions)
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.

Class invariants for Velocity:

- speed >= 0 (non-negativity)
- speedX = speed * cos(direction)
- speedY = speed * sin(direction)
- direction >= 0 && direction < 360
- (direction > 90 && direction < 270) ==> speedX < 0
- (direction > 180 && direction < 360) ==> speedY < 0

Methods contracts:

/* @constructor Velocity()
 * @precondition  None (no preconditions for default constructor)
 * @postcondition speed == 0
 *                direction == 0
 *                speedX == 0
 *                speedY == 0
 */
public Velocity();
 
/* @constructor Velocity(Speed speed, Direction direction)
* @precondition  speed >= 0
*                direction >= 0 && direction < 360
* @postcondition this.speed == speed
*                this.direction == direction
*                speedX == speed * cos(direction)
*                speedY == speed * sin(direction)
*/
public Velocity(Speed speed, Direction direction);
 
/* @method getSpeed
* @precondition  true
* @postcondition \result == speed && unchanged(this)
*/
public Speed getSpeed();
 
/* @method getSpeedX
* @precondition  true
* @postcondition \result == speedX && unchanged(this)
*/
public Speed getSpeedX();
 
/* @method getSpeedY
* @precondition  true
* @postcondition \result == speedY && unchanged(this)
*/
public Speed getSpeedY();
 
/* @method getDirection
* @precondition  true
* @postcondition \result == direction && unchanged(this)
*/
public Direction getDirection();
 
/* @method setSpeed
* @precondition  speed >= 0
* @postcondition this.speed == speed
*                speedX == speed * cos(direction)
*                speedY == speed * sin(direction)
*/
public void setSpeed(Speed speed);
 
/* @method setDirection
* @precondition  direction >= 0 && direction < 360
* @postcondition this.direction == direction
*                speedX == speed * cos(direction)
*                speedY == speed * sin(direction)
*/
public void setDirection(Direction direction);
 
/* @method reverse
* @precondition  true
* @postcondition direction == (old(direction) + 180) % 360
*                speedX == -old(speedX)
*                speedY == -old(speedY)
*                speed == old(speed)
*/
public void reverse();
 
/* @method reverseX
* @precondition  true
* @postcondition speedX == -old(speedX)
*                speedY == old(speedY)
*                speed == old(speed)
*                (old(direction) >= 0 && old(direction) < 180) ==>
*                direction == (180 - old(direction)) % 360
*                (old(direction) >= 180 && old(direction) < 360) ==>
*                direction == (540 - old(direction)) % 360
*/
public void reverseX();
 
/* @method reverseY
* @precondition  true
* @postcondition speedY == -old(speedY)
*                speedX == old(speedX)
*                speed == old(speed)
*                direction == (360 - old(direction)) % 360
*/
public void reverseY();

3

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°) = 0
assertEquals(10, velocity.getSpeedY()); // sin(90°) = 1 * 10
assertEquals(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 degrees
velocity.setSpeed(10); // Double the speed
assertEquals(45, velocity.getDirection()); // Direction should remain unchanged
assertEquals(7.07, velocity.getSpeedX(), 0.01); // (cos(45 deg) := 0.707) * 10
assertEquals(7.07, velocity.getSpeedY(), 0.01); // (sin(45 deg) :=  0.707) * 10
assertEquals(10, velocity.getSpeed()); // Speed should be updated to 10

reverse

Case 1: Reverse direction from East

// Arrange
Velocity velocity = new Velocity(10, 0); // Speed 10, direction 0 (East)
velocity.reverse();
assertEquals(180, velocity.getDirection()); // Should now be West
assertEquals(-10, velocity.getSpeedX()); // Should be negated
assertEquals(0, velocity.getSpeedY()); // Should remain 0
assertEquals(10, velocity.getSpeed()); // Speed magnitude should be unchanged

Case 2: Reverse direction from North

// Arrange
Velocity velocity = new Velocity(10, 90); // Speed 10, direction 90 (North)
velocity.reverse();
assertEquals(270, velocity.getDirection()); // Should now be South
assertEquals(0, velocity.getSpeedX()); // Should remain 0
assertEquals(-10, velocity.getSpeedY()); // Should be negated
assertEquals(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 Southeast
assertEquals(7.07, velocity.getSpeedX(), 0.01); // Should be negated from -7.07
assertEquals(-7.07, velocity.getSpeedY(), 0.01); // Should be negated from 7.07
assertEquals(10, velocity.getSpeed()); // Speed magnitude should be unchanged

Case 4: Reverse direction from speed=0

Velocity velocity = new Velocity(0, 45); // Speed 0, direction 45
velocity.reverse();
assertEquals(225, velocity.getDirection()); // Should be opposite
assertEquals(0, velocity.getSpeedX()); // Should remain 0
assertEquals(0, velocity.getSpeedY()); // Should remain 0
assertEquals(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 0
assertEquals(10, velocity.getSpeedY()); // Should be negated from -10
assertEquals(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 West
assertEquals(-10, velocity.getSpeedX()); // Should be negated
assertEquals(0, velocity.getSpeedY()); // Should remain unchanged
assertEquals(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 0
assertEquals(10, velocity.getSpeedY()); // Should remain unchanged
assertEquals(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 Northwest
assertEquals(-7.07, velocity.getSpeedX(), 0.01); // Should be negated from 7.07
assertEquals(7.07, velocity.getSpeedY(), 0.01); // Should remain unchanged
assertEquals(10, velocity.getSpeed()); // Speed magnitude should be unchanged

Case 4: reverseX from Southwest

// Arrange
Velocity velocity = new Velocity(10, 225); // Speed 10, direction 225 (Southwest)
velocity.reverseX();
assertEquals(315, velocity.getDirection()); // Should become Southeast
assertEquals(7.07, velocity.getSpeedX(), 0.01); // Should be negated from -7.07
assertEquals(-7.07, velocity.getSpeedY(), 0.01); // Should remain unchanged
assertEquals(10, velocity.getSpeed()); // Speed magnitude should be unchanged

Case 5: reverseX from Zero speed

Velocity velocity = new Velocity(0, 45); // Speed 0, direction 45
velocity.reverseX();
assertEquals(135, velocity.getDirection()); // Direction should change
assertEquals(0, velocity.getSpeedX()); // Should remain 0
assertEquals(0, velocity.getSpeedY()); // Should remain 0
assertEquals(0, velocity.getSpeed()); // Speed magnitude should be unchanged