---
date: '2025-04-06'
description: and static analysis
id: a3
modified: 2026-06-05 15:08:39 GMT-04:00
tags:
  - sfwr3s03
title: Testing Breakout
created: '2025-04-06'
published: '2025-04-06'
pageLayout: default
slug: thoughts/university/twenty-four-twenty-five/sfwr-3s03/a3
permalink: https://aarnphm.xyz/thoughts/university/twenty-four-twenty-five/sfwr-3s03/a3.md
generator:
  quartz: v4.6.0
  hostedProvider: Cloudflare
  baseUrl: aarnphm.xyz
full: https://aarnphm.xyz/llms-full.txt
---
> \[!question\] 1
>
> Using a table, specify a test plan for the `Velocity` class:
>
> ```java
> 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)<br>- Properly calculate and update velocity components (`speedX`, `speedY`) and maintain class invariants.<br>- Support collision physics for the puck’s interactions with walls, bricks, and player<br>- Ensure velocity remains within acceptable bounds for gameplay<br>- 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<br>- Inspect boundary cases (e.g., direction at $0\deg, 90\deg, 180\deg, 270\deg$) to ensure proper component calculations<br>- Verify consistency of velocity after multiple reverse operations<br>- Review for proper encapsulation and state management<br><br>**Justification**:<br/>- velocity calculations involve trigonometric relationships that are error-prone and might not be fully exercised through manual testing alone.<br/>- 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: <br/>- Constructor initializations<br/>- Getter/setter validation<br/>- Direction reversal logic per requirements<br/>- Speed/direction relationships ($0\deg$ → positive X, $90\deg$ → positive Y)<br/>- Test behavior at edge cases (minimum/maximum values, boundary angles)                                                                                                                                                                                                                                                                                                                                                              | black-box testing                                                                          |
| Interaction-based testing    | Test method sequences:<br/>- `reverseX()` → `reverseY()` should equal `reverse()`<br/>- `setDirection()` → `getSpeedX/Y()` consistency<br/>- Multiple reverses followed by speed changes<br/>- Test for potential overflow or precision issues in calculations                                                                                                                                                                                                                                                                                                                                                                                                        | Reveal potential intergrations problems between components                                 |
| Implementation-based testing | Validate internal logic:<br/>- Angle normalization (e.g., $450\deg \to 90\deg$)<br/>- Negative speed handling<br/>- Float-to-integer conversion precision<br/>- Edge cases ($0\deg, 90\deg, 180\deg, 270\deg$ directions)                                                                                                                                                                                                                                                                                                                                                                                                                                             | Code-coverage and branch-coverage to ensure no regression will be introduced in the future |

> \[!question\] 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`:

```prolog
- 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:

```java
/* @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();
```

> \[!question\] 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_

```java
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_

```java
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_

```java
// 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_

```java
// 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_

```java
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`_

```java
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_

```java
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_

```java
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_

```java
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_

```java
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_

```java
// 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_

```java
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
```

