TT Lab
Get started
Learn Learning paths Courses

Testing Tools in Practice

Catch real faults with boundary tests

Continue in TT Lab

Goal

You run the same pytest tests against a correct implementation of a price function and eight defective implementations.

Why it matters

Success on one normal request does not guarantee boundary values or failure recovery. In this lab you implement or test the contract of each function in small pieces and then connect them in real execution. The grader does not look only at whether code exists or at the wording of a report; it checks results, exceptions, and stored state. Keep the code from the earlier steps as you move to the next step.

Steps

  1. In /root/work/test-boundaries-lab/test_service.py, write a pytest test that asserts that price(0) is exactly 0. Merely calling the function or checking that the result is an int is not enough. Do the first preparation with the following command.
mkdir -p /root/work/test-boundaries-lab
cp /opt/fixtures/practice_depth/test-boundaries-lab/* /root/work/test-boundaries-lab/
cd /root/work/test-boundaries-lab
  1. In /root/work/test-boundaries-lab/test_service.py, test that the amount for price(1) is 350. Keep the existing test for 0 items as well.
  2. In /root/work/test-boundaries-lab/test_service.py, test that price(9) is 3150. It must detect an implementation that wrongly discounts from 9 items.
  3. In /root/work/test-boundaries-lab/test_service.py, test that price(10) is 3000. It catches the error of a > condition that does not discount at 10 items.
  4. In /root/work/test-boundaries-lab/test_service.py, test that price(11) is 3300. It detects an implementation that returns a fixed 3000 for the whole discount range.
  5. In /root/work/test-boundaries-lab/test_service.py, use pytest.raises to check that price(100) is 30000 and that price(101) is a ValueError.
  6. In /root/work/test-boundaries-lab/test_service.py, test that price(-1) is a ValueError. Do not treat returning a negative price as normal handling.
  7. In /root/work/test-boundaries-lab/test_service.py, add a parametrized test that True, False, 1.0, '1', and None are all TypeError. In particular, it must catch the defect that accepts bool as an int.

Notes

Guard the minimum charge for an empty order

In /root/work/test-boundaries-lab/test_service.py, write a pytest test that asserts that price(0) is exactly 0. Merely calling the function or checking that the result is an int is not enough. Do the first preparation with the following command.

mkdir -p /root/work/test-boundaries-lab
cp /opt/fixtures/practice_depth/test-boundaries-lab/* /root/work/test-boundaries-lab/
cd /root/work/test-boundaries-lab

Think of the defect that charges 350 even for an empty order.

You can reproduce the grading directly with bash /opt/lab/checks/test-boundaries-lab/01-contract.sh. Save the file and run it again.

Confirm the minimum valid quantity

In /root/work/test-boundaries-lab/test_service.py, test that the amount for price(1) is 350. Keep the existing test for 0 items as well.

A check that the price is positive lets a bug that charges 400 pass.

You can reproduce the grading directly with bash /opt/lab/checks/test-boundaries-lab/02-contract.sh. Save the file and run it again.

Catch the boundary just before the discount

In /root/work/test-boundaries-lab/test_service.py, test that price(9) is 3150. It must detect an implementation that wrongly discounts from 9 items.

The value just before the discount starts plays a different role from an ordinary middle value.

You can reproduce the grading directly with bash /opt/lab/checks/test-boundaries-lab/03-contract.sh. Save the file and run it again.

Include the discount starting point

In /root/work/test-boundaries-lab/test_service.py, test that price(10) is 3000. It catches the error of a > condition that does not discount at 10 items.

Read the policy table again to see whether the condition should be true at the boundary.

You can reproduce the grading directly with bash /opt/lab/checks/test-boundaries-lab/04-contract.sh. Save the file and run it again.

Do not mistake the discounted amount for a constant

In /root/work/test-boundaries-lab/test_service.py, test that price(11) is 3300. It detects an implementation that returns a fixed 3000 for the whole discount range.

If you check only one point at the boundary, you cannot tell even when the slope of the discount range is wrong.

You can reproduce the grading directly with bash /opt/lab/checks/test-boundaries-lab/05-contract.sh. Save the file and run it again.

Verify both sides of the upper limit together

In /root/work/test-boundaries-lab/test_service.py, use pytest.raises to check that price(100) is 30000 and that price(101) is a ValueError.

Treat the largest legal value and the illegal value right after it as a pair.

You can reproduce the grading directly with bash /opt/lab/checks/test-boundaries-lab/06-contract.sh. Save the file and run it again.

Do not turn negative input into success

In /root/work/test-boundaries-lab/test_service.py, test that price(-1) is a ValueError. Do not treat returning a negative price as normal handling.

If you do nothing in try/except, the test can pass even when no exception is raised. Use pytest.raises.

You can reproduce the grading directly with bash /opt/lab/checks/test-boundaries-lab/07-contract.sh. Save the file and run it again.

Reject bool and number-shaped strings

In /root/work/test-boundaries-lab/test_service.py, add a parametrized test that True, False, 1.0, '1', and None are all TypeError. In particular, it must catch the defect that accepts bool as an int.

Include inputs that expose the difference between type(x) and isinstance(x, int). The test must call the public function, not the implementation source.

You can reproduce the grading directly with bash /opt/lab/checks/test-boundaries-lab/08-contract.sh. Save the file and run it again.