Prompt Details
Model
(claude-5-5-opus)
Token size
2,275
Example input
[CODE_TO_TEST]: calculate_shipping_cost(weight_kg, destination_zone, is_expedited): looks up a base rate per zone from {zone_1:5.0, zone_2:8.0, zone_3:12.0, zone_4:20.0}, raises ValueError for an unknown zone, adds (weight_kg-5)*1.5 when weight exceeds 5kg, raises ValueError when expediting to zone_4, otherwise multiplies by 1.5 when expedited, then rounds to 2 decimals.
[TESTING_FRAMEWORK]: pytest
[EXISTING_TEST_CONVENTIONS]: Tests use pytest.mark.parametrize for input variations and are named test_<function>_<scenario>; fixtures live in conftest.py
[EDGE_CASES_OR_REQUIREMENTS_CONTEXT]: Zone 4 (international) has no expedited option and should raise a ValueError if is_expedited=True is passed with destination_zone="zone_4"
Example output
# UNIT_TEST_SUITE: `calculate_shipping_cost`
## 1. Code Understanding & Testability Assessment
**Behavior.** `calculate_shipping_cost(weight_kg, destination_zone, is_expedited)` returns a shipping cost as a float rounded to 2 decimals. The evaluation order, as supplied, is:
1. Look up the base rate for `destination_zone` in `{zone_1: 5.0, zone_2: 8.0, zone_3: 12.0, zone_4: 20.0}`; raise `ValueError` if the zone is not a key.
2. If `weight_kg > 5`, add `(weight_kg - 5) * 1.5`.
3. If `is_expedited` and the zone is `zone_4`, raise `ValueError`.
4. Otherwise, if `is_expedited`, multiply the running cost by 1.5.
5. Round to 2 decimals and return.
**Inputs:** a numeric weight in kg, a zone string, an expedite flag.
**Outputs:** a rounded float, or a `ValueError`.
**Side effects:** none.
**External dependencies:** none (no network, file I/O, database, clock, or randomness). The function is pure and deterministic.
**Testability flags.**
- The rate table, the 5 kg threshold, the 1.5 per-kg surcharge, and the 1.5 expedite multiplier are hard-coded values. Tests must assert against literal expected results rather than reading constants, so a change to any constant fails the tests, which is the desired behavior.
- No input validation on `weight_kg` is described (zero, negative, non-numeric). Behavior for those inputs is unspecified and therefore not asserted (see Sections 4 and 7).
- The supplied description does not state the `ValueError` messages, so messages cannot be asserted.
- The description states the expedite multiplier is applied after the weight surcharge, but does not say explicitly whether it scales the surcharge too. That reading affects expected values for any expedited overweight parcel (see `<NEEDS-INPUT: expedite-multiplier-scope>`).
- Return values are floats. Exact `==` comparison is used on values that are exactly representable or already rounded to 2 decimals; `pytest.approx` is avoided because it would mask rounding defects.
## 2. Test Case Inventory
Evidence tags: **[code]** = derived directly from code logic; **[req]** = derived from requirements context; **[needs-input]** = `<NEEDS-INPUT: id>`.
### Happy path
- **`test_calculate_shipping_cost_base_rate_per_zone_standard_under_threshold`** **[code]**. Parametrized over all four zones, weight 3 kg, not expedited. Expected: 5.0, 8.0, 12.0, 20.0 respectively (base rate only; no surcharge, no multiplier).
- **`test_calculate_shipping_cost_overweight_standard_adds_surcharge`** **[code]**. Parametrized: `zone_1` at 7 kg expects 8.0 (5.0 + 2 × 1.5); `zone_3` at 10 kg expects 19.5 (12.0 + 5 × 1.5). Not expedited.
- **`test_calculate_shipping_cost_expedited_under_threshold_multiplies_base_by_1_5`** **[code]**. Parametrized over `zone_1`, `zone_2`, `zone_3` at 3 kg, expedited. Expected: 7.5, 12.0, 18.0. Isolates the ×1.5 branch from the surcharge branch.
### Boundary conditions
- **`test_calculate_shipping_cost_weight_exactly_5kg_has_no_surcharge`** **[code]**. The condition is "exceeds 5 kg", so exactly 5 kg is on the non-surcharge side. Parametrized on `zone_2` at 5 kg: standard expects 8.0; expedited expects 12.0.
- **`test_calculate_shipping_cost_weight_just_above_5kg_has_surcharge`** **[code]**. `zone_1` at 5.5 kg, standard. Expected: 5.75 (5.0 + 0.5 × 1.5).
- **`test_calculate_shipping_cost_result_rounded_to_two_decimals`** **[code]**. `zone_1` at 5.333 kg, standard. Unrounded result is approximately 5.4995; expected 5.5. Fails if the final rounding step is removed or changed to a different precision.
- **`test_calculate_shipping_cost_zone_4_standard_overweight_is_allowed`** **[code]**. `zone_4` at 8 kg, not expedited. Expected: 24.5 (20.0 + 3 × 1.5). Confirms the `zone_4` restriction applies only to expedited requests, not to the zone or to overweight parcels.
### Error handling
- **`test_calculate_shipping_cost_unknown_zone_raises_value_error`** **[code]**. Parametrized on `zone_5` and `zone_0`, 3 kg, not expedited. Expected: `ValueError` (message not asserted; see Section 7).
- **`test_calculate_shipping_cost_zone_4_expedited_raises_value_error`** **[code, req]**. Parametrized over weights 1, 5, 5.5, 50 kg with `destination_zone="zone_4"` and `is_expedited=True`. Expected: `ValueError` at every weight, including above the surcharge threshold, since the restriction is independent of weight.
### Business-rule cases (from requirements context)
- The requirement that `zone_4` has no expedited option and raises `ValueError` is covered by `test_calculate_shipping_cost_zone_4_expedited_raises_value_error` above. The supplied code logic already implements this rule, so this test is expected to pass; no currently-failing gap was identified from the requirements context.
### Cases pending confirmation
- **`test_calculate_shipping_cost_expedited_overweight_multiplier_scope`** **[needs-input]** `<NEEDS-INPUT: expedite-multiplier-scope>`. `zone_2` at 7 kg, expedited. Under the reading "×1.5 applies to the running total after the surcharge", expected is 16.5 ((8.0 + 3.0) × 1.5). Under the alternative reading "×1.5 applies to the base rate only", expected would be 15.0 (12.0 + 3.0). The test is implemented against the first reading, which follows the stated evaluation order, and must be confirmed before being trusted as a regression guard.
## 3. Test Implementation
Framework: pytest, matching the supplied conventions (`pytest.mark.parametrize` for input variations, `test_<function>_<scenario>` naming). No fixtures are used because the function is pure and has no setup requirements, so nothing is added to `conftest.py`.
```python
# test_shipping.py
import pytest
# <NEEDS-INPUT: module-import-path>
from shipping import calculate_shipping_cost
@pytest.mark.parametrize(
"zone, expected",
[
("zone_1", 5.0),
("zone_2", 8.0),
("zone_3", 12.0),
("zone_4", 20.0),
],
)
def test_calculate_shipping_cost_base_rate_per_zone_standard_under_threshold(zone, expected):
result = calculate_shipping_cost(weight_kg=3, destination_zone=zone, is_expedited=False)
assert result == expected
@pytest.mark.parametrize(
"zone, weight_kg, expected",
[
("zone_1", 7, 8.0), # 5.0 + (7 - 5) * 1.5
("zone_3", 10, 19.5), # 12.0 + (10 - 5) * 1.5
],
)
def test_calculate_shipping_cost_overweight_standard_adds_surcharge(zone, weight_kg, expected):
result = calculate_shipping_cost(weight_kg=weight_kg, destination_zone=zone, is_expedited=False)
assert result == expected
@pytest.mark.parametrize(
"zone, expected",
[
("zone_1", 7.5), # 5.0 * 1.5
("zone_2", 12.0), # 8.0 * 1.5
("zone_3", 18.0), # 12.0 * 1.5
],
)
def test_calculate_shipping_cost_expedited_under_threshold_multiplies_base_by_1_5(zone, expected):
result = calculate_shipping_cost(weight_kg=3, destination_zone=zone, is_expedited=True)
assert result == expected
@pytest.mark.parametrize(
"is_expedited, expected",
[
(False, 8.0),
(True, 12.0),
],
)
def test_calculate_shipping_cost_weight_exactly_5kg_has_no_surcharge(is_expedited, expected):
result = calculate_shipping_cost(weight_kg=5, destination_zone="zone_2", is_expedited=is_expedited)
assert result == expected
def test_calculate_shipping_cost_weight_just_above_5kg_has_surcharge():
result = calculate_shipping_cost(weight_kg=5.5, destination_zone="zone_1", is_expedited=False)
assert result == 5.75 # 5.0 + 0.5 * 1.5
def test_calculate_shipping_cost_result_rounded_to_two_decimals():
# Unrounded: 5.0 + 0.333 * 1.5 ~= 5.4995
result = calculate_shipping_cost(weight_kg=5.333, destination_zone="zone_1", is_expedited=False)
assert result == 5.5
def test_calculate_shipping_cost_zone_4_standard_overweight_is_allowed():
result = calculate_shipping_cost(weight_kg=8, destination_zone="zone_4", is_expedited=False)
assert result == 24.5 # 20.0 + 3 * 1.5
@pytest.mark.parametrize("zone", ["zone_5", "zone_0"])
def test_calculate_shipping_cost_unknown_zone_raises_value_error(zone):
with pytest.raises(ValueError):
calculate_shipping_cost(weight_kg=3, destination_zone=zone, is_expedited=False)
@pytest.mark.parametrize("weight_kg", [1, 5, 5.5, 50])
def test_calculate_shipping_cost_zone_4_expedited_raises_value_error(weight_kg):
with pytest.raises(ValueError):
calculate_shipping_cost(weight_kg=weight_kg, destination_zone="zone_4", is_expedited=True)
def test_calculate_shipping_cost_expedited_overweight_multiplier_scope():
# <NEEDS-INPUT: expedite-multiplier-scope>
# Assumes the x1.5 multiplier applies to the running total (base + surcharge).
# If the multiplier applies to the base rate only, the correct value is 15.0.
result = calculate_shipping_cost(weight_kg=7, destination_zone="zone_2", is_expedited=True)
assert result == 16.5 # (8.0 + 2 * 1.5) * 1.5
```
## 4. Coverage Gap Analysis
Covered: every explicit branch in the supplied logic: all four zone lookups, unknown-zone error, the surcharge branch (above 5 kg), the no-surcharge side (at and below 5 kg), the `zone_4` expedited error, the expedited ×1.5 branch, and final rounding.
Not covered:
- **Zero, negative, or non-numeric `weight_kg`.** No condition in the supplied logic branches on these, so no boundary is invented for them (a negative weight would silently return the base rate). Whether these should raise is a requirements question (`<NEEDS-INPUT: invalid-weight-behavior>`).
- **Zone string normalization** (case, surrounding whitespace, `None`). The supplied logic describes an exact-key lookup; whether `"ZONE_1"` or `" zone_1"` should be accepted is unspecified (`<NEEDS-INPUT: zone-key-normalization>`).
- **Non-boolean `is_expedited` values** (truthy/falsy non-bools). Not described in the supplied logic.
- **Exact rounding-tie behavior** (e.g. a value landing precisely on a half-cent). Python's `round` uses round-half-to-even on binary floats, and constructing a reliable tie in binary floating point is impractical; only a clearly non-tie rounding case is tested (`<NEEDS-INPUT: rounding-mode-expectation>`).
- **Very large weights and float overflow.** No branch depends on them and they are of no practical unit-test value here.
- **Error message text.** Not supplied, so only the exception type is asserted (`<NEEDS-INPUT: error-message-text>`).
- **Mutation of the rate table at runtime.** Not applicable if the table is a module constant; not verified.
- **Expedited overweight scope** is covered only provisionally (see `<NEEDS-INPUT: expedite-multiplier-scope>`).
## 5. Mocking & Dependency Isolation Strategy
No external dependencies were identified in Section 1: no network, file I/O, database, clock, or randomness. Consequently no mocks, stubs, fakes, or monkeypatching are used. This is deliberate. The rate table and multipliers are exercised as real code paths; patching them would make the tests independent of the values they are meant to lock in. No `conftest.py` fixtures are required.
## 6. Assertion Rationale
- **Exact `==` on floats (all success-path tests):** every expected value is either exactly representable in binary floating point or already rounded to 2 decimals, so exact equality is valid. `pytest.approx` is avoided because a loose tolerance could hide a rounding regression.
- **`test_calculate_shipping_cost_weight_exactly_5kg_has_no_surcharge`:** fails if the comparison changes from `>` to `>=` (surcharge of 0 would not change the result, so the fixed 5.0 kg case with the expedite parametrization also guards the multiplier ordering; the value 12.0 confirms no surcharge leaks in).
- **`test_calculate_shipping_cost_weight_just_above_5kg_has_surcharge`:** fails if the surcharge is dropped, or if the `weight_kg - 5` offset changes (for example to `weight_kg`).
- **`test_calculate_shipping_cost_result_rounded_to_two_decimals`:** fails if `round(..., 2)` is removed or changed to another precision, since the unrounded value (about 5.4995) differs from 5.5.
- **`test_calculate_shipping_cost_zone_4_standard_overweight_is_allowed`:** fails if the `zone_4` restriction is broadened to cover non-expedited requests or overweight parcels.
- **`test_calculate_shipping_cost_zone_4_expedited_raises_value_error` at 50 kg and 5.5 kg:** fails if the `zone_4` check is moved before the weight logic in a way that lets heavy parcels bypass it, or is made conditional on weight.
- **`test_calculate_shipping_cost_expedited_overweight_multiplier_scope`:** fails if the order of the surcharge and multiplier steps changes; 16.5 versus 15.0 distinguishes the two readings.
## 7. Open Questions & Data Requests
1. `<NEEDS-INPUT: expedite-multiplier-scope>`: When a parcel is expedited and over 5 kg, should the ×1.5 multiplier apply to the base rate plus the weight surcharge (16.5 for `zone_2` at 7 kg), or to the base rate only (15.0)?
2. `<NEEDS-INPUT: module-import-path>`: What is the actual module path from which `calculate_shipping_cost` is imported? The test file uses `from shipping import calculate_shipping_cost` as a stand-in.
3. `<NEEDS-INPUT: invalid-weight-behavior>`: Should a weight of zero, a negative weight, or a non-numeric weight raise an error, or is returning the base rate acceptable?
4. `<NEEDS-INPUT: zone-key-normalization>`: Should zone identifiers be case-insensitive or whitespace-tolerant (`"ZONE_1"`, `" zone_1"`), or is exact-match lookup the intended behavior?
5. `<NEEDS-INPUT: error-message-text>`: Are the `ValueError` messages for unknown zones and for expedited `zone_4` part of the contract? If so, what is the exact text, so `pytest.raises(..., match=...)` can be added?
6. `<NEEDS-INPUT: rounding-mode-expectation>`: Is Python's default `round` (round-half-to-even on binary floats) the intended rounding behavior for currency, or should half-cent values round up (e.g. via `Decimal`)?
Get this prompt + 9 more with SelectFrom $14/mo · Cancel anytimeFrom $14/mo · Cancel anytime
View SelectBy purchasing this prompt, you agree to our terms of service
CLAUDE-5-5-OPUS
🧠 Turns your real inputs into a structured unit test case generator—not a generic checklist or guesswork. Produces UNIT_TEST_SUITE.md covering Code Understanding & Testability Assessment, Test Case Inventory, Test Implementation, with evidence gaps clearly flagged instead of invented details. Built for engineers, developers, QA leads, and technical teams who need traceable analysis they can act on. 🎯
...more
Added 1 week ago
